From 0a1ad74691b32959fef62409f49cdef47c7099f2 Mon Sep 17 00:00:00 2001 From: Gao Sun Date: Fri, 1 Mar 2024 14:56:32 +0800 Subject: [PATCH 001/687] refactor(schemas): update schema to fit cloud --- packages/schemas/package.json | 2 +- packages/schemas/src/types/organization.ts | 14 +++++++++----- pnpm-lock.yaml | 14 ++++++++++++-- 3 files changed, 22 insertions(+), 8 deletions(-) diff --git a/packages/schemas/package.json b/packages/schemas/package.json index 3e56663cebb..a962a0687ef 100644 --- a/packages/schemas/package.json +++ b/packages/schemas/package.json @@ -86,7 +86,7 @@ "@logto/phrases": "workspace:^1.9.0", "@logto/phrases-experience": "workspace:^1.6.0", "@logto/shared": "workspace:^3.1.0", - "@withtyped/server": "^0.12.9" + "@withtyped/server": "^0.13.1" }, "peerDependencies": { "zod": "^3.22.4" diff --git a/packages/schemas/src/types/organization.ts b/packages/schemas/src/types/organization.ts index 32d750eba43..fdbefcd4245 100644 --- a/packages/schemas/src/types/organization.ts +++ b/packages/schemas/src/types/organization.ts @@ -11,6 +11,10 @@ import { import { type UserInfo, type FeaturedUser, userInfoGuard } from './user.js'; +type ToZodObject = z.ZodObject<{ + [K in keyof T]: z.ZodType; +}>; + /** * The simplified organization scope entity that is returned for some endpoints. */ @@ -23,7 +27,7 @@ export type OrganizationRoleWithScopes = OrganizationRole & { scopes: OrganizationScopeEntity[]; }; -export const organizationRoleWithScopesGuard: z.ZodType = +export const organizationRoleWithScopesGuard: ToZodObject = OrganizationRoles.guard.extend({ scopes: z .object({ @@ -42,7 +46,7 @@ export type OrganizationRoleEntity = { name: string; }; -const organizationRoleEntityGuard: z.ZodType = z.object({ +const organizationRoleEntityGuard: ToZodObject = z.object({ id: z.string(), name: z.string(), }); @@ -56,7 +60,7 @@ export type OrganizationWithRoles = Organization & { organizationRoles: OrganizationRoleEntity[]; }; -export const organizationWithOrganizationRolesGuard: z.ZodType = +export const organizationWithOrganizationRolesGuard: ToZodObject = Organizations.guard.extend({ organizationRoles: organizationRoleEntityGuard.array(), }); @@ -70,7 +74,7 @@ export type UserWithOrganizationRoles = UserInfo & { organizationRoles: OrganizationRoleEntity[]; }; -export const userWithOrganizationRolesGuard: z.ZodType = +export const userWithOrganizationRolesGuard: ToZodObject = userInfoGuard.extend({ organizationRoles: organizationRoleEntityGuard.array(), }); @@ -93,7 +97,7 @@ export type OrganizationInvitationEntity = OrganizationInvitation & { organizationRoles: OrganizationRoleEntity[]; }; -export const organizationInvitationEntityGuard: z.ZodType = +export const organizationInvitationEntityGuard: ToZodObject = OrganizationInvitations.guard.extend({ organizationRoles: organizationRoleEntityGuard.array(), }); diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index fc47c7b4bd7..271428e7489 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -3997,8 +3997,8 @@ importers: specifier: workspace:^3.1.0 version: link:../shared '@withtyped/server': - specifier: ^0.12.9 - version: 0.12.9(zod@3.22.4) + specifier: ^0.13.1 + version: 0.13.1(zod@3.22.4) zod: specifier: ^3.22.4 version: 3.22.4 @@ -10547,6 +10547,16 @@ packages: '@withtyped/shared': 0.2.2 zod: 3.22.4 + /@withtyped/server@0.13.1(zod@3.22.4): + resolution: {integrity: sha512-Fmmlw/7f3oidMS2tjgOx82BIkNEDBpHbFPj4oghXbyaZ8bgskLjKoLE0Qscbua6vhWUG4EgAmfR5ijSfg3bw2Q==} + peerDependencies: + zod: ^3.19.1 + dependencies: + '@silverhand/essentials': 2.9.0 + '@withtyped/shared': 0.2.2 + zod: 3.22.4 + dev: false + /@withtyped/shared@0.2.2: resolution: {integrity: sha512-Vpcj12NqaoZ8M5Z/1kffheI9FBZEm9goed0THmgTcMKXLHjXSRbMZMp0olVxovEgaTIAydshqJOQUXKZMctIZw==} From 791f6f9013fd863c6c947e4cf51936869e9c02e4 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Sat, 2 Mar 2024 09:08:55 +0000 Subject: [PATCH 002/687] chore(deps): upgrade commitlint and husky (#5443) chore: upgrade commitlint and husky Co-authored-by: Gao Sun --- commitlint.config.cjs => commitlint.config.ts | 10 +- package.json | 6 +- pnpm-lock.yaml | 392 +++++------------- 3 files changed, 121 insertions(+), 287 deletions(-) rename commitlint.config.cjs => commitlint.config.ts (65%) diff --git a/commitlint.config.cjs b/commitlint.config.ts similarity index 65% rename from commitlint.config.cjs rename to commitlint.config.ts index a46859ab2f3..5f44c75e5e8 100644 --- a/commitlint.config.cjs +++ b/commitlint.config.ts @@ -1,15 +1,17 @@ -const { rules } = require('@commitlint/config-conventional'); +import conventional from '@commitlint/config-conventional'; +import { UserConfig } from '@commitlint/types'; const isCi = process.env.CI === 'true'; -/** @type {import('@commitlint/types').UserConfig} **/ -module.exports = { +const config: UserConfig = { extends: ['@commitlint/config-conventional'], rules: { - 'type-enum': [2, 'always', [...rules['type-enum'][2], 'api', 'release']], + 'type-enum': [2, 'always', [...conventional.rules['type-enum'][2], 'api', 'release']], 'scope-enum': [2, 'always', ['connector', 'console', 'core', 'demo-app', 'test', 'phrases', 'schemas', 'shared', 'experience', 'deps', 'deps-dev', 'cli', 'toolkit', 'cloud', 'app-insights']], // Slightly increase the tolerance to allow the appending PR number ...(isCi && { 'header-max-length': [2, 'always', 110] }), 'body-max-line-length': [2, 'always', 110], }, }; + +export default config; diff --git a/package.json b/package.json index 292c0aa6989..4752a4934a5 100644 --- a/package.json +++ b/package.json @@ -25,9 +25,9 @@ }, "devDependencies": { "@changesets/cli": "^2.26.2", - "@commitlint/cli": "^18.0.0", - "@commitlint/config-conventional": "^18.0.0", - "@commitlint/types": "^18.0.0", + "@commitlint/cli": "^19.0.0", + "@commitlint/config-conventional": "^19.0.0", + "@commitlint/types": "^19.0.0", "@types/pg": "^8.6.6", "husky": "^9.0.0", "pg": "^8.8.0", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 271428e7489..2acfcc33217 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -16,14 +16,14 @@ importers: specifier: ^2.26.2 version: 2.26.2 '@commitlint/cli': - specifier: ^18.0.0 - version: 18.4.3(typescript@5.0.2) + specifier: ^19.0.0 + version: 19.0.3(@types/node@20.11.20)(typescript@5.0.2) '@commitlint/config-conventional': - specifier: ^18.0.0 - version: 18.4.3 + specifier: ^19.0.0 + version: 19.0.3 '@commitlint/types': - specifier: ^18.0.0 - version: 18.4.3 + specifier: ^19.0.0 + version: 19.0.3 '@types/pg': specifier: ^8.6.6 version: 8.6.6 @@ -3725,7 +3725,7 @@ importers: version: 3.0.0 jest: specifier: ^29.7.0 - version: 29.7.0(@types/node@18.19.3) + version: 29.7.0(@types/node@20.11.20) jest-environment-jsdom: specifier: ^29.0.0 version: 29.2.2 @@ -6775,45 +6775,44 @@ packages: dev: true optional: true - /@commitlint/cli@18.4.3(typescript@5.0.2): - resolution: {integrity: sha512-zop98yfB3A6NveYAZ3P1Mb6bIXuCeWgnUfVNkH4yhIMQpQfzFwseadazOuSn0OOfTt0lWuFauehpm9GcqM5lww==} + /@commitlint/cli@19.0.3(@types/node@20.11.20)(typescript@5.0.2): + resolution: {integrity: sha512-mGhh/aYPib4Vy4h+AGRloMY+CqkmtdeKPV9poMcZeImF5e3knQ5VYaSeAM0mEzps1dbKsHvABwaDpafLUuM96g==} engines: {node: '>=v18'} hasBin: true dependencies: - '@commitlint/format': 18.4.3 - '@commitlint/lint': 18.4.3 - '@commitlint/load': 18.4.3(typescript@5.0.2) - '@commitlint/read': 18.4.3 - '@commitlint/types': 18.4.3 - execa: 5.1.1 - lodash.isfunction: 3.0.9 - resolve-from: 5.0.0 - resolve-global: 1.0.0 + '@commitlint/format': 19.0.3 + '@commitlint/lint': 19.0.3 + '@commitlint/load': 19.0.3(@types/node@20.11.20)(typescript@5.0.2) + '@commitlint/read': 19.0.3 + '@commitlint/types': 19.0.3 + execa: 8.0.1 yargs: 17.7.2 transitivePeerDependencies: + - '@types/node' - typescript dev: true - /@commitlint/config-conventional@18.4.3: - resolution: {integrity: sha512-729eRRaNta7JZF07qf6SAGSghoDEp9mH7yHU0m7ff0q89W97wDrWCyZ3yoV3mcQJwbhlmVmZPTkPcm7qiAu8WA==} + /@commitlint/config-conventional@19.0.3: + resolution: {integrity: sha512-vh0L8XeLaEzTe8VCxSd0gAFvfTK0RFolrzw4o431bIuWJfi/yRCHJlsDwus7wW2eJaFFDR0VFXJyjGyDQhi4vA==} engines: {node: '>=v18'} dependencies: + '@commitlint/types': 19.0.3 conventional-changelog-conventionalcommits: 7.0.2 dev: true - /@commitlint/config-validator@18.4.3: - resolution: {integrity: sha512-FPZZmTJBARPCyef9ohRC9EANiQEKSWIdatx5OlgeHKu878dWwpyeFauVkhzuBRJFcCA4Uvz/FDtlDKs008IHcA==} + /@commitlint/config-validator@19.0.3: + resolution: {integrity: sha512-2D3r4PKjoo59zBc2auodrSCaUnCSALCx54yveOFwwP/i2kfEAQrygwOleFWswLqK0UL/F9r07MFi5ev2ohyM4Q==} engines: {node: '>=v18'} dependencies: - '@commitlint/types': 18.4.3 + '@commitlint/types': 19.0.3 ajv: 8.12.0 dev: true - /@commitlint/ensure@18.4.3: - resolution: {integrity: sha512-MI4fwD9TWDVn4plF5+7JUyLLbkOdzIRBmVeNlk4dcGlkrVA+/l5GLcpN66q9LkFsFv6G2X31y89ApA3hqnqIFg==} + /@commitlint/ensure@19.0.3: + resolution: {integrity: sha512-SZEpa/VvBLoT+EFZVb91YWbmaZ/9rPH3ESrINOl0HD2kMYsjvl0tF7nMHh0EpTcv4+gTtZBAe1y/SS6/OhfZzQ==} engines: {node: '>=v18'} dependencies: - '@commitlint/types': 18.4.3 + '@commitlint/types': 19.0.3 lodash.camelcase: 4.3.0 lodash.kebabcase: 4.1.1 lodash.snakecase: 4.1.1 @@ -6821,122 +6820,121 @@ packages: lodash.upperfirst: 4.3.1 dev: true - /@commitlint/execute-rule@18.4.3: - resolution: {integrity: sha512-t7FM4c+BdX9WWZCPrrbV5+0SWLgT3kCq7e7/GhHCreYifg3V8qyvO127HF796vyFql75n4TFF+5v1asOOWkV1Q==} + /@commitlint/execute-rule@19.0.0: + resolution: {integrity: sha512-mtsdpY1qyWgAO/iOK0L6gSGeR7GFcdW7tIjcNFxcWkfLDF5qVbPHKuGATFqRMsxcO8OUKNj0+3WOHB7EHm4Jdw==} engines: {node: '>=v18'} dev: true - /@commitlint/format@18.4.3: - resolution: {integrity: sha512-8b+ItXYHxAhRAXFfYki5PpbuMMOmXYuzLxib65z2XTqki59YDQJGpJ/wB1kEE5MQDgSTQWtKUrA8n9zS/1uIDQ==} + /@commitlint/format@19.0.3: + resolution: {integrity: sha512-QjjyGyoiVWzx1f5xOteKHNLFyhyweVifMgopozSgx1fGNrGV8+wp7k6n1t6StHdJ6maQJ+UUtO2TcEiBFRyR6Q==} engines: {node: '>=v18'} dependencies: - '@commitlint/types': 18.4.3 - chalk: 4.1.2 + '@commitlint/types': 19.0.3 + chalk: 5.3.0 dev: true - /@commitlint/is-ignored@18.4.3: - resolution: {integrity: sha512-ZseOY9UfuAI32h9w342Km4AIaTieeFskm2ZKdrG7r31+c6zGBzuny9KQhwI9puc0J3GkUquEgKJblCl7pMnjwg==} + /@commitlint/is-ignored@19.0.3: + resolution: {integrity: sha512-MqDrxJaRSVSzCbPsV6iOKG/Lt52Y+PVwFVexqImmYYFhe51iVJjK2hRhOG2jUAGiUHk4jpdFr0cZPzcBkSzXDQ==} engines: {node: '>=v18'} dependencies: - '@commitlint/types': 18.4.3 - semver: 7.5.4 + '@commitlint/types': 19.0.3 + semver: 7.6.0 dev: true - /@commitlint/lint@18.4.3: - resolution: {integrity: sha512-18u3MRgEXNbnYkMOWoncvq6QB8/90m9TbERKgdPqVvS+zQ/MsuRhdvHYCIXGXZxUb0YI4DV2PC4bPneBV/fYuA==} + /@commitlint/lint@19.0.3: + resolution: {integrity: sha512-uHPyRqIn57iIplYa5xBr6oNu5aPXKGC4WLeuHfqQHclwIqbJ33g3yA5fIA+/NYnp5ZM2EFiujqHFaVUYj6HlKA==} engines: {node: '>=v18'} dependencies: - '@commitlint/is-ignored': 18.4.3 - '@commitlint/parse': 18.4.3 - '@commitlint/rules': 18.4.3 - '@commitlint/types': 18.4.3 + '@commitlint/is-ignored': 19.0.3 + '@commitlint/parse': 19.0.3 + '@commitlint/rules': 19.0.3 + '@commitlint/types': 19.0.3 dev: true - /@commitlint/load@18.4.3(typescript@5.0.2): - resolution: {integrity: sha512-v6j2WhvRQJrcJaj5D+EyES2WKTxPpxENmNpNG3Ww8MZGik3jWRXtph0QTzia5ZJyPh2ib5aC/6BIDymkUUM58Q==} + /@commitlint/load@19.0.3(@types/node@20.11.20)(typescript@5.0.2): + resolution: {integrity: sha512-18Tk/ZcDFRKIoKfEcl7kC+bYkEQ055iyKmGsYDoYWpKf6FUvBrP9bIWapuy/MB+kYiltmP9ITiUx6UXtqC9IRw==} engines: {node: '>=v18'} dependencies: - '@commitlint/config-validator': 18.4.3 - '@commitlint/execute-rule': 18.4.3 - '@commitlint/resolve-extends': 18.4.3 - '@commitlint/types': 18.4.3 - '@types/node': 18.19.3 - chalk: 4.1.2 + '@commitlint/config-validator': 19.0.3 + '@commitlint/execute-rule': 19.0.0 + '@commitlint/resolve-extends': 19.0.3 + '@commitlint/types': 19.0.3 + chalk: 5.3.0 cosmiconfig: 8.3.6(typescript@5.0.2) - cosmiconfig-typescript-loader: 5.0.0(@types/node@18.19.3)(cosmiconfig@8.3.6)(typescript@5.0.2) + cosmiconfig-typescript-loader: 5.0.0(@types/node@20.11.20)(cosmiconfig@8.3.6)(typescript@5.0.2) lodash.isplainobject: 4.0.6 lodash.merge: 4.6.2 lodash.uniq: 4.5.0 - resolve-from: 5.0.0 transitivePeerDependencies: + - '@types/node' - typescript dev: true - /@commitlint/message@18.4.3: - resolution: {integrity: sha512-ddJ7AztWUIoEMAXoewx45lKEYEOeOlBVWjk8hDMUGpprkuvWULpaXczqdjwVtjrKT3JhhN+gMs8pm5G3vB2how==} + /@commitlint/message@19.0.0: + resolution: {integrity: sha512-c9czf6lU+9oF9gVVa2lmKaOARJvt4soRsVmbR7Njwp9FpbBgste5i7l/2l5o8MmbwGh4yE1snfnsy2qyA2r/Fw==} engines: {node: '>=v18'} dev: true - /@commitlint/parse@18.4.3: - resolution: {integrity: sha512-eoH7CXM9L+/Me96KVcfJ27EIIbA5P9sqw3DqjJhRYuhaULIsPHFs5S5GBDCqT0vKZQDx0DgxhMpW6AQbnKrFtA==} + /@commitlint/parse@19.0.3: + resolution: {integrity: sha512-Il+tNyOb8VDxN3P6XoBBwWJtKKGzHlitEuXA5BP6ir/3loWlsSqDr5aecl6hZcC/spjq4pHqNh0qPlfeWu38QA==} engines: {node: '>=v18'} dependencies: - '@commitlint/types': 18.4.3 + '@commitlint/types': 19.0.3 conventional-changelog-angular: 7.0.0 conventional-commits-parser: 5.0.0 dev: true - /@commitlint/read@18.4.3: - resolution: {integrity: sha512-H4HGxaYA6OBCimZAtghL+B+SWu8ep4X7BwgmedmqWZRHxRLcX2q0bWBtUm5FsMbluxbOfrJwOs/Z0ah4roP/GQ==} + /@commitlint/read@19.0.3: + resolution: {integrity: sha512-b5AflTyAXkUx5qKw4TkjjcOccXZHql3JqMi522knTQktq2AubKXFz60Sws+K4FsefwPws6fGz9mqiI/NvsvxFA==} engines: {node: '>=v18'} dependencies: - '@commitlint/top-level': 18.4.3 - '@commitlint/types': 18.4.3 - fs-extra: 11.1.1 - git-raw-commits: 2.0.11 + '@commitlint/top-level': 19.0.0 + '@commitlint/types': 19.0.3 + git-raw-commits: 4.0.0 minimist: 1.2.8 dev: true - /@commitlint/resolve-extends@18.4.3: - resolution: {integrity: sha512-30sk04LZWf8+SDgJrbJCjM90gTg2LxsD9cykCFeFu+JFHvBFq5ugzp2eO/DJGylAdVaqxej3c7eTSE64hR/lnw==} + /@commitlint/resolve-extends@19.0.3: + resolution: {integrity: sha512-18BKmta8OC8+Ub+Q3QGM9l27VjQaXobloVXOrMvu8CpEwJYv62vC/t7Ka5kJnsW0tU9q1eMqJFZ/nN9T/cOaIA==} engines: {node: '>=v18'} dependencies: - '@commitlint/config-validator': 18.4.3 - '@commitlint/types': 18.4.3 - import-fresh: 3.3.0 + '@commitlint/config-validator': 19.0.3 + '@commitlint/types': 19.0.3 + global-directory: 4.0.1 + import-meta-resolve: 4.0.0 lodash.mergewith: 4.6.2 resolve-from: 5.0.0 - resolve-global: 1.0.0 dev: true - /@commitlint/rules@18.4.3: - resolution: {integrity: sha512-8KIeukDf45BiY+Lul1T0imSNXF0sMrlLG6JpLLKolkmYVQ6PxxoNOriwyZ3UTFFpaVbPy0rcITaV7U9JCAfDTA==} + /@commitlint/rules@19.0.3: + resolution: {integrity: sha512-TspKb9VB6svklxNCKKwxhELn7qhtY1rFF8ls58DcFd0F97XoG07xugPjjbVnLqmMkRjZDbDIwBKt9bddOfLaPw==} engines: {node: '>=v18'} dependencies: - '@commitlint/ensure': 18.4.3 - '@commitlint/message': 18.4.3 - '@commitlint/to-lines': 18.4.3 - '@commitlint/types': 18.4.3 - execa: 5.1.1 + '@commitlint/ensure': 19.0.3 + '@commitlint/message': 19.0.0 + '@commitlint/to-lines': 19.0.0 + '@commitlint/types': 19.0.3 + execa: 8.0.1 dev: true - /@commitlint/to-lines@18.4.3: - resolution: {integrity: sha512-fy1TAleik4Zfru1RJ8ZU6cOSvgSVhUellxd3WZV1D5RwHZETt1sZdcA4mQN2y3VcIZsUNKkW0Mq8CM9/L9harQ==} + /@commitlint/to-lines@19.0.0: + resolution: {integrity: sha512-vkxWo+VQU5wFhiP9Ub9Sre0FYe019JxFikrALVoD5UGa8/t3yOJEpEhxC5xKiENKKhUkTpEItMTRAjHw2SCpZw==} engines: {node: '>=v18'} dev: true - /@commitlint/top-level@18.4.3: - resolution: {integrity: sha512-E6fJPBLPFL5R8+XUNSYkj4HekIOuGMyJo3mIx2PkYc3clel+pcWQ7TConqXxNWW4x1ugigiIY2RGot55qUq1hw==} + /@commitlint/top-level@19.0.0: + resolution: {integrity: sha512-KKjShd6u1aMGNkCkaX4aG1jOGdn7f8ZI8TR1VEuNqUOjWTOdcDSsmglinglJ18JTjuBX5I1PtjrhQCRcixRVFQ==} engines: {node: '>=v18'} dependencies: - find-up: 5.0.0 + find-up: 7.0.0 dev: true - /@commitlint/types@18.4.3: - resolution: {integrity: sha512-cvzx+vtY/I2hVBZHCLrpoh+sA0hfuzHwDc+BAFPimYLjJkpHnghQM+z8W/KyLGkygJh3BtI3xXXq+dKjnSWEmA==} + /@commitlint/types@19.0.3: + resolution: {integrity: sha512-tpyc+7i6bPG9mvaBbtKUeghfyZSDgWquIDfMgqYtTbmZ9Y9VzEm2je9EYcQ0aoz5o7NvGS+rcDec93yO08MHYA==} engines: {node: '>=v18'} dependencies: - chalk: 4.1.2 + '@types/conventional-commits-parser': 5.0.0 + chalk: 5.3.0 dev: true /@cspotcode/source-map-support@0.8.1: @@ -9903,6 +9901,12 @@ packages: resolution: {integrity: sha512-0mPF08jn9zYI0n0Q/Pnz7C4kThdSt+6LD4amsrYDDpgBfrVWa3TcCOxKX1zkGgYniGagRv8heN2cbh+CAn+uuQ==} dev: true + /@types/conventional-commits-parser@5.0.0: + resolution: {integrity: sha512-loB369iXNmAZglwWATL+WRe+CRMmmBPtpolYzIebFaX4YA3x+BEfLqhUAV9WanycKI3TG1IMr5bMJDajDKLlUQ==} + dependencies: + '@types/node': 20.11.20 + dev: true + /@types/cookiejar@2.1.5: resolution: {integrity: sha512-he+DHOWReW0nghN24E1WUqM0efK4kI9oTqDm6XmK8ZPe2djZ90BSNdGnIyCLzCPw7/pogPlGbzI2wHGGmi4O/Q==} dev: true @@ -10147,12 +10151,6 @@ packages: resolution: {integrity: sha512-J8xLz7q2OFulZ2cyGTLE1TbbZcjpno7FaN6zdJNrgAdrJ+DZzh/uFR6YrTb4C+nXakvud8Q4+rbhoIWlYQbUFQ==} dev: true - /@types/node@18.19.3: - resolution: {integrity: sha512-k5fggr14DwAytoA/t8rPrIz++lXK7/DqckthCmoZOKNsEbJkId4Z//BqgApXBUGrGddrigYa1oqheo/7YmW4rg==} - dependencies: - undici-types: 5.26.5 - dev: true - /@types/node@20.10.4: resolution: {integrity: sha512-D08YG6rr8X90YB56tSIuBaddy/UXAA9RKJoFvrsnogAum/0pmjkgi4+2nx96A330FmioegBWmEYQ+syqCFaveg==} dependencies: @@ -11730,7 +11728,7 @@ packages: resolution: {integrity: sha512-aDdvlDder8QmY91H88GzNi9EtQi2TjvQhpCX6B1v/dAZHU1AuLgHvRh54RiOerpEhEW46Tkf+vgAViB/CWC0ag==} requiresBuild: true - /cosmiconfig-typescript-loader@5.0.0(@types/node@18.19.3)(cosmiconfig@8.3.6)(typescript@5.0.2): + /cosmiconfig-typescript-loader@5.0.0(@types/node@20.11.20)(cosmiconfig@8.3.6)(typescript@5.0.2): resolution: {integrity: sha512-+8cK7jRAReYkMwMiG+bxhcNKiHJDM6bR9FD/nGBXOWdMLuYawjF5cGrtLilJ+LGd3ZjCXnJjR5DkfWPoIVlqJA==} engines: {node: '>=v16'} peerDependencies: @@ -11738,7 +11736,7 @@ packages: cosmiconfig: '>=8.2' typescript: '>=4' dependencies: - '@types/node': 18.19.3 + '@types/node': 20.11.20 cosmiconfig: 8.3.6(typescript@5.0.2) jiti: 1.21.0 typescript: 5.0.2 @@ -11830,25 +11828,6 @@ packages: lodash.get: 4.4.2 dev: true - /create-jest@29.7.0(@types/node@18.19.3): - resolution: {integrity: sha512-Adz2bdH0Vq3F53KEMJOoftQFutWCukm6J24wbPWRO4k1kMY7gS7ds/uoJkNuV8wDCtWWnuwGcJwpWcih+zEW1Q==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - hasBin: true - dependencies: - '@jest/types': 29.6.3 - chalk: 4.1.2 - exit: 0.1.2 - graceful-fs: 4.2.11 - jest-config: 29.7.0(@types/node@18.19.3) - jest-util: 29.7.0 - prompts: 2.4.2 - transitivePeerDependencies: - - '@types/node' - - babel-plugin-macros - - supports-color - - ts-node - dev: true - /create-jest@29.7.0(@types/node@20.10.4): resolution: {integrity: sha512-Adz2bdH0Vq3F53KEMJOoftQFutWCukm6J24wbPWRO4k1kMY7gS7ds/uoJkNuV8wDCtWWnuwGcJwpWcih+zEW1Q==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} @@ -12089,9 +12068,9 @@ packages: resolution: {integrity: sha512-sdQSFB7+llfUcQHUQO3+B8ERRj0Oa4w9POWMI/puGtuf7gFywGmkaLCElnudfTiKZV+NvHqL0ifzdrI8Ro7ESA==} dev: true - /dargs@7.0.0: - resolution: {integrity: sha512-2iy1EkLdlBzQGvbweYRFxmFath8+K7+AKB0TlhHWkNuH+TmovaMH/Wp7V7R4u7f4SnX3OgLsU9t1NI9ioDnUpg==} - engines: {node: '>=8'} + /dargs@8.1.0: + resolution: {integrity: sha512-wAV9QHOsNbwnWdNW2FYvE1P56wtgSbM+3SZcdGiWQILwVjACCXDCI3Ai8QlCjMDB8YK5zySiXZYBiwGmNY3lnw==} + engines: {node: '>=12'} dev: true /data-uri-to-buffer@4.0.0: @@ -13520,7 +13499,6 @@ packages: locate-path: 7.2.0 path-exists: 5.0.0 unicorn-magic: 0.1.0 - dev: false /find-yarn-workspace-root2@1.2.16: resolution: {integrity: sha512-hr6hb1w8ePMpPVUK39S4RlwJzi+xPLuVuG8XlwXU3KD5Yn3qgBWVfy3AzNlDhWvE1EORCE65/Qm26rFQt3VLVA==} @@ -13629,15 +13607,6 @@ packages: engines: {node: '>=0.10.0'} dev: true - /fs-extra@11.1.1: - resolution: {integrity: sha512-MGIE4HOvQCeUCzmlHs0vXpih4ysz4wg9qiSAu6cd42lVwPbTM1TjV7RusoyQqMmk/95gdQZX72u+YW+c3eEpFQ==} - engines: {node: '>=14.14'} - dependencies: - graceful-fs: 4.2.11 - jsonfile: 6.1.0 - universalify: 2.0.0 - dev: true - /fs-extra@7.0.1: resolution: {integrity: sha512-YJDaCJZEnBmcbw13fvdAM9AwNOJwOzrE4pqMqBq5nFiEqXUqHwlK4B+3pUw6JNvfSPtX05xFHtYy/1ni01eGCw==} engines: {node: '>=6 <7 || >=8'} @@ -13809,16 +13778,14 @@ packages: - supports-color dev: true - /git-raw-commits@2.0.11: - resolution: {integrity: sha512-VnctFhw+xfj8Va1xtfEqCUD2XDrbAPSJx+hSrE5K7fGdjZruW7XV+QOrN7LF/RJyvspRiD2I0asWsxFp0ya26A==} - engines: {node: '>=10'} + /git-raw-commits@4.0.0: + resolution: {integrity: sha512-ICsMM1Wk8xSGMowkOmPrzo2Fgmfo4bMHLNX6ytHjajRJUqvHOw/TFapQ+QG75c3X/tTDDhOSRPGC52dDbNM8FQ==} + engines: {node: '>=16'} hasBin: true dependencies: - dargs: 7.0.0 - lodash: 4.17.21 - meow: 8.1.2 - split2: 3.2.2 - through2: 4.0.2 + dargs: 8.1.0 + meow: 12.1.1 + split2: 4.2.0 dev: true /glob-parent@5.1.2: @@ -13857,11 +13824,11 @@ packages: once: 1.4.0 dev: true - /global-dirs@0.1.1: - resolution: {integrity: sha512-NknMLn7F2J7aflwFOlGdNIuCDpN3VGoSoB+aap3KABFWbHVn1TCgFC+np23J8W2BiZbjfEw3BFBycSMv1AFblg==} - engines: {node: '>=4'} + /global-directory@4.0.1: + resolution: {integrity: sha512-wHTUcDUoZ1H5/0iVqEudYW4/kAlN5cZ3j/bXn0Dpbizl9iaUVeWSHqiOjsgk6OW2bkLclbBjzewBz6weQ1zA2Q==} + engines: {node: '>=18'} dependencies: - ini: 1.3.8 + ini: 4.1.1 dev: true /global-modules@0.2.3: @@ -14529,6 +14496,10 @@ packages: resolve-cwd: 3.0.0 dev: true + /import-meta-resolve@4.0.0: + resolution: {integrity: sha512-okYUR7ZQPH+efeuMJGlq4f8ubUgO50kByRPyt/Cy1Io4PSRsPjxME+YlVaCOx+NIToW7hCsZNFJyTPFFKepRSA==} + dev: true + /import-modules@2.1.0: resolution: {integrity: sha512-8HEWcnkbGpovH9yInoisxaSoIg9Brbul+Ju3Kqe2UsYDUBJD/iQjSgEj0zPcTDPKfPp2fs5xlv1i+JSye/m1/A==} engines: {node: '>=8'} @@ -14576,6 +14547,11 @@ packages: resolution: {integrity: sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==} dev: true + /ini@4.1.1: + resolution: {integrity: sha512-QQnnxNyfvmHFIsj7gkPcYymR8Jdw/o7mp5ZFihxn6h8Ci6fh3Dx4E1gPjpQEpIuPo9XVNY/ZUwh4BPMjGyL01g==} + engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} + dev: true + /inline-loops.macro@1.2.2: resolution: {integrity: sha512-w5cOGQGnNoBTSibg6IzaIG2OG9sbXJxTn3uzYP717C/SvcJVEFz5Zu1dJwvCLlnwtBWQgcfnV2BNEQaRoIAfIw==} dependencies: @@ -15058,34 +15034,6 @@ packages: - supports-color dev: true - /jest-cli@29.7.0(@types/node@18.19.3): - resolution: {integrity: sha512-OVVobw2IubN/GSYsxETi+gOe7Ka59EFMR/twOU3Jb2GnKKeMGJB5SGUUrEz3SFVmJASUdZUzy83sLNNQ2gZslg==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - hasBin: true - peerDependencies: - node-notifier: ^8.0.1 || ^9.0.0 || ^10.0.0 - peerDependenciesMeta: - node-notifier: - optional: true - dependencies: - '@jest/core': 29.7.0(ts-node@10.9.2) - '@jest/test-result': 29.7.0 - '@jest/types': 29.6.3 - chalk: 4.1.2 - create-jest: 29.7.0(@types/node@18.19.3) - exit: 0.1.2 - import-local: 3.1.0 - jest-config: 29.7.0(@types/node@18.19.3) - jest-util: 29.7.0 - jest-validate: 29.7.0 - yargs: 17.7.2 - transitivePeerDependencies: - - '@types/node' - - babel-plugin-macros - - supports-color - - ts-node - dev: true - /jest-cli@29.7.0(@types/node@20.10.4): resolution: {integrity: sha512-OVVobw2IubN/GSYsxETi+gOe7Ka59EFMR/twOU3Jb2GnKKeMGJB5SGUUrEz3SFVmJASUdZUzy83sLNNQ2gZslg==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} @@ -15170,46 +15118,6 @@ packages: - ts-node dev: true - /jest-config@29.7.0(@types/node@18.19.3): - resolution: {integrity: sha512-uXbpfeQ7R6TZBqI3/TxCU4q4ttk3u0PJeC+E0zbfSoSjq6bJ7buBPxzQPL0ifrkY4DNu4JUdk0ImlBUYi840eQ==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - peerDependencies: - '@types/node': '*' - ts-node: '>=9.0.0' - peerDependenciesMeta: - '@types/node': - optional: true - ts-node: - optional: true - dependencies: - '@babel/core': 7.20.2 - '@jest/test-sequencer': 29.7.0 - '@jest/types': 29.6.3 - '@types/node': 18.19.3 - babel-jest: 29.7.0(@babel/core@7.20.2) - chalk: 4.1.2 - ci-info: 3.8.0 - deepmerge: 4.3.1 - glob: 7.2.3 - graceful-fs: 4.2.11 - jest-circus: 29.7.0 - jest-environment-node: 29.7.0 - jest-get-type: 29.6.3 - jest-regex-util: 29.6.3 - jest-resolve: 29.7.0 - jest-runner: 29.7.0 - jest-util: 29.7.0 - jest-validate: 29.7.0 - micromatch: 4.0.5 - parse-json: 5.2.0 - pretty-format: 29.7.0 - slash: 3.0.0 - strip-json-comments: 3.1.1 - transitivePeerDependencies: - - babel-plugin-macros - - supports-color - dev: true - /jest-config@29.7.0(@types/node@20.10.4): resolution: {integrity: sha512-uXbpfeQ7R6TZBqI3/TxCU4q4ttk3u0PJeC+E0zbfSoSjq6bJ7buBPxzQPL0ifrkY4DNu4JUdk0ImlBUYi840eQ==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} @@ -15756,27 +15664,6 @@ packages: supports-color: 8.1.1 dev: true - /jest@29.7.0(@types/node@18.19.3): - resolution: {integrity: sha512-NIy3oAFp9shda19hy4HK0HRTWKtPJmGdnvywu01nOqNC2vZg+Z+fvJDxpMQA88eb2I9EcafcdjYgsDthnYTvGw==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - hasBin: true - peerDependencies: - node-notifier: ^8.0.1 || ^9.0.0 || ^10.0.0 - peerDependenciesMeta: - node-notifier: - optional: true - dependencies: - '@jest/core': 29.7.0(ts-node@10.9.2) - '@jest/types': 29.6.3 - import-local: 3.1.0 - jest-cli: 29.7.0(@types/node@18.19.3) - transitivePeerDependencies: - - '@types/node' - - babel-plugin-macros - - supports-color - - ts-node - dev: true - /jest@29.7.0(@types/node@20.10.4): resolution: {integrity: sha512-NIy3oAFp9shda19hy4HK0HRTWKtPJmGdnvywu01nOqNC2vZg+Z+fvJDxpMQA88eb2I9EcafcdjYgsDthnYTvGw==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} @@ -16009,14 +15896,6 @@ packages: graceful-fs: 4.2.11 dev: true - /jsonfile@6.1.0: - resolution: {integrity: sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==} - dependencies: - universalify: 2.0.0 - optionalDependencies: - graceful-fs: 4.2.11 - dev: true - /jsonparse@1.3.1: resolution: {integrity: sha512-POQXvpdL69+CluYsillJ7SUhKvytYjW9vG/GKpnf+xP8UWgYEM/RaMzHHofbALDiKbbP1W8UEYmgGl39WkPZsg==} engines: {'0': node >= 0.2.0} @@ -16483,7 +16362,6 @@ packages: engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} dependencies: p-locate: 6.0.0 - dev: false /lodash-es@4.17.21: resolution: {integrity: sha512-mKnC+QJ9pWVzv+C4/U3rRsHapFfHvQFoFB92e52xeyGMcX6/OlIl78je1u8vePzYZSkkogMPJ2yjxxsb89cxyw==} @@ -16508,10 +16386,6 @@ packages: /lodash.isempty@4.4.0: resolution: {integrity: sha512-oKMuF3xEeqDltrGMfDxAPGIVMSSRv8tbRSODbrs4KGsRRLEhrW8N8Rd4DRgB2+621hY8A8XwwrTVhXWpxFvMzg==} - /lodash.isfunction@3.0.9: - resolution: {integrity: sha512-AirXNj15uRIMMPihnkInB4i3NHeb4iBtNg9WRWuK2o31S+ePwwNmDPaTL3o7dTJ+VXNZim7rFs4rxN4YU1oUJw==} - dev: true - /lodash.isinteger@4.0.4: resolution: {integrity: sha512-DBwtEWN2caHQ9/imiNeEA5ys1JoRtRfY3d7V9wkqtbycnAmTvRRmbHKDV4a0EYc678/dia0jrte4tjYwVBaZUA==} dev: false @@ -16933,23 +16807,6 @@ packages: yargs-parser: 18.1.3 dev: true - /meow@8.1.2: - resolution: {integrity: sha512-r85E3NdZ+mpYk1C6RjPFEMSE+s1iZMuHtsHAqY0DT3jZczl0diWUZ8g6oU7h0M9cD2EL+PzaYghhCLzR0ZNn5Q==} - engines: {node: '>=10'} - dependencies: - '@types/minimist': 1.2.5 - camelcase-keys: 6.2.2 - decamelize-keys: 1.1.1 - hard-rejection: 2.1.0 - minimist-options: 4.1.0 - normalize-package-data: 3.0.3 - read-pkg-up: 7.0.1 - redent: 3.0.0 - trim-newlines: 3.0.1 - type-fest: 0.18.1 - yargs-parser: 20.2.9 - dev: true - /meow@9.0.0: resolution: {integrity: sha512-+obSblOQmRhcyBt62furQqRAQpNyWXo8BuQ5bN7dG8wmwQ+vwHKp/rCFD4CrTP8CsDQD1sjoZ94K417XEUk8IQ==} engines: {node: '>=10'} @@ -17935,7 +17792,6 @@ packages: engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} dependencies: yocto-queue: 1.0.0 - dev: false /p-limit@5.0.0: resolution: {integrity: sha512-/Eaoq+QyLSiXQ4lyYV23f14mZRQcXnxfHrN0vCai+ak9G0pp9iEQukIIZq5NccEvwRB8PUnZT0KsOoDCINS1qQ==} @@ -17962,7 +17818,6 @@ packages: engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} dependencies: p-limit: 4.0.0 - dev: false /p-map@2.1.0: resolution: {integrity: sha512-y3b8Kpd8OAN444hxfBbFfj1FY/RjtTd8tzYwhUqNYXx0fXx2iX4maP4Qr6qhIKbQXI02wTLAda4fYUbDagTUFw==} @@ -18126,7 +17981,6 @@ packages: /path-exists@5.0.0: resolution: {integrity: sha512-RjhtfwJOxzcFmNOi6ltcbcu4Iu+FL3zEj83dk4kAS+fVpTxXLO1b38RvJgT/0QwvV/L3aY9TAnyv0EOqW4GoMQ==} engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} - dev: false /path-is-absolute@1.0.1: resolution: {integrity: sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==} @@ -19555,13 +19409,6 @@ packages: engines: {node: '>=8'} dev: true - /resolve-global@1.0.0: - resolution: {integrity: sha512-zFa12V4OLtT5XUX/Q4VLvTfBf+Ok0SPc1FNGM/z9ctUdiU618qwKpWnd0CHs3+RqROfyEg/DhuHbMWYqcgljEw==} - engines: {node: '>=8'} - dependencies: - global-dirs: 0.1.1 - dev: true - /resolve-path@1.4.0: resolution: {integrity: sha1-xL2p9e+y/OZSR4c6s2u02DT+Fvc=} engines: {node: '>= 0.8'} @@ -19798,14 +19645,6 @@ packages: dependencies: lru-cache: 6.0.0 - /semver@7.5.4: - resolution: {integrity: sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==} - engines: {node: '>=10'} - hasBin: true - dependencies: - lru-cache: 6.0.0 - dev: true - /semver@7.6.0: resolution: {integrity: sha512-EnwXhrlwXMk9gKu5/flx5sv/an57AkRplG3hTK68W7FRDN+k+OWBj65M7719OkA82XLBxrcX0KSHj+X5COhOVg==} engines: {node: '>=10'} @@ -21256,7 +21095,6 @@ packages: /unicorn-magic@0.1.0: resolution: {integrity: sha512-lRfVq8fE8gz6QMBuDM6a+LO3IAzTi05H6gCVaUpir2E1Rwpo4ZUog45KpNXKC/Mn3Yb9UDuHumeFTo9iV/D9FQ==} engines: {node: '>=18'} - dev: false /unified@11.0.3: resolution: {integrity: sha512-jlCV402P+YDcFcB2VcN/n8JasOddqIiaxv118wNBoZXEhOn+lYG7BR4Bfg2BwxvlK58dwbuH2w7GX2esAjL6Mg==} @@ -21374,11 +21212,6 @@ packages: engines: {node: '>= 4.0.0'} dev: true - /universalify@2.0.0: - resolution: {integrity: sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ==} - engines: {node: '>= 10.0.0'} - dev: true - /unpipe@1.0.0: resolution: {integrity: sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==} engines: {node: '>= 0.8'} @@ -21885,7 +21718,6 @@ packages: /yocto-queue@1.0.0: resolution: {integrity: sha512-9bnSc/HEW2uRy67wc+T8UwauLuPJVn28jb+GtJY16iiKWyvmYJRXVT4UamsAEGQfPohgr2q4Tq0sQbQlxTfi1g==} engines: {node: '>=12.20'} - dev: false /zod@3.22.4: resolution: {integrity: sha512-iC+8Io04lddc+mVqQ9AZ7OQ2MrUKGN+oIQyq1vemgt46jwCwLfhq7/pwnBnNXXXZb8VTVLKwp9EDkx+ryxIWmg==} From 79b49ab79a095433829fe08a61a72c0d078003a8 Mon Sep 17 00:00:00 2001 From: wangsijie Date: Mon, 4 Mar 2024 12:18:19 +0900 Subject: [PATCH 003/687] feat(core): support more encrypt methods (#5444) * feat(schemas): add more encryption methods * feat(core): support more encrypt methods * fix(schemas): fix alter down column name * fix(core): fix tiny lint issue * refactor(core,schemas): use uppercase value * feat(core,schemas): add bcrypt * fix(schemas): fix alter script * refactor(core,schemas): rename bcrypt and use hash-wasm * chore: fix lock file --- packages/core/src/__mocks__/user.ts | 3 +- packages/core/src/libraries/user.test.ts | 87 ++++++++++++++++++- packages/core/src/libraries/user.ts | 44 +++++++++- packages/core/src/utils/password.ts | 1 - ...1709521416-user-password-encrypt-method.ts | 36 ++++++++ packages/schemas/tables/users.sql | 2 +- 6 files changed, 166 insertions(+), 7 deletions(-) create mode 100644 packages/schemas/alterations/next-1709521416-user-password-encrypt-method.ts diff --git a/packages/core/src/__mocks__/user.ts b/packages/core/src/__mocks__/user.ts index f9883193ebf..022740b9074 100644 --- a/packages/core/src/__mocks__/user.ts +++ b/packages/core/src/__mocks__/user.ts @@ -8,7 +8,8 @@ export const mockUser: User = { username: 'foo', primaryEmail: 'foo@logto.io', primaryPhone: '111111', - passwordEncrypted: 'password', + passwordEncrypted: + '$argon2i$v=19$m=4096,t=256,p=1$SYD0xSoVR8l+CN63Nz8fGw$ln5T09X9u4yd0DwLBKnlNV/eUHxwSWo32scw40ov4kI', passwordEncryptionMethod: UsersPasswordEncryptionMethod.Argon2i, name: null, avatar: null, diff --git a/packages/core/src/libraries/user.test.ts b/packages/core/src/libraries/user.test.ts index 8efb0b5afff..1ab423b0481 100644 --- a/packages/core/src/libraries/user.test.ts +++ b/packages/core/src/libraries/user.test.ts @@ -2,11 +2,12 @@ import { MfaFactor, UsersPasswordEncryptionMethod } from '@logto/schemas'; import { mockResource, mockAdminUserRole, mockScope } from '#src/__mocks__/index.js'; import { mockUser } from '#src/__mocks__/user.js'; +import RequestError from '#src/errors/RequestError/index.js'; import { MockQueries } from '#src/test-utils/tenant.js'; const { jest } = import.meta; -const { encryptUserPassword, createUserLibrary } = await import('./user.js'); +const { encryptUserPassword, createUserLibrary, verifyUserPassword } = await import('./user.js'); const hasUserWithId = jest.fn(); const updateUserById = jest.fn(); @@ -68,6 +69,90 @@ describe('encryptUserPassword()', () => { }); }); +describe('verifyUserPassword()', () => { + describe('Argon2', () => { + it('resolves when password is correct', async () => { + await expect( + verifyUserPassword(mockUser, 'HOH2hTmW0xtYAJUfRSQjJdW5') + ).resolves.not.toThrowError(); + }); + + it('rejects when password is incorrect', async () => { + await expect(verifyUserPassword(mockUser, 'wrong')).rejects.toThrowError( + new RequestError({ code: 'session.invalid_credentials', status: 422 }) + ); + }); + }); + + describe('MD5', () => { + const user = { + ...mockUser, + passwordEncrypted: '5f4dcc3b5aa765d61d8327deb882cf99', + passwordEncryptionMethod: UsersPasswordEncryptionMethod.MD5, + }; + it('resolves when password is correct', async () => { + await expect(verifyUserPassword(user, 'password')).resolves.not.toThrowError(); + }); + + it('rejects when password is incorrect', async () => { + await expect(verifyUserPassword(user, 'wrong')).rejects.toThrowError( + new RequestError({ code: 'session.invalid_credentials', status: 422 }) + ); + }); + }); + + describe('SHA1', () => { + const user = { + ...mockUser, + passwordEncrypted: '5baa61e4c9b93f3f0682250b6cf8331b7ee68fd8', + passwordEncryptionMethod: UsersPasswordEncryptionMethod.SHA1, + }; + it('resolves when password is correct', async () => { + await expect(verifyUserPassword(user, 'password')).resolves.not.toThrowError(); + }); + + it('rejects when password is incorrect', async () => { + await expect(verifyUserPassword(user, 'wrong')).rejects.toThrowError( + new RequestError({ code: 'session.invalid_credentials', status: 422 }) + ); + }); + }); + + describe('SHA256', () => { + const user = { + ...mockUser, + passwordEncrypted: '5e884898da28047151d0e56f8dc6292773603d0d6aabbdd62a11ef721d1542d8', + passwordEncryptionMethod: UsersPasswordEncryptionMethod.SHA256, + }; + it('resolves when password is correct', async () => { + await expect(verifyUserPassword(user, 'password')).resolves.not.toThrowError(); + }); + + it('rejects when password is incorrect', async () => { + await expect(verifyUserPassword(user, 'wrong')).rejects.toThrowError( + new RequestError({ code: 'session.invalid_credentials', status: 422 }) + ); + }); + }); + + describe('Bcrypt', () => { + const user = { + ...mockUser, + passwordEncrypted: '$2a$12$WQMqTfbtcZFBC1C1u8wpie6lXOSciUr5kk/8yEydoIMKltb9UKJ.6', + passwordEncryptionMethod: UsersPasswordEncryptionMethod.Bcrypt, + }; + it('resolves when password is correct', async () => { + await expect(verifyUserPassword(user, 'password')).resolves.not.toThrowError(); + }); + + it('rejects when password is incorrect', async () => { + await expect(verifyUserPassword(user, 'wrong')).rejects.toThrowError( + new RequestError({ code: 'session.invalid_credentials', status: 422 }) + ); + }); + }); +}); + describe('findUserScopesForResourceId()', () => { const { findUserScopesForResourceIndicator } = createUserLibrary(queries); diff --git a/packages/core/src/libraries/user.ts b/packages/core/src/libraries/user.ts index bf29868fc23..30012023fe4 100644 --- a/packages/core/src/libraries/user.ts +++ b/packages/core/src/libraries/user.ts @@ -4,7 +4,7 @@ import { generateStandardShortId, generateStandardId } from '@logto/shared'; import type { OmitAutoSetFields } from '@logto/shared'; import type { Nullable } from '@silverhand/essentials'; import { deduplicate } from '@silverhand/essentials'; -import { argon2Verify } from 'hash-wasm'; +import { argon2Verify, bcryptVerify, md5, sha1, sha256 } from 'hash-wasm'; import pRetry from 'p-retry'; import { buildInsertIntoWithPool } from '#src/database/insert-into.js'; @@ -40,9 +40,47 @@ export const verifyUserPassword = async (user: Nullable, password: string) new RequestError({ code: 'session.invalid_credentials', status: 422 }) ); - const result = await argon2Verify({ password, hash: passwordEncrypted }); + switch (passwordEncryptionMethod) { + case UsersPasswordEncryptionMethod.Argon2i: { + const result = await argon2Verify({ password, hash: passwordEncrypted }); + assertThat(result, new RequestError({ code: 'session.invalid_credentials', status: 422 })); + break; + } + case UsersPasswordEncryptionMethod.MD5: { + const expectedEncrypted = await md5(password); + assertThat( + expectedEncrypted === passwordEncrypted, + new RequestError({ code: 'session.invalid_credentials', status: 422 }) + ); + break; + } + case UsersPasswordEncryptionMethod.SHA1: { + const expectedEncrypted = await sha1(password); + assertThat( + expectedEncrypted === passwordEncrypted, + new RequestError({ code: 'session.invalid_credentials', status: 422 }) + ); + break; + } + case UsersPasswordEncryptionMethod.SHA256: { + const expectedEncrypted = await sha256(password); + assertThat( + expectedEncrypted === passwordEncrypted, + new RequestError({ code: 'session.invalid_credentials', status: 422 }) + ); + break; + } + case UsersPasswordEncryptionMethod.Bcrypt: { + const result = await bcryptVerify({ password, hash: passwordEncrypted }); + assertThat(result, new RequestError({ code: 'session.invalid_credentials', status: 422 })); + break; + } + default: { + throw new RequestError({ code: 'session.invalid_credentials', status: 422 }); + } + } - assertThat(result, new RequestError({ code: 'session.invalid_credentials', status: 422 })); + // TODO(@sijie) migrate to use argon2 return user; }; diff --git a/packages/core/src/utils/password.ts b/packages/core/src/utils/password.ts index 27a809cc51c..e5eb462016e 100644 --- a/packages/core/src/utils/password.ts +++ b/packages/core/src/utils/password.ts @@ -11,7 +11,6 @@ export const encryptPassword = async ( method: UsersPasswordEncryptionMethod ): Promise => { assertThat( - // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition method === UsersPasswordEncryptionMethod.Argon2i, new RequestError({ code: 'password.unsupported_encryption_method', method }) ); diff --git a/packages/schemas/alterations/next-1709521416-user-password-encrypt-method.ts b/packages/schemas/alterations/next-1709521416-user-password-encrypt-method.ts new file mode 100644 index 00000000000..38c75b868f5 --- /dev/null +++ b/packages/schemas/alterations/next-1709521416-user-password-encrypt-method.ts @@ -0,0 +1,36 @@ +import { sql } from 'slonik'; + +import type { AlterationScript } from '../lib/types/alteration.js'; + +const alteration: AlterationScript = { + up: async (pool) => { + await pool.query(sql` + alter type users_password_encryption_method add value 'SHA1'; + alter type users_password_encryption_method add value 'SHA256'; + alter type users_password_encryption_method add value 'MD5'; + alter type users_password_encryption_method add value 'Bcrypt'; + `); + }, + down: async (pool) => { + const { rows } = await pool.query(sql` + select id from users + where password_encryption_method <> ${'Argon2i'} + `); + if (rows.length > 0) { + throw new Error('There are users with password encryption methods other than Argon2i.'); + } + + await pool.query(sql` + create type users_password_encryption_method_revised as enum ('Argon2i'); + + alter table users + alter column password_encryption_method type users_password_encryption_method_revised + using password_encryption_method::text::users_password_encryption_method_revised; + + drop type users_password_encryption_method; + alter type users_password_encryption_method_revised rename to users_password_encryption_method; + `); + }, +}; + +export default alteration; diff --git a/packages/schemas/tables/users.sql b/packages/schemas/tables/users.sql index e873e6b710c..be43e5ac4a6 100644 --- a/packages/schemas/tables/users.sql +++ b/packages/schemas/tables/users.sql @@ -1,6 +1,6 @@ /* init_order = 1 */ -create type users_password_encryption_method as enum ('Argon2i'); +create type users_password_encryption_method as enum ('Argon2i', 'SHA1', 'SHA256', 'MD5', 'Bcrypt'); create table users ( tenant_id varchar(21) not null From 3b9edaea1489b08ec0bbb4eed5f89223820e4ef8 Mon Sep 17 00:00:00 2001 From: Gao Sun Date: Mon, 4 Mar 2024 12:15:57 +0800 Subject: [PATCH 004/687] chore(schemas): upgrade withtyped pacakge --- packages/schemas/package.json | 2 +- pnpm-lock.yaml | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/packages/schemas/package.json b/packages/schemas/package.json index a962a0687ef..38f5a725eaf 100644 --- a/packages/schemas/package.json +++ b/packages/schemas/package.json @@ -86,7 +86,7 @@ "@logto/phrases": "workspace:^1.9.0", "@logto/phrases-experience": "workspace:^1.6.0", "@logto/shared": "workspace:^3.1.0", - "@withtyped/server": "^0.13.1" + "@withtyped/server": "^0.13.3" }, "peerDependencies": { "zod": "^3.22.4" diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 2acfcc33217..ccdc8b0defd 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -3997,8 +3997,8 @@ importers: specifier: workspace:^3.1.0 version: link:../shared '@withtyped/server': - specifier: ^0.13.1 - version: 0.13.1(zod@3.22.4) + specifier: ^0.13.3 + version: 0.13.3(zod@3.22.4) zod: specifier: ^3.22.4 version: 3.22.4 @@ -10545,8 +10545,8 @@ packages: '@withtyped/shared': 0.2.2 zod: 3.22.4 - /@withtyped/server@0.13.1(zod@3.22.4): - resolution: {integrity: sha512-Fmmlw/7f3oidMS2tjgOx82BIkNEDBpHbFPj4oghXbyaZ8bgskLjKoLE0Qscbua6vhWUG4EgAmfR5ijSfg3bw2Q==} + /@withtyped/server@0.13.3(zod@3.22.4): + resolution: {integrity: sha512-MPyjRPQd5JySDnMnXPxGXXnw7AACAl8TLhWPjm4sdBgVMssSrmBbjRxBep0jY64PJ3xzICZh0ArWTRdXyNFIog==} peerDependencies: zod: ^3.19.1 dependencies: From 94d3b2c2e7230c14aff48d64f04dc454bf762b9a Mon Sep 17 00:00:00 2001 From: Xiao Yijun Date: Mon, 4 Mar 2024 14:05:23 +0800 Subject: [PATCH 005/687] refactor(schemas): regenerate dau table data from logs (#5455) --- .../next-1709528944-regenerate-dau-data.ts | 49 +++++++++++++++++++ 1 file changed, 49 insertions(+) create mode 100644 packages/schemas/alterations/next-1709528944-regenerate-dau-data.ts diff --git a/packages/schemas/alterations/next-1709528944-regenerate-dau-data.ts b/packages/schemas/alterations/next-1709528944-regenerate-dau-data.ts new file mode 100644 index 00000000000..1dc1ac5a66f --- /dev/null +++ b/packages/schemas/alterations/next-1709528944-regenerate-dau-data.ts @@ -0,0 +1,49 @@ +import { generateStandardId } from '@logto/shared/universal'; +import { sql } from 'slonik'; + +import type { AlterationScript } from '../lib/types/alteration.js'; + +type ActiveUserInteractionLog = { + tenantId: string; + userId: string; + createdAt: number; +}; + +const alteration: AlterationScript = { + up: async (pool) => { + // Delete all record from `daily_active_users` table + await pool.query(sql`delete from daily_active_users;`); + + // Retrieve all active user logs from `logs` table + const { rows: interactionLogs } = await pool.query(sql` + select tenant_id, payload->>'userId' as user_id, created_at + from logs + where payload->>'userId' is not null and key like 'ExchangeTokenBy.%' and payload->>'result' = 'Success' + `); + + if (interactionLogs.length === 0) { + console.log('No active user interaction logs found, skip alteration'); + return; + } + + // Generate DAU data from active user logs + for (const { tenantId, userId, createdAt } of interactionLogs) { + /** + * Note: we ignore the conflict here because conflict data may be inserted when staging. + */ + // eslint-disable-next-line no-await-in-loop + await pool.query(sql` + insert into daily_active_users (id, tenant_id, user_id, date) + values (${generateStandardId()},${tenantId}, ${userId}, ${new Date( + createdAt + ).toISOString()}) + on conflict do nothing; + `); + } + }, + down: async (pool) => { + // Cannot be reverted + }, +}; + +export default alteration; From cc01acbd0e5cced253ccdc2b7693c7860bdbb7d4 Mon Sep 17 00:00:00 2001 From: wangsijie Date: Mon, 4 Mar 2024 15:41:36 +0900 Subject: [PATCH 006/687] feat(core): create user with encrypted password (#5446) --- .changeset/real-eels-jam.md | 8 +++++ .../src/routes/admin-user/basic.openapi.json | 9 ++++++ .../core/src/routes/admin-user/basics.test.ts | 16 +++++++++- packages/core/src/routes/admin-user/basics.ts | 30 +++++++++++++++++-- .../integration-tests/src/api/admin-user.ts | 3 ++ .../integration-tests/src/helpers/index.ts | 7 ++++- .../src/tests/api/admin-user.test.ts | 15 ++++++++++ .../phrases/src/locales/de/errors/user.ts | 4 +++ .../phrases/src/locales/en/errors/user.ts | 2 ++ .../phrases/src/locales/es/errors/user.ts | 4 +++ .../phrases/src/locales/fr/errors/user.ts | 4 +++ .../phrases/src/locales/it/errors/user.ts | 4 +++ .../phrases/src/locales/ja/errors/user.ts | 4 +++ .../phrases/src/locales/ko/errors/user.ts | 4 +++ .../phrases/src/locales/pl-pl/errors/user.ts | 4 +++ .../phrases/src/locales/pt-br/errors/user.ts | 4 +++ .../phrases/src/locales/pt-pt/errors/user.ts | 4 +++ .../phrases/src/locales/ru/errors/user.ts | 4 +++ .../phrases/src/locales/tr-tr/errors/user.ts | 4 +++ .../phrases/src/locales/zh-cn/errors/user.ts | 4 +++ .../phrases/src/locales/zh-hk/errors/user.ts | 4 +++ .../phrases/src/locales/zh-tw/errors/user.ts | 4 +++ 22 files changed, 141 insertions(+), 5 deletions(-) create mode 100644 .changeset/real-eels-jam.md diff --git a/.changeset/real-eels-jam.md b/.changeset/real-eels-jam.md new file mode 100644 index 00000000000..cd8e618d50a --- /dev/null +++ b/.changeset/real-eels-jam.md @@ -0,0 +1,8 @@ +--- +"@logto/integration-tests": minor +"@logto/phrases": minor +"@logto/schemas": minor +"@logto/core": minor +--- + +Create a new user through API with password digest and corresponding algorithm diff --git a/packages/core/src/routes/admin-user/basic.openapi.json b/packages/core/src/routes/admin-user/basic.openapi.json index 9f8ea597767..75457348a83 100644 --- a/packages/core/src/routes/admin-user/basic.openapi.json +++ b/packages/core/src/routes/admin-user/basic.openapi.json @@ -124,6 +124,15 @@ }, "username": { "description": "Username for the user. It should be unique across all users." + }, + "password": { + "description": "Plain text password for the user." + }, + "passwordDigest": { + "description": "In case you already have the password digests and not the passwords, you can use them for the newly created user via this property. The value should be generated with one of the supported algorithms. The algorithm can be specified using the `passwordAlgorithm` property." + }, + "passwordAlgorithm": { + "description": "The hash algorithm used for the password. It should be one of the supported algorithms: argon2, md5, sha1, sha256. Should the encryption algorithm differ from argon2, it will automatically be upgraded to argon2 upon the user's next sign-in." } } } diff --git a/packages/core/src/routes/admin-user/basics.test.ts b/packages/core/src/routes/admin-user/basics.test.ts index 0c332b07859..77b03664d75 100644 --- a/packages/core/src/routes/admin-user/basics.test.ts +++ b/packages/core/src/routes/admin-user/basics.test.ts @@ -1,5 +1,5 @@ import type { CreateUser, Role, SignInExperience, User } from '@logto/schemas'; -import { RoleType } from '@logto/schemas'; +import { RoleType, UsersPasswordEncryptionMethod } from '@logto/schemas'; import { createMockUtils, pickDefault } from '@logto/shared/esm'; import { removeUndefinedKeys } from '@silverhand/essentials'; @@ -136,6 +136,20 @@ describe('adminUserRoutes', () => { ).resolves.toHaveProperty('status', 200); }); + it('POST /users with password digest', async () => { + const username = 'MJAtLogto'; + const name = 'Michael'; + + await expect( + userRequest.post('/users').send({ + username, + name, + passwordDigest: '5f4dcc3b5aa765d61d8327deb882cf99', + passwordAlgorithm: UsersPasswordEncryptionMethod.MD5, + }) + ).resolves.toHaveProperty('status', 200); + }); + it('POST /users should throw if username exists', async () => { const mockHasUser = hasUser as jest.Mock; mockHasUser.mockImplementationOnce(async () => true); diff --git a/packages/core/src/routes/admin-user/basics.ts b/packages/core/src/routes/admin-user/basics.ts index fe17335c28d..c9e994d9716 100644 --- a/packages/core/src/routes/admin-user/basics.ts +++ b/packages/core/src/routes/admin-user/basics.ts @@ -1,7 +1,12 @@ import { emailRegEx, phoneRegEx, usernameRegEx } from '@logto/core-kit'; -import { jsonObjectGuard, userInfoSelectFields, userProfileResponseGuard } from '@logto/schemas'; +import { + UsersPasswordEncryptionMethod, + jsonObjectGuard, + userInfoSelectFields, + userProfileResponseGuard, +} from '@logto/schemas'; import { conditional, pick, yes } from '@silverhand/essentials'; -import { boolean, literal, object, string } from 'zod'; +import { boolean, literal, nativeEnum, object, string } from 'zod'; import RequestError from '#src/errors/RequestError/index.js'; import { encryptUserPassword, verifyUserPassword } from '#src/libraries/user.js'; @@ -111,13 +116,26 @@ export default function adminUserBasicsRoutes(...args: R primaryEmail: string().regex(emailRegEx), username: string().regex(usernameRegEx), password: string().min(1), + passwordDigest: string(), + passwordAlgorithm: nativeEnum(UsersPasswordEncryptionMethod), name: string(), }).partial(), response: userProfileResponseGuard, status: [200, 404, 422], }), async (ctx, next) => { - const { primaryEmail, primaryPhone, username, password, name } = ctx.guard.body; + const { + primaryEmail, + primaryPhone, + username, + password, + name, + passwordDigest, + passwordAlgorithm, + } = ctx.guard.body; + + assertThat(!(password && passwordDigest), new RequestError('user.password_and_digest')); + assertThat(!passwordDigest || passwordAlgorithm, 'user.password_algorithm_required'); assertThat( !username || !(await hasUser(username)), @@ -148,6 +166,12 @@ export default function adminUserBasicsRoutes(...args: R username, name, ...conditional(password && (await encryptUserPassword(password))), + ...conditional( + passwordDigest && { + passwordEncrypted: passwordDigest, + passwordEncryptionMethod: passwordAlgorithm, + } + ), }, [] ); diff --git a/packages/integration-tests/src/api/admin-user.ts b/packages/integration-tests/src/api/admin-user.ts index 4a46a5ee772..a052d53c8a1 100644 --- a/packages/integration-tests/src/api/admin-user.ts +++ b/packages/integration-tests/src/api/admin-user.ts @@ -6,6 +6,7 @@ import type { Role, User, UserSsoIdentity, + UsersPasswordEncryptionMethod, } from '@logto/schemas'; import { conditional } from '@silverhand/essentials'; @@ -17,6 +18,8 @@ export type CreateUserPayload = Partial<{ username: string; password: string; name: string; + passwordDigest: string; + passwordAlgorithm: UsersPasswordEncryptionMethod; }>; export const createUser = async (payload: CreateUserPayload = {}) => diff --git a/packages/integration-tests/src/helpers/index.ts b/packages/integration-tests/src/helpers/index.ts index b5f93ca23f3..9ae080bb864 100644 --- a/packages/integration-tests/src/helpers/index.ts +++ b/packages/integration-tests/src/helpers/index.ts @@ -2,6 +2,7 @@ import fs from 'node:fs/promises'; import { createServer, type RequestListener } from 'node:http'; import { mockConnectorFilePaths, type SendMessagePayload } from '@logto/connector-kit'; +import { type UsersPasswordEncryptionMethod } from '@logto/schemas'; import { RequestError } from 'got'; import { createUser } from '#src/api/index.js'; @@ -12,7 +13,9 @@ export const createUserByAdmin = async ( password?: string, primaryEmail?: string, primaryPhone?: string, - name?: string + name?: string, + passwordDigest?: string, + passwordAlgorithm?: UsersPasswordEncryptionMethod ) => { return createUser({ username: username ?? generateUsername(), @@ -20,6 +23,8 @@ export const createUserByAdmin = async ( name: name ?? username ?? 'John', primaryEmail, primaryPhone, + passwordDigest, + passwordAlgorithm, }); }; diff --git a/packages/integration-tests/src/tests/api/admin-user.test.ts b/packages/integration-tests/src/tests/api/admin-user.test.ts index 01be84c3f1d..582dba88bf6 100644 --- a/packages/integration-tests/src/tests/api/admin-user.test.ts +++ b/packages/integration-tests/src/tests/api/admin-user.test.ts @@ -1,3 +1,4 @@ +import { UsersPasswordEncryptionMethod } from '@logto/schemas'; import { HTTPError } from 'got'; import { @@ -36,6 +37,20 @@ describe('admin console user management', () => { expect(userDetailsWithSsoIdentities.ssoIdentities).toStrictEqual([]); }); + it('should create user with password digest successfully', async () => { + const user = await createUserByAdmin( + undefined, + undefined, + undefined, + undefined, + undefined, + '5f4dcc3b5aa765d61d8327deb882cf99', + UsersPasswordEncryptionMethod.MD5 + ); + + await expect(verifyUserPassword(user.id, 'password')).resolves.not.toThrow(); + }); + it('should fail when create user with conflict identifiers', async () => { const [username, password, email, phone] = [ generateUsername(), diff --git a/packages/phrases/src/locales/de/errors/user.ts b/packages/phrases/src/locales/de/errors/user.ts index 34f4b6dface..e43dd16ca02 100644 --- a/packages/phrases/src/locales/de/errors/user.ts +++ b/packages/phrases/src/locales/de/errors/user.ts @@ -37,6 +37,10 @@ const user = { missing_mfa: 'Sie müssen zusätzliches MFA verbinden, bevor Sie sich anmelden können.', totp_already_in_use: 'TOTP wird bereits verwendet.', backup_code_already_in_use: 'Backup-Code wird bereits verwendet.', + /** UNTRANSLATED */ + password_algorithm_required: 'Password algorithm is required.', + /** UNTRANSLATED */ + password_and_digest: 'You cannot set both plain text password and password digest.', }; export default Object.freeze(user); diff --git a/packages/phrases/src/locales/en/errors/user.ts b/packages/phrases/src/locales/en/errors/user.ts index b935bd592a1..cff11815bdc 100644 --- a/packages/phrases/src/locales/en/errors/user.ts +++ b/packages/phrases/src/locales/en/errors/user.ts @@ -32,6 +32,8 @@ const user = { missing_mfa: 'You need to bind additional MFA before signing-in.', totp_already_in_use: 'TOTP is already in use.', backup_code_already_in_use: 'Backup code is already in use.', + password_algorithm_required: 'Password algorithm is required.', + password_and_digest: 'You cannot set both plain text password and password digest.', }; export default Object.freeze(user); diff --git a/packages/phrases/src/locales/es/errors/user.ts b/packages/phrases/src/locales/es/errors/user.ts index 15a57779174..3bcb5b3af4b 100644 --- a/packages/phrases/src/locales/es/errors/user.ts +++ b/packages/phrases/src/locales/es/errors/user.ts @@ -34,6 +34,10 @@ const user = { missing_mfa: 'Debes vincular un MFA adicional antes de iniciar sesión.', totp_already_in_use: 'TOTP ya está en uso.', backup_code_already_in_use: 'El código de respaldo ya está en uso.', + /** UNTRANSLATED */ + password_algorithm_required: 'Password algorithm is required.', + /** UNTRANSLATED */ + password_and_digest: 'You cannot set both plain text password and password digest.', }; export default Object.freeze(user); diff --git a/packages/phrases/src/locales/fr/errors/user.ts b/packages/phrases/src/locales/fr/errors/user.ts index 9959938e4e6..3737a685704 100644 --- a/packages/phrases/src/locales/fr/errors/user.ts +++ b/packages/phrases/src/locales/fr/errors/user.ts @@ -33,6 +33,10 @@ const user = { missing_mfa: 'Vous devez lier un MFA supplémentaire avant de vous connecter.', totp_already_in_use: 'TOTP est déjà utilisé.', backup_code_already_in_use: 'Le code de sauvegarde est déjà utilisé.', + /** UNTRANSLATED */ + password_algorithm_required: 'Password algorithm is required.', + /** UNTRANSLATED */ + password_and_digest: 'You cannot set both plain text password and password digest.', }; export default Object.freeze(user); diff --git a/packages/phrases/src/locales/it/errors/user.ts b/packages/phrases/src/locales/it/errors/user.ts index 5f5b0f4903b..2184b289e91 100644 --- a/packages/phrases/src/locales/it/errors/user.ts +++ b/packages/phrases/src/locales/it/errors/user.ts @@ -33,6 +33,10 @@ const user = { missing_mfa: "Devi legare un'ulteriore MFA prima di accedere.", totp_already_in_use: 'TOTP è già in uso.', backup_code_already_in_use: 'Il codice di backup è già in uso.', + /** UNTRANSLATED */ + password_algorithm_required: 'Password algorithm is required.', + /** UNTRANSLATED */ + password_and_digest: 'You cannot set both plain text password and password digest.', }; export default Object.freeze(user); diff --git a/packages/phrases/src/locales/ja/errors/user.ts b/packages/phrases/src/locales/ja/errors/user.ts index 370ebfd30fa..78abaa94f30 100644 --- a/packages/phrases/src/locales/ja/errors/user.ts +++ b/packages/phrases/src/locales/ja/errors/user.ts @@ -33,6 +33,10 @@ const user = { missing_mfa: 'MFAを追加してからサインインしてください。', totp_already_in_use: 'TOTPはすでに使用されています。', backup_code_already_in_use: 'バックアップコードはすでに使用されています。', + /** UNTRANSLATED */ + password_algorithm_required: 'Password algorithm is required.', + /** UNTRANSLATED */ + password_and_digest: 'You cannot set both plain text password and password digest.', }; export default Object.freeze(user); diff --git a/packages/phrases/src/locales/ko/errors/user.ts b/packages/phrases/src/locales/ko/errors/user.ts index 738affbe3bf..07415262af5 100644 --- a/packages/phrases/src/locales/ko/errors/user.ts +++ b/packages/phrases/src/locales/ko/errors/user.ts @@ -32,6 +32,10 @@ const user = { missing_mfa: 'You need to bind additional MFA before signing-in.', totp_already_in_use: 'TOTP is already in use.', backup_code_already_in_use: 'Backup code is already in use.', + /** UNTRANSLATED */ + password_algorithm_required: 'Password algorithm is required.', + /** UNTRANSLATED */ + password_and_digest: 'You cannot set both plain text password and password digest.', }; export default Object.freeze(user); diff --git a/packages/phrases/src/locales/pl-pl/errors/user.ts b/packages/phrases/src/locales/pl-pl/errors/user.ts index 524cb2a3579..516707d4b48 100644 --- a/packages/phrases/src/locales/pl-pl/errors/user.ts +++ b/packages/phrases/src/locales/pl-pl/errors/user.ts @@ -33,6 +33,10 @@ const user = { missing_mfa: 'You need to bind additional MFA before signing-in.', totp_already_in_use: 'TOTP is already in use.', backup_code_already_in_use: 'Backup code is already in use.', + /** UNTRANSLATED */ + password_algorithm_required: 'Password algorithm is required.', + /** UNTRANSLATED */ + password_and_digest: 'You cannot set both plain text password and password digest.', }; export default Object.freeze(user); diff --git a/packages/phrases/src/locales/pt-br/errors/user.ts b/packages/phrases/src/locales/pt-br/errors/user.ts index e5b078952ce..fd8f21da0b5 100644 --- a/packages/phrases/src/locales/pt-br/errors/user.ts +++ b/packages/phrases/src/locales/pt-br/errors/user.ts @@ -33,6 +33,10 @@ const user = { missing_mfa: 'Você precisa vincular MFA adicional antes de fazer login.', totp_already_in_use: 'TOTP já está em uso.', backup_code_already_in_use: 'O código de backup já está em uso.', + /** UNTRANSLATED */ + password_algorithm_required: 'Password algorithm is required.', + /** UNTRANSLATED */ + password_and_digest: 'You cannot set both plain text password and password digest.', }; export default Object.freeze(user); diff --git a/packages/phrases/src/locales/pt-pt/errors/user.ts b/packages/phrases/src/locales/pt-pt/errors/user.ts index 1fe77879727..602a8857aa3 100644 --- a/packages/phrases/src/locales/pt-pt/errors/user.ts +++ b/packages/phrases/src/locales/pt-pt/errors/user.ts @@ -33,6 +33,10 @@ const user = { missing_mfa: 'You need to bind additional MFA before signing-in.', totp_already_in_use: 'TOTP is already in use.', backup_code_already_in_use: 'Backup code is already in use.', + /** UNTRANSLATED */ + password_algorithm_required: 'Password algorithm is required.', + /** UNTRANSLATED */ + password_and_digest: 'You cannot set both plain text password and password digest.', }; export default Object.freeze(user); diff --git a/packages/phrases/src/locales/ru/errors/user.ts b/packages/phrases/src/locales/ru/errors/user.ts index 672c3a1c053..6ca739d0054 100644 --- a/packages/phrases/src/locales/ru/errors/user.ts +++ b/packages/phrases/src/locales/ru/errors/user.ts @@ -33,6 +33,10 @@ const user = { missing_mfa: 'You need to bind additional MFA before signing-in.', totp_already_in_use: 'TOTP is already in use.', backup_code_already_in_use: 'Backup code is already in use.', + /** UNTRANSLATED */ + password_algorithm_required: 'Password algorithm is required.', + /** UNTRANSLATED */ + password_and_digest: 'You cannot set both plain text password and password digest.', }; export default Object.freeze(user); diff --git a/packages/phrases/src/locales/tr-tr/errors/user.ts b/packages/phrases/src/locales/tr-tr/errors/user.ts index 3c50b6cc106..11ba8ded99d 100644 --- a/packages/phrases/src/locales/tr-tr/errors/user.ts +++ b/packages/phrases/src/locales/tr-tr/errors/user.ts @@ -32,6 +32,10 @@ const user = { missing_mfa: 'You need to bind additional MFA before signing-in.', totp_already_in_use: 'TOTP is already in use.', backup_code_already_in_use: 'Backup code is already in use.', + /** UNTRANSLATED */ + password_algorithm_required: 'Password algorithm is required.', + /** UNTRANSLATED */ + password_and_digest: 'You cannot set both plain text password and password digest.', }; export default Object.freeze(user); diff --git a/packages/phrases/src/locales/zh-cn/errors/user.ts b/packages/phrases/src/locales/zh-cn/errors/user.ts index 899dcade239..8fdbf7dd6d8 100644 --- a/packages/phrases/src/locales/zh-cn/errors/user.ts +++ b/packages/phrases/src/locales/zh-cn/errors/user.ts @@ -31,6 +31,10 @@ const user = { missing_mfa: '你需要在登录之前绑定额外的MFA。', totp_already_in_use: 'TOTP已在使用中。', backup_code_already_in_use: '备用代码已在使用中。', + /** UNTRANSLATED */ + password_algorithm_required: 'Password algorithm is required.', + /** UNTRANSLATED */ + password_and_digest: 'You cannot set both plain text password and password digest.', }; export default Object.freeze(user); diff --git a/packages/phrases/src/locales/zh-hk/errors/user.ts b/packages/phrases/src/locales/zh-hk/errors/user.ts index 81fe7efb15d..98b7938e4da 100644 --- a/packages/phrases/src/locales/zh-hk/errors/user.ts +++ b/packages/phrases/src/locales/zh-hk/errors/user.ts @@ -31,6 +31,10 @@ const user = { missing_mfa: '你需要在登錄前綁定額外的 MFA。', totp_already_in_use: 'TOTP 已經在使用中。', backup_code_already_in_use: '備份代碼已經在使用中。', + /** UNTRANSLATED */ + password_algorithm_required: 'Password algorithm is required.', + /** UNTRANSLATED */ + password_and_digest: 'You cannot set both plain text password and password digest.', }; export default Object.freeze(user); diff --git a/packages/phrases/src/locales/zh-tw/errors/user.ts b/packages/phrases/src/locales/zh-tw/errors/user.ts index ae767874e96..2ca2b159575 100644 --- a/packages/phrases/src/locales/zh-tw/errors/user.ts +++ b/packages/phrases/src/locales/zh-tw/errors/user.ts @@ -31,6 +31,10 @@ const user = { missing_mfa: '在登錄前需要綁定額外的多因素驗證。', totp_already_in_use: 'TOTP 已經在使用中。', backup_code_already_in_use: '備份代碼已經在使用中。', + /** UNTRANSLATED */ + password_algorithm_required: 'Password algorithm is required.', + /** UNTRANSLATED */ + password_and_digest: 'You cannot set both plain text password and password digest.', }; export default Object.freeze(user); From a0a19b13f9c547a76f5efee1a98f7c51a0b3e12d Mon Sep 17 00:00:00 2001 From: Xiao Yijun Date: Mon, 4 Mar 2024 14:59:56 +0800 Subject: [PATCH 007/687] refactor(core): migrate `dashboard/users/active` api data deps (#5457) --- .../core/src/queries/daily-active-user.ts | 30 ++++++++++++++++++- packages/core/src/routes/dashboard.test.ts | 6 ++-- packages/core/src/routes/dashboard.ts | 2 +- 3 files changed, 33 insertions(+), 5 deletions(-) diff --git a/packages/core/src/queries/daily-active-user.ts b/packages/core/src/queries/daily-active-user.ts index 547f6aa9194..00ebdcc199c 100644 --- a/packages/core/src/queries/daily-active-user.ts +++ b/packages/core/src/queries/daily-active-user.ts @@ -1,14 +1,42 @@ import { DailyActiveUsers } from '@logto/schemas'; -import type { CommonQueryMethods } from 'slonik'; +import { convertToIdentifiers } from '@logto/shared'; +import { sql, type CommonQueryMethods } from 'slonik'; import { buildInsertIntoWithPool } from '#src/database/insert-into.js'; +const { table, fields } = convertToIdentifiers(DailyActiveUsers); + export const createDailyActiveUsersQueries = (pool: CommonQueryMethods) => { const insertActiveUser = buildInsertIntoWithPool(pool)(DailyActiveUsers, { onConflict: { ignore: true }, }); + const countActiveUsersByTimeInterval = async ( + startTimeExclusive: number, + endTimeInclusive: number + ) => + pool.one<{ count: number }>(sql` + select count(distinct(${fields.userId})) + from ${table} + where ${fields.date} > to_timestamp(${startTimeExclusive}::double precision / 1000) + and ${fields.date} <= to_timestamp(${endTimeInclusive}::double precision / 1000) + `); + + const getDailyActiveUserCountsByTimeInterval = async ( + startTimeExclusive: number, + endTimeInclusive: number + ) => + pool.any<{ date: string; count: number }>(sql` + select date(${fields.date}), count(distinct(${fields.userId})) + from ${table} + where ${fields.date} > to_timestamp(${startTimeExclusive}::double precision / 1000) + and ${fields.date} <= to_timestamp(${endTimeInclusive}::double precision / 1000) + group by date(${fields.date}) + `); + return { insertActiveUser, + countActiveUsersByTimeInterval, + getDailyActiveUserCountsByTimeInterval, }; }; diff --git a/packages/core/src/routes/dashboard.test.ts b/packages/core/src/routes/dashboard.test.ts index ae7ef9ae1b9..04995739b79 100644 --- a/packages/core/src/routes/dashboard.test.ts +++ b/packages/core/src/routes/dashboard.test.ts @@ -41,13 +41,13 @@ const users = { }; const { countUsers, getDailyNewUserCountsByTimeInterval } = users; -const logs = { +const dailyActiveUsers = { getDailyActiveUserCountsByTimeInterval: jest.fn().mockResolvedValue(mockDailyActiveUserCounts), countActiveUsersByTimeInterval: jest.fn().mockResolvedValue({ count: mockActiveUserCount }), }; -const { getDailyActiveUserCountsByTimeInterval, countActiveUsersByTimeInterval } = logs; +const { getDailyActiveUserCountsByTimeInterval, countActiveUsersByTimeInterval } = dailyActiveUsers; -const tenantContext = new MockTenant(undefined, { logs, users }); +const tenantContext = new MockTenant(undefined, { dailyActiveUsers, users }); const dashboardRoutes = await pickDefault(import('./dashboard.js')); describe('dashboardRoutes', () => { diff --git a/packages/core/src/routes/dashboard.ts b/packages/core/src/routes/dashboard.ts index b5c29d5ffec..f5f7b7deb3b 100644 --- a/packages/core/src/routes/dashboard.ts +++ b/packages/core/src/routes/dashboard.ts @@ -17,7 +17,7 @@ export default function dashboardRoutes( ...[router, { queries }]: RouterInitArgs ) { const { - logs: { countActiveUsersByTimeInterval, getDailyActiveUserCountsByTimeInterval }, + dailyActiveUsers: { countActiveUsersByTimeInterval, getDailyActiveUserCountsByTimeInterval }, users: { countUsers, getDailyNewUserCountsByTimeInterval }, } = queries; From 3ae59baf6e05df8c5a65c1f3182bd20f7f1e5c92 Mon Sep 17 00:00:00 2001 From: Xiao Yijun Date: Mon, 4 Mar 2024 15:50:37 +0800 Subject: [PATCH 008/687] chore(core): deprecate unused query methods for logs table (#5464) --- packages/core/src/queries/log.ts | 31 +------------------------------ 1 file changed, 1 insertion(+), 30 deletions(-) diff --git a/packages/core/src/queries/log.ts b/packages/core/src/queries/log.ts index c6ddaf923fe..d8e632bee35 100644 --- a/packages/core/src/queries/log.ts +++ b/packages/core/src/queries/log.ts @@ -1,5 +1,5 @@ import { - token, + type token, type hook, Logs, type HookExecutionStats, @@ -77,33 +77,6 @@ export const createLogQueries = (pool: CommonQueryMethods) => { const findLogById = buildFindEntityByIdWithPool(pool)(Logs); - const getDailyActiveUserCountsByTimeInterval = async ( - startTimeExclusive: number, - endTimeInclusive: number - ) => - pool.any<{ date: string; count: number }>(sql` - select date(${fields.createdAt}), count(distinct(${fields.payload}->>'userId')) - from ${table} - where ${fields.createdAt} > to_timestamp(${startTimeExclusive}::double precision / 1000) - and ${fields.createdAt} <= to_timestamp(${endTimeInclusive}::double precision / 1000) - and ${fields.key} like ${`${token.Type.ExchangeTokenBy}.%`} - and ${fields.payload}->>'result' = 'Success' - group by date(${fields.createdAt}) - `); - - const countActiveUsersByTimeInterval = async ( - startTimeExclusive: number, - endTimeInclusive: number - ) => - pool.one<{ count: number }>(sql` - select count(distinct(${fields.payload}->>'userId')) - from ${table} - where ${fields.createdAt} > to_timestamp(${startTimeExclusive}::double precision / 1000) - and ${fields.createdAt} <= to_timestamp(${endTimeInclusive}::double precision / 1000) - and ${fields.key} like ${`${token.Type.ExchangeTokenBy}.%`} - and ${fields.payload}->>'result' = 'Success' - `); - const getHookExecutionStatsByHookId = async (hookId: string) => { const startTimeExclusive = subDays(new Date(), 1).getTime(); return pool.one(sql` @@ -120,8 +93,6 @@ export const createLogQueries = (pool: CommonQueryMethods) => { countLogs, findLogs, findLogById, - getDailyActiveUserCountsByTimeInterval, - countActiveUsersByTimeInterval, getHookExecutionStatsByHookId, }; }; From b47c2a2de196c758e6197b58fb78e3a5e4ab4d3d Mon Sep 17 00:00:00 2001 From: Gao Sun Date: Tue, 5 Mar 2024 11:41:39 +0800 Subject: [PATCH 009/687] refactor(console): refactor conversion tracking (#5466) * refactor(console): refactor conversion tracking * refactor(console): manually set enhanced user data * refactor: report production tenant conversion * refactor(console): use transaction id for reporting --- packages/console/src/App.tsx | 8 +- .../src/components/Conversion/index.tsx | 117 ++++++++++++++++++ .../src/components/Conversion/use-retry.ts | 52 ++++++++ .../utils.test.ts | 0 .../src/components/Conversion/utils.ts | 106 ++++++++++++++++ .../SelectTenantPlanModal/index.tsx | 2 + .../src/components/ReportConversion/index.tsx | 85 ------------- .../src/components/ReportConversion/utils.ts | 88 ------------- packages/console/src/consts/env.ts | 1 - packages/console/src/include.d/tags.d.ts | 11 +- packages/console/src/onboarding/index.tsx | 22 +++- .../pages/CheckoutSuccessCallback/index.tsx | 11 +- 12 files changed, 316 insertions(+), 187 deletions(-) create mode 100644 packages/console/src/components/Conversion/index.tsx create mode 100644 packages/console/src/components/Conversion/use-retry.ts rename packages/console/src/components/{ReportConversion => Conversion}/utils.test.ts (100%) create mode 100644 packages/console/src/components/Conversion/utils.ts delete mode 100644 packages/console/src/components/ReportConversion/index.tsx delete mode 100644 packages/console/src/components/ReportConversion/utils.ts diff --git a/packages/console/src/App.tsx b/packages/console/src/App.tsx index 007f035a99b..3f2ab4b6935 100644 --- a/packages/console/src/App.tsx +++ b/packages/console/src/App.tsx @@ -27,6 +27,7 @@ import { OnboardingRoutes } from '@/onboarding'; import useUserOnboardingData from '@/onboarding/hooks/use-user-onboarding-data'; import { ConsoleRoutes } from '@/pages/ConsoleRoutes'; +import { GlobalScripts } from './components/Conversion'; import { adminTenantEndpoint, mainTitle } from './consts'; import ErrorBoundary from './containers/ErrorBoundary'; import LogtoErrorBoundary from './containers/LogtoErrorBoundary'; @@ -153,5 +154,10 @@ function AppRoutes() { return ; } - return isAuthenticated && isOnboarding ? : ; + return ( + <> + + {isAuthenticated && isOnboarding ? : } + + ); } diff --git a/packages/console/src/components/Conversion/index.tsx b/packages/console/src/components/Conversion/index.tsx new file mode 100644 index 00000000000..450249c1c25 --- /dev/null +++ b/packages/console/src/components/Conversion/index.tsx @@ -0,0 +1,117 @@ +import { useEffect, useState } from 'react'; +import { Helmet } from 'react-helmet'; + +import useCurrentUser from '@/hooks/use-current-user'; + +import { useRetry } from './use-retry'; +import { + shouldReport, + gtagAwTrackingId, + redditPixelId, + hashEmail, + type GtagConversionId, + type RedditReportType, + reportToGoogle, + reportToReddit, +} from './utils'; + +type ScriptProps = { + userEmailHash?: string; +}; + +function GoogleScripts({ userEmailHash }: ScriptProps) { + if (!userEmailHash) { + return null; + } + + return ( + + + + ); +} + +function RedditScripts({ userEmailHash }: ScriptProps) { + if (!userEmailHash) { + return null; + } + + return ( + + + + ); +} + +/** + * Renders global scripts for conversion tracking. + */ +export function GlobalScripts() { + const { user, isLoaded } = useCurrentUser(); + const [userEmailHash, setUserEmailHash] = useState(); + + /** + * Use user email to prevent duplicate conversion, and it is hashed before sending + * to protect user privacy. + */ + useEffect(() => { + const init = async () => { + setUserEmailHash(await hashEmail(user?.primaryEmail ?? undefined)); + }; + + if (isLoaded) { + void init(); + } + }, [user, isLoaded]); + + if (!shouldReport) { + return null; + } + + return ( + <> + + + + ); +} + +type ReportConversionOptions = { + transactionId?: string; + gtagId?: GtagConversionId; + redditType?: RedditReportType; +}; + +export const useReportConversion = ({ + gtagId, + redditType, + transactionId, +}: ReportConversionOptions) => { + useRetry({ + precondition: Boolean(shouldReport && gtagId), + execute: () => (gtagId ? reportToGoogle(gtagId, { transactionId }) : false), + }); + + useRetry({ + precondition: Boolean(shouldReport && redditType), + execute: () => (redditType ? reportToReddit(redditType) : false), + }); +}; diff --git a/packages/console/src/components/Conversion/use-retry.ts b/packages/console/src/components/Conversion/use-retry.ts new file mode 100644 index 00000000000..da7c73f0d00 --- /dev/null +++ b/packages/console/src/components/Conversion/use-retry.ts @@ -0,0 +1,52 @@ +import { useEffect } from 'react'; + +type UseRetryOptions = { + /** The precondition to check before executing the function. */ + precondition: boolean; + /** The function to execute when the precondition is not met. */ + onPreconditionFailed?: () => void; + /** The function to execute. If it returns `true`, the retry will stop. */ + execute: () => boolean; + /** + * The maximum number of retries. + * + * @default 3 + */ + maxRetry?: number; +}; + +/** + * A hook to retry a function until the condition is met. The retry interval is 1 second. + */ +export const useRetry = ({ + precondition, + onPreconditionFailed, + execute, + maxRetry = 3, +}: UseRetryOptions) => { + useEffect(() => { + if (!precondition) { + onPreconditionFailed?.(); + } + }, [onPreconditionFailed, precondition]); + + useEffect(() => { + if (!precondition) { + return; + } + + // eslint-disable-next-line @silverhand/fp/no-let + let retry = 0; + const interval = setInterval(() => { + if (execute() || retry >= maxRetry) { + clearInterval(interval); + } + // eslint-disable-next-line @silverhand/fp/no-mutation + retry += 1; + }, 1000); + + return () => { + clearInterval(interval); + }; + }, [execute, maxRetry, precondition]); +}; diff --git a/packages/console/src/components/ReportConversion/utils.test.ts b/packages/console/src/components/Conversion/utils.test.ts similarity index 100% rename from packages/console/src/components/ReportConversion/utils.test.ts rename to packages/console/src/components/Conversion/utils.test.ts diff --git a/packages/console/src/components/Conversion/utils.ts b/packages/console/src/components/Conversion/utils.ts new file mode 100644 index 00000000000..16b73f467af --- /dev/null +++ b/packages/console/src/components/Conversion/utils.ts @@ -0,0 +1,106 @@ +import { cond } from '@silverhand/essentials'; + +import { isProduction } from '@/consts/env'; + +export const gtagAwTrackingId = 'AW-11124811245'; +export enum GtagConversionId { + /** This ID indicates a user has truly signed up for Logto Cloud. */ + SignUp = 'AW-11192640559/ZuqUCLvNpasYEK_IiNkp', + /** This ID indicates a user has created a production tenant. */ + CreateProductionTenant = 'AW-11192640559/m04fCMDrxI0ZEK_IiNkp', + /** This ID indicates a user has purchased a Pro plan. */ + PurchaseProPlan = 'AW-11192640559/WjCtCKHCtpgZEK_IiNkp', +} + +export const redditPixelId = 't2_ggt11omdo'; + +const logtoProductionHostname = 'logto.io'; + +/** + * Due to the special of conversion reporting, it should be `true` only in the + * Logto Cloud production environment. + * Add the leading '.' to make it safer (ignore hostnames like "foologto.io"). + */ +export const shouldReport = window.location.hostname.endsWith('.' + logtoProductionHostname); + +const sha256 = async (message: string) => { + const hash = await crypto.subtle.digest('SHA-256', new TextEncoder().encode(message)); + // https://stackoverflow.com/questions/40031688/javascript-arraybuffer-to-hex + return [...new Uint8Array(hash)].map((value) => value.toString(16).padStart(2, '0')).join(''); +}; + +/** + * This function will do the following things: + * + * 1. Canonicalize the given email by Reddit's rule: lowercase, trim, + * remove dots, remove everything after the first '+'. + * 2. Hash the canonicalized email by SHA256. + */ +export const hashEmail = async (email?: string) => { + if (!email) { + return; + } + + const splitEmail = email.toLocaleLowerCase().trim().split('@'); + const [localPart, domain] = splitEmail; + + if (!localPart || !domain || splitEmail.length > 2) { + return; + } + + // eslint-disable-next-line unicorn/prefer-string-replace-all + const canonicalizedEmail = `${localPart.replace(/\./g, '').replace(/\+.*/, '')}@${domain}`; + return sha256(canonicalizedEmail); +}; + +/** Print debug message if not in production. */ +const debug = (...args: Parameters<(typeof console)['debug']>) => { + if (!isProduction) { + console.debug(...args); + } +}; + +/** + * Add more if needed: https://reddit.my.site.com/helpcenter/s/article/Install-the-Reddit-Pixel-on-your-website + */ +export type RedditReportType = + | 'PageVisit' + | 'ViewContent' + | 'Search' + | 'Purchase' + | 'Lead' + | 'SignUp'; + +export const reportToReddit = (redditType: RedditReportType) => { + if (!window.rdt) { + return false; + } + + debug('report:', 'redditType =', redditType); + window.rdt('track', redditType); + + return true; +}; + +export const reportToGoogle = ( + gtagId: GtagConversionId, + { transactionId }: { transactionId?: string } = {} +) => { + if (!window.gtag) { + return false; + } + + const run = async () => { + const transaction = cond(transactionId && { transaction_id: await sha256(transactionId) }); + + debug('report:', 'gtagId =', gtagId, 'transaction =', transaction); + window.gtag?.('event', 'conversion', { + send_to: gtagId, + ...transaction, + }); + }; + + void run(); + + return true; +}; diff --git a/packages/console/src/components/CreateTenantModal/SelectTenantPlanModal/index.tsx b/packages/console/src/components/CreateTenantModal/SelectTenantPlanModal/index.tsx index 7c4fc8ccfa3..8609fede8b7 100644 --- a/packages/console/src/components/CreateTenantModal/SelectTenantPlanModal/index.tsx +++ b/packages/console/src/components/CreateTenantModal/SelectTenantPlanModal/index.tsx @@ -5,6 +5,7 @@ import Modal from 'react-modal'; import { useCloudApi, toastResponseError } from '@/cloud/hooks/use-cloud-api'; import { type TenantResponse } from '@/cloud/types/router'; +import { GtagConversionId, reportToGoogle } from '@/components/Conversion/utils'; import { pricingLink } from '@/consts'; import DangerousRaw from '@/ds-components/DangerousRaw'; import ModalLayout from '@/ds-components/ModalLayout'; @@ -43,6 +44,7 @@ function SelectTenantPlanModal({ tenantData, onClose }: Props) { const { name, tag } = tenantData; const newTenant = await cloudApi.post('/api/tenants', { body: { name, tag } }); + reportToGoogle(GtagConversionId.CreateProductionTenant, { transactionId: newTenant.id }); onClose(newTenant); return; } diff --git a/packages/console/src/components/ReportConversion/index.tsx b/packages/console/src/components/ReportConversion/index.tsx deleted file mode 100644 index 6fc8a209d69..00000000000 --- a/packages/console/src/components/ReportConversion/index.tsx +++ /dev/null @@ -1,85 +0,0 @@ -import { useEffect } from 'react'; -import { Helmet } from 'react-helmet'; - -import useCurrentUser from '@/hooks/use-current-user'; - -import { - shouldReport, - lintrk, - gtagAwTrackingId, - linkedInConversionId, - gtag, - gtagSignUpConversionId, - rdt, - redditPixelId, - hashEmail, -} from './utils'; - -/** - * In cloud production environment, this component initiates gtag.js and LinkedIn - * Insight Tag, then reports a sign-up conversion to them. - */ -export default function ReportConversion() { - const { user, isLoading } = useCurrentUser(); - - /** - * Initiate Reddit Pixel and report a sign-up conversion to it when user is loaded. - * Use user email to prevent duplicate conversion, and it is hashed before sending - * to protect user privacy. - */ - useEffect(() => { - const report = async () => { - rdt('init', redditPixelId, { - optOut: false, - useDecimalCurrencyValues: true, - email: await hashEmail(user?.primaryEmail ?? undefined), - }); - rdt('track', 'SignUp'); - }; - - if (shouldReport && !isLoading) { - void report(); - } - }, [user, isLoading]); - - /** - * This `useEffect()` initiates Google Tag and report a sign-up conversion to it. - * It may run multiple times (e.g. a user visit multiple times to finish the onboarding process, - * which rarely happens), but it'll be okay since we've set conversion's "Count" to "One" - * which means only the first interaction is valuable. - * - * Track this conversion in the backend has been considered, but Google does not provide - * a clear guideline for it and marks the [Node library](https://developers.google.com/tag-platform/tag-manager/api/v2/libraries) - * as "alpha" which looks unreliable. - */ - useEffect(() => { - if (shouldReport) { - gtag('js', new Date()); - gtag('config', gtagAwTrackingId); - gtag('event', 'conversion', { - send_to: gtagSignUpConversionId, - }); - - lintrk('track', { conversion_id: linkedInConversionId }); - console.debug('Have a good day!'); - } else { - console.debug("Not reporting conversion because it's not production"); - } - }, []); - - if (shouldReport) { - return ( - - + + ); +} + /** * Renders global scripts for conversion tracking. */ @@ -88,6 +103,7 @@ export function GlobalScripts() { return ( <> + diff --git a/packages/console/src/components/Conversion/utils.ts b/packages/console/src/components/Conversion/utils.ts index 16b73f467af..d63b052daba 100644 --- a/packages/console/src/components/Conversion/utils.ts +++ b/packages/console/src/components/Conversion/utils.ts @@ -13,6 +13,7 @@ export enum GtagConversionId { } export const redditPixelId = 't2_ggt11omdo'; +export const plausibleDataDomain = 'cloud.logto.io'; const logtoProductionHostname = 'logto.io'; diff --git a/packages/console/src/containers/ConsoleContent/index.tsx b/packages/console/src/containers/ConsoleContent/index.tsx index 3449daa4139..651982374c6 100644 --- a/packages/console/src/containers/ConsoleContent/index.tsx +++ b/packages/console/src/containers/ConsoleContent/index.tsx @@ -1,7 +1,8 @@ -import { useOutletContext } from 'react-router-dom'; +import { useOutletContext, useRoutes } from 'react-router-dom'; import OverlayScrollbar from '@/ds-components/OverlayScrollbar'; import { useConsoleRoutes } from '@/hooks/use-console-routes'; +import { usePlausiblePageview } from '@/hooks/use-plausible-pageview'; import type { AppContentOutletContext } from '../AppContent/types'; @@ -11,9 +12,11 @@ import * as styles from './index.module.scss'; function ConsoleContent() { const { scrollableContent } = useOutletContext(); - const routes = useConsoleRoutes(); + const routeObjects = useConsoleRoutes(); + const routes = useRoutes(routeObjects); // Use this hook here to make sure console listens to user tenant scope changes. useTenantScopeListener(); + usePlausiblePageview(routeObjects); return (
diff --git a/packages/console/src/hooks/use-console-routes/index.tsx b/packages/console/src/hooks/use-console-routes/index.tsx index a3c4df02a44..61d5db43eb1 100644 --- a/packages/console/src/hooks/use-console-routes/index.tsx +++ b/packages/console/src/hooks/use-console-routes/index.tsx @@ -1,6 +1,6 @@ import { condArray } from '@silverhand/essentials'; import { useMemo } from 'react'; -import { type RouteObject, useRoutes } from 'react-router-dom'; +import { type RouteObject } from 'react-router-dom'; import { isCloud, isDevFeaturesEnabled } from '@/consts/env'; import Dashboard from '@/pages/Dashboard'; @@ -54,7 +54,6 @@ export const useConsoleRoutes = () => { ), [tenantSettings] ); - const routes = useRoutes(routeObjects); - return routes; + return routeObjects; }; diff --git a/packages/console/src/hooks/use-plausible-pageview.ts b/packages/console/src/hooks/use-plausible-pageview.ts new file mode 100644 index 00000000000..f4135a9509e --- /dev/null +++ b/packages/console/src/hooks/use-plausible-pageview.ts @@ -0,0 +1,26 @@ +import { appendPath } from '@silverhand/essentials'; +import debug from 'debug'; +import { useEffect } from 'react'; +import { type RouteObject, useLocation } from 'react-router-dom'; + +import { plausibleDataDomain } from '@/components/Conversion/utils'; +import { getRoutePattern } from '@/utils/route'; + +const log = debug('usePlausiblePageview'); + +export const usePlausiblePageview = (routes: RouteObject[]) => { + const { pathname } = useLocation(); + + useEffect(() => { + const routePattern = getRoutePattern(pathname, routes); + + log('pageview', routePattern); + + // https://plausible.io/docs/custom-locations#3-specify-a-custom-location + window.plausible?.('pageview', { + u: + appendPath(new URL('https://' + plausibleDataDomain), routePattern).href + + window.location.search, + }); + }, [pathname, routes]); +}; diff --git a/packages/console/src/include.d/tags.d.ts b/packages/console/src/include.d/tags.d.ts index e315ba04b4f..09550516dbb 100644 --- a/packages/console/src/include.d/tags.d.ts +++ b/packages/console/src/include.d/tags.d.ts @@ -3,4 +3,6 @@ declare interface Window { gtag?: (...args: unknown[]) => void; // Reddit rdt?: (...args: unknown[]) => void; + // Plausible + plausible?: (...args: unknown[]) => void; } diff --git a/packages/console/src/onboarding/containers/AppContent/index.tsx b/packages/console/src/onboarding/containers/AppContent/index.tsx index c31d7aa073f..69f35bb7a3f 100644 --- a/packages/console/src/onboarding/containers/AppContent/index.tsx +++ b/packages/console/src/onboarding/containers/AppContent/index.tsx @@ -1,16 +1,47 @@ -import { Outlet } from 'react-router-dom'; +import { useRoutes, type RouteObject, Navigate } from 'react-router-dom'; +import { usePlausiblePageview } from '@/hooks/use-plausible-pageview'; import Topbar from '@/onboarding/components/Topbar'; +import SignInExperience from '@/onboarding/pages/SignInExperience'; +import Welcome from '@/onboarding/pages/Welcome'; +import { OnboardingPage, OnboardingRoute } from '@/onboarding/types'; +import NotFound from '@/pages/NotFound'; import * as styles from './index.module.scss'; +const routeObjects: RouteObject[] = [ + { + path: OnboardingRoute.Onboarding, + children: [ + { + index: true, + element: , + }, + { + path: OnboardingPage.Welcome, + element: , + }, + { + path: OnboardingPage.SignInExperience, + element: , + }, + ], + }, + { + path: '*', + element: , + }, +]; + function AppContent() { + const routes = useRoutes(routeObjects); + + usePlausiblePageview(routeObjects); + return (
-
- -
+
{routes}
); } diff --git a/packages/console/src/onboarding/index.tsx b/packages/console/src/onboarding/index.tsx index 1c60a282f0a..4f3bf45c911 100644 --- a/packages/console/src/onboarding/index.tsx +++ b/packages/console/src/onboarding/index.tsx @@ -15,13 +15,10 @@ import Toast from '@/ds-components/Toast'; import useCurrentUser from '@/hooks/use-current-user'; import useSwrOptions from '@/hooks/use-swr-options'; import useTenantPathname from '@/hooks/use-tenant-pathname'; -import NotFound from '@/pages/NotFound'; import AppContent from './containers/AppContent'; import useUserOnboardingData from './hooks/use-user-onboarding-data'; import * as styles from './index.module.scss'; -import SignInExperience from './pages/SignInExperience'; -import Welcome from './pages/Welcome'; import { OnboardingPage, OnboardingRoute } from './types'; import { getOnboardingPage } from './utils'; @@ -88,12 +85,7 @@ export function OnboardingRoutes() { }> }> } /> - }> - } /> - } /> - } /> - - } /> + } /> diff --git a/packages/console/src/utils/route.ts b/packages/console/src/utils/route.ts new file mode 100644 index 00000000000..1afaa57a9ef --- /dev/null +++ b/packages/console/src/utils/route.ts @@ -0,0 +1,31 @@ +import { matchRoutes, type RouteObject } from 'react-router-dom'; + +export const getRoutePattern = (pathname: string, routes: RouteObject[]) => { + // Remove the first segment of the pathname, which is the tenant ID. + const normalized = pathname.replace(/^\/[^/]+/, ''); + const matches = matchRoutes(routes, normalized) ?? []; + return ( + '/' + + matches + .filter((match) => !match.route.index) + .flatMap(({ route: { path }, params }) => { + // Path could have multiple segments, e.g. 'api-resources/:id/*'. + const segments = path?.split('/') ?? []; + + return segments.map((segment) => { + if (segment === '*') { + return params['*'] ?? segment; + } + + // If the path is not a parameter, or it's an ID parameter, use the path as is. + if (!segment.startsWith(':') || segment.endsWith('Id') || segment.endsWith('id')) { + return segment; + } + + // Otherwise, use the parameter value. + return params[segment.slice(1)] ?? segment; + }); + }) + .join('/') + ); +}; diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 54e091fc366..9796db70c65 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -2792,6 +2792,9 @@ importers: '@types/color': specifier: ^3.0.3 version: 3.0.3 + '@types/debug': + specifier: ^4.1.7 + version: 4.1.7 '@types/jest': specifier: ^29.4.0 version: 29.4.0 @@ -2843,6 +2846,9 @@ importers: dayjs: specifier: ^1.10.5 version: 1.11.6 + debug: + specifier: ^4.3.4 + version: 4.3.4 deep-object-diff: specifier: ^1.1.9 version: 1.1.9 @@ -15656,7 +15662,7 @@ packages: jest: ^28.1.0 || ^29.1.2 react: ^17.0.0 || ^18.0.0 dependencies: - jest: 29.7.0(@types/node@20.11.20) + jest: 29.7.0(@types/node@20.11.20)(ts-node@10.9.2) react: 18.2.0 dev: true From ddd99865a5796fa8741dd385dd8a290ef8979cf1 Mon Sep 17 00:00:00 2001 From: Xiao Yijun Date: Wed, 17 Apr 2024 16:02:17 +0800 Subject: [PATCH 283/687] refactor(console,phrases): update phrases for organization role (#5736) --- .../Guide/Introduction/index.tsx | 23 +++++++++++++------ .../organization-role-details.ts | 6 ++--- .../admin-console/organizations.ts | 4 +++- .../organization-role-details.ts | 6 ++--- .../admin-console/organizations.ts | 4 +++- .../organization-role-details.ts | 4 ++-- .../admin-console/organizations.ts | 4 +++- .../organization-role-details.ts | 4 ++-- .../admin-console/organizations.ts | 4 +++- .../organization-role-details.ts | 4 ++-- .../admin-console/organizations.ts | 4 +++- .../organization-role-details.ts | 4 ++-- .../admin-console/organizations.ts | 4 +++- .../organization-role-details.ts | 2 +- .../admin-console/organizations.ts | 5 +++- .../organization-role-details.ts | 4 ++-- .../admin-console/organizations.ts | 4 +++- .../organization-role-details.ts | 4 ++-- .../admin-console/organizations.ts | 4 +++- .../organization-role-details.ts | 6 ++--- .../admin-console/organizations.ts | 4 +++- .../organization-role-details.ts | 4 ++-- .../admin-console/organizations.ts | 4 +++- .../organization-role-details.ts | 4 ++-- .../admin-console/organizations.ts | 4 +++- .../organization-role-details.ts | 2 +- .../admin-console/organizations.ts | 3 ++- .../organization-role-details.ts | 2 +- .../admin-console/organizations.ts | 3 ++- .../organization-role-details.ts | 2 +- .../admin-console/organizations.ts | 3 ++- 31 files changed, 88 insertions(+), 51 deletions(-) diff --git a/packages/console/src/pages/Organizations/Guide/Introduction/index.tsx b/packages/console/src/pages/Organizations/Guide/Introduction/index.tsx index 21aef08d103..ad4e8e22dd4 100644 --- a/packages/console/src/pages/Organizations/Guide/Introduction/index.tsx +++ b/packages/console/src/pages/Organizations/Guide/Introduction/index.tsx @@ -5,6 +5,7 @@ import { useTranslation } from 'react-i18next'; import OrganizationFeatureDark from '@/assets/icons/organization-feature-dark.svg'; import OrganizationFeature from '@/assets/icons/organization-feature.svg'; import ActionBar from '@/components/ActionBar'; +import { isDevFeaturesEnabled } from '@/consts/env'; import Button from '@/ds-components/Button'; import Card from '@/ds-components/Card'; import OverlayScrollbar from '@/ds-components/OverlayScrollbar'; @@ -86,7 +87,11 @@ function Introduction({ isReadonly }: Props) {
- -
{t('guide.introduction.section_3.title')}
-
- {t('guide.introduction.section_3.description')} -
-
+ {isDevFeaturesEnabled && ( + +
+ {t('guide.introduction.section_3.title')} +
+
+ {t('guide.introduction.section_3.description')} +
+
+ )}
{t('guide.introduction.section_4.title')}
diff --git a/packages/phrases/src/locales/de/translation/admin-console/organization-role-details.ts b/packages/phrases/src/locales/de/translation/admin-console/organization-role-details.ts index 71b51d09594..3c0d2f296ae 100644 --- a/packages/phrases/src/locales/de/translation/admin-console/organization-role-details.ts +++ b/packages/phrases/src/locales/de/translation/admin-console/organization-role-details.ts @@ -4,7 +4,7 @@ const organization_role_details = { org_role: 'Org-Rolle', delete_confirm: 'Dadurch werden die mit dieser Rolle verbundenen Berechtigungen von den betroffenen Benutzern entfernt und die Beziehungen zwischen Organisationsrollen, Mitgliedern in der Organisation und Organisationsberechtigungen gelöscht.', - deleted: 'Organisationsrolle {{name}} wurde erfolgreich gelöscht.', + deleted: 'Die Organisationsrolle {{name}} wurde erfolgreich gelöscht.', permissions: { tab: 'Berechtigungen', name_column: 'Berechtigung', @@ -12,7 +12,7 @@ const organization_role_details = { type_column: 'Berechtigungstyp', type: { api: 'API-Berechtigung', - org: 'Org-Berechtigung', + org: 'Organisationsberechtigung', }, assign_permissions: 'Berechtigungen zuweisen', remove_permission: 'Berechtigung entfernen', @@ -30,7 +30,7 @@ const organization_role_details = { tab: 'Allgemein', settings: 'Einstellungen', description: - 'Die Organisationsrolle ist eine Gruppierung von Berechtigungen, die Benutzern zugewiesen werden können. Die Berechtigungen müssen aus den vordefinierten Organisationsberechtigungen stammen.', + 'Die Organisationsrolle ist eine Gruppierung von Berechtigungen, die Benutzern zugewiesen werden können. Die Berechtigungen können aus den vordefinierten Organisationsberechtigungen und API-Berechtigungen stammen.', name_field: 'Name', description_field: 'Beschreibung', description_field_placeholder: 'Benutzer mit nur Leseberechtigungen', diff --git a/packages/phrases/src/locales/de/translation/admin-console/organizations.ts b/packages/phrases/src/locales/de/translation/admin-console/organizations.ts index c910092997b..d4977c8e988 100644 --- a/packages/phrases/src/locales/de/translation/admin-console/organizations.ts +++ b/packages/phrases/src/locales/de/translation/admin-console/organizations.ts @@ -54,8 +54,10 @@ const organizations = { 'In Multi-Tenant-SaaS-Anwendungen teilen häufig mehrere Organisationen dieselbe Zugriffskontrollvorlage, zu der Berechtigungen und Rollen gehören. In Logto nennen wir es "Organisationsvorlage".', permission_description: 'Die Organisationsberechtigung bezieht sich auf die Autorisierung zum Zugriff auf eine Ressource im Kontext der Organisation.', - role_description: + role_description_deprecated: 'Eine Organisationsrolle ist eine Gruppierung von Organisationsberechtigungen, die Benutzern zugewiesen werden können.', + role_description: + 'Die Organisationsrolle ist eine Gruppierung von Organisationsberechtigungen oder API-Berechtigungen, die Mitgliedern zugewiesen werden können.', }, section_3: { title: 'Kann ich API-Berechtigungen zu Organisationsrollen zuweisen?', diff --git a/packages/phrases/src/locales/en/translation/admin-console/organization-role-details.ts b/packages/phrases/src/locales/en/translation/admin-console/organization-role-details.ts index e17220c183a..bace0551ebb 100644 --- a/packages/phrases/src/locales/en/translation/admin-console/organization-role-details.ts +++ b/packages/phrases/src/locales/en/translation/admin-console/organization-role-details.ts @@ -4,7 +4,7 @@ const organization_role_details = { org_role: 'Organization role', delete_confirm: 'Doing so will remove the permissions associated with this role from the affected users and delete the relations among organization roles, members in the organization, and organization permissions.', - deleted: 'Org role {{name}} was successfully deleted.', + deleted: 'Organization role {{name}} was successfully deleted.', permissions: { tab: 'Permissions', name_column: 'Permission', @@ -12,7 +12,7 @@ const organization_role_details = { type_column: 'Permission type', type: { api: 'API permission', - org: 'Org permission', + org: 'Organization permission', }, assign_permissions: 'Assign permissions', remove_permission: 'Remove permission', @@ -30,7 +30,7 @@ const organization_role_details = { tab: 'General', settings: 'Settings', description: - 'Organization role is a grouping of permissions that can be assigned to users. The permissions must come from the predefined organization permissions.', + 'Organization role is a grouping of permissions that can be assigned to users. The permissions can come from the predefined organization permissions and API permission.', name_field: 'Name', description_field: 'Description', description_field_placeholder: 'Users with view-only permissions', diff --git a/packages/phrases/src/locales/en/translation/admin-console/organizations.ts b/packages/phrases/src/locales/en/translation/admin-console/organizations.ts index 8de651f20c8..7baa1f115e8 100644 --- a/packages/phrases/src/locales/en/translation/admin-console/organizations.ts +++ b/packages/phrases/src/locales/en/translation/admin-console/organizations.ts @@ -52,8 +52,10 @@ const organizations = { 'In multi-tenant SaaS applications, multiple organizations often share the same access control template, which includes permissions and roles. In Logto, we call it "organization template."', permission_description: 'Organization permission refers to the authorization to access a resource in the context of organization.', - role_description: + role_description_deprecated: 'Organization role is a grouping of organization permissions that can be assigned to members.', + role_description: + 'Organization role is a grouping of organization permissions or API permissions that can be assigned to members.', }, section_3: { title: 'Can I assign API permissions to organization roles?', diff --git a/packages/phrases/src/locales/es/translation/admin-console/organization-role-details.ts b/packages/phrases/src/locales/es/translation/admin-console/organization-role-details.ts index c50df444cd6..8da044728ed 100644 --- a/packages/phrases/src/locales/es/translation/admin-console/organization-role-details.ts +++ b/packages/phrases/src/locales/es/translation/admin-console/organization-role-details.ts @@ -4,7 +4,7 @@ const organization_role_details = { org_role: 'Rol de la organización', delete_confirm: 'Al hacerlo, se eliminarán los permisos asociados con este rol de los usuarios afectados y se borrarán las relaciones entre roles de organización, miembros en la organización y permisos de organización.', - deleted: 'El rol de la organización {{name}} se eliminó correctamente.', + deleted: 'El rol de organización {{name}} se eliminó con éxito.', permissions: { tab: 'Permisos', name_column: 'Permiso', @@ -30,7 +30,7 @@ const organization_role_details = { tab: 'General', settings: 'Configuración', description: - 'El rol de la organización es un grupo de permisos que se pueden asignar a los usuarios. Los permisos deben provenir de los permisos de organización predefinidos.', + 'El rol de organización es un agrupamiento de permisos que se pueden asignar a los usuarios. Los permisos pueden provenir de los permisos de organización predefinidos y permisos de API.', name_field: 'Nombre', description_field: 'Descripción', description_field_placeholder: 'Usuarios con permisos de solo lectura', diff --git a/packages/phrases/src/locales/es/translation/admin-console/organizations.ts b/packages/phrases/src/locales/es/translation/admin-console/organizations.ts index 91c7709e9d3..6c65e5339cb 100644 --- a/packages/phrases/src/locales/es/translation/admin-console/organizations.ts +++ b/packages/phrases/src/locales/es/translation/admin-console/organizations.ts @@ -55,8 +55,10 @@ const organizations = { 'En aplicaciones SaaS multiinquilino, varias organizaciones a menudo comparten la misma plantilla de control de acceso, que incluye permisos y roles. En Logto, lo llamamos "plantilla de organización".', permission_description: 'El permiso de la organización se refiere a la autorización para acceder a un recurso en el contexto de la organización.', - role_description: + role_description_deprecated: 'El rol de la organización es un agrupamiento de permisos de organización que se pueden asignar a los miembros.', + role_description: + 'El rol de la organización es un agrupamiento de permisos de la organización o permisos de API que se pueden asignar a los miembros.', }, section_3: { title: '¿Puedo asignar permisos de API a roles de organización?', diff --git a/packages/phrases/src/locales/fr/translation/admin-console/organization-role-details.ts b/packages/phrases/src/locales/fr/translation/admin-console/organization-role-details.ts index 47ca23d976f..36c932c9fa1 100644 --- a/packages/phrases/src/locales/fr/translation/admin-console/organization-role-details.ts +++ b/packages/phrases/src/locales/fr/translation/admin-console/organization-role-details.ts @@ -4,7 +4,7 @@ const organization_role_details = { org_role: "Rôle de l'organisation", delete_confirm: "Cela supprimera les autorisations associées à ce rôle des utilisateurs concernés et supprimera les relations entre les rôles de l'organisation, les membres de l'organisation et les autorisations de l'organisation.", - deleted: "Le rôle d'organisation {{name}} a été supprimé avec succès.", + deleted: "Le rôle de l'organisation {{name}} a été supprimé avec succès.", permissions: { tab: 'Autorisations', name_column: 'Autorisation', @@ -30,7 +30,7 @@ const organization_role_details = { tab: 'Général', settings: 'Réglages', description: - "Le rôle d'organisation est un regroupement de permissions qui peuvent être attribuées aux utilisateurs. Les permissions doivent provenir des permissions d'organisation prédéfinies.", + 'Le rôle d’organisation est un regroupement de permissions qui peuvent être attribuées aux utilisateurs. Les permissions peuvent provenir des permissions d’organisation prédéfinies et des permissions API.', name_field: 'Nom', description_field: 'Description', description_field_placeholder: 'Utenti con permessi di sola visualizzazione', diff --git a/packages/phrases/src/locales/fr/translation/admin-console/organizations.ts b/packages/phrases/src/locales/fr/translation/admin-console/organizations.ts index 543fc764685..88464d9d852 100644 --- a/packages/phrases/src/locales/fr/translation/admin-console/organizations.ts +++ b/packages/phrases/src/locales/fr/translation/admin-console/organizations.ts @@ -55,8 +55,10 @@ const organizations = { "Dans les applications multi-locataires SaaS, plusieurs organisations partagent souvent le même modèle de contrôle d'accès, comprenant des autorisations et des rôles. Chez Logto, nous l'appelons \"modèle d'organisation\".", permission_description: "L'autorisation d'organisation se réfère à l'autorisation d'accéder à une ressource dans le contexte de l'organisation.", - role_description: + role_description_deprecated: "Le rôle d'organisation est un regroupement de permissions d'organisation pouvant être attribuées aux membres.", + role_description: + "Le rôle de l'organisation est un regroupement de permissions d'organisation ou de permissions API qui peuvent être attribuées aux membres.", }, section_3: { title: "Puis-je attribuer des permissions API aux rôles de l'organisation?", diff --git a/packages/phrases/src/locales/it/translation/admin-console/organization-role-details.ts b/packages/phrases/src/locales/it/translation/admin-console/organization-role-details.ts index f4cc9bb9022..5a20b180cf6 100644 --- a/packages/phrases/src/locales/it/translation/admin-console/organization-role-details.ts +++ b/packages/phrases/src/locales/it/translation/admin-console/organization-role-details.ts @@ -4,7 +4,7 @@ const organization_role_details = { org_role: "Ruolo dell'organizzazione", delete_confirm: "Facendo ciò, verranno rimossi i permessi associati a questo ruolo dagli utenti interessati e verranno eliminati i rapporti tra ruoli organizzativi, membri nell'organizzazione e permessi dell'organizzazione.", - deleted: "Il ruolo dell'organizzazione {{name}} è stato eliminato con successo.", + deleted: "Il ruolo dell'organizzazione {{name}} è stato cancellato con successo.", permissions: { tab: 'Autorizzazioni', name_column: 'Autorizzazione', @@ -30,7 +30,7 @@ const organization_role_details = { tab: 'Generale', settings: 'Impostazioni', description: - "Il ruolo dell'organizzazione è un raggruppamento di autorizzazioni che possono essere assegnate agli utenti. Le autorizzazioni devono provenire dalle autorizzazioni predefinite dell'organizzazione.", + 'Il ruolo dell’organizzazione è un raggruppamento di permessi che possono essere assegnati agli utenti. I permessi possono derivare dai permessi dell’organizzazione predefiniti e dai permessi API.', name_field: 'Nome', description_field: 'Descrizione', description_field_placeholder: 'Utenti con permessi di sola visualizzazione', diff --git a/packages/phrases/src/locales/it/translation/admin-console/organizations.ts b/packages/phrases/src/locales/it/translation/admin-console/organizations.ts index f3a6a1d4294..3e7656ff33d 100644 --- a/packages/phrases/src/locales/it/translation/admin-console/organizations.ts +++ b/packages/phrases/src/locales/it/translation/admin-console/organizations.ts @@ -55,8 +55,10 @@ const organizations = { 'Nelle applicazioni SaaS multi-inquilino, spesso più organizzazioni condividono lo stesso modello di controllo degli accessi, che include permessi e ruoli. In Logto, lo chiamiamo "modello organizzativo".', permission_description: "Il permesso organizzativo si riferisce all'autorizzazione per accedere a una risorsa nel contesto dell'organizzazione.", - role_description: + role_description_deprecated: 'Il ruolo organizzativo è un raggruppamento di permessi organizzativi che possono essere assegnati ai membri.', + role_description: + "Il ruolo dell'organizzazione è un raggruppamento di permessi dell'organizzazione o permessi API che possono essere assegnati ai membri.", }, section_3: { title: "Posso assegnare permessi API ai ruoli dell'organizzazione?", diff --git a/packages/phrases/src/locales/ja/translation/admin-console/organization-role-details.ts b/packages/phrases/src/locales/ja/translation/admin-console/organization-role-details.ts index f9f90e2ac94..4a2c15f1ae4 100644 --- a/packages/phrases/src/locales/ja/translation/admin-console/organization-role-details.ts +++ b/packages/phrases/src/locales/ja/translation/admin-console/organization-role-details.ts @@ -4,7 +4,7 @@ const organization_role_details = { org_role: '組織の役割', delete_confirm: 'これにより、関連するユーザーからこのロールに関連付けられた権限が削除され、組織の役割、組織のメンバー、および組織の権限間の関係が削除されます。', - deleted: '組織の役割 {{name}} は正常に削除されました。', + deleted: '組織の役割{{name}}が正常に削除されました。', permissions: { tab: '許可', name_column: '許可', @@ -30,7 +30,7 @@ const organization_role_details = { tab: '一般', settings: '設定', description: - '組織の役割は、ユーザーに割り当てることができる許可のグループです。 許可は、事前定義された組織の許可から取得する必要があります。', + '組織ロールは、ユーザーに割り当てることができる権限のグループです。権限は、事前に定義された組織の権限とAPIの権限から来ることがあります。', name_field: '名前', description_field: '説明', description_field_placeholder: '閲覧専用権限を持つユーザー', diff --git a/packages/phrases/src/locales/ja/translation/admin-console/organizations.ts b/packages/phrases/src/locales/ja/translation/admin-console/organizations.ts index fb071c2d87b..038473d2cc3 100644 --- a/packages/phrases/src/locales/ja/translation/admin-console/organizations.ts +++ b/packages/phrases/src/locales/ja/translation/admin-console/organizations.ts @@ -54,8 +54,10 @@ const organizations = { 'マルチテナントSaaSアプリケーションでは、複数の組織がしばしば同じアクセス制御テンプレートを共有します。これには権限や役割が含まれます。Logtoではこれを「組織テンプレート」と呼びます。', permission_description: '組織権限とは、組織のコンテキストでリソースにアクセスするための承認です。', - role_description: + role_description_deprecated: '組織役割は、ユーザーに割り当てることができる権限のグループ化です。権限は事前に定義された組織権限から取得する必要があります。', + role_description: + '組織の役割は、メンバーに割り当てることができる組織の権限またはAPIの権限のグループです。', }, section_3: { title: '組織の役割にAPI権限を割り当てることはできますか?', diff --git a/packages/phrases/src/locales/ko/translation/admin-console/organization-role-details.ts b/packages/phrases/src/locales/ko/translation/admin-console/organization-role-details.ts index c36c83ac360..c7e93a2b785 100644 --- a/packages/phrases/src/locales/ko/translation/admin-console/organization-role-details.ts +++ b/packages/phrases/src/locales/ko/translation/admin-console/organization-role-details.ts @@ -30,7 +30,7 @@ const organization_role_details = { tab: '일반', settings: '설정', description: - '조직 역할은 사용자에게 할당할 수있는 권한의 그룹입니다. 권한은 사전 정의 된 조직 권한에서 가져와야합니다.', + '조직 역할은 사용자에게 할당할 수 있는 권한의 그룹입니다. 권한은 사전에 정의된 조직 권한과 API 권한에서 올 수 있습니다.', name_field: '이름', description_field: '설명', description_field_placeholder: '읽기 전용 권한을 가진 사용자', diff --git a/packages/phrases/src/locales/ko/translation/admin-console/organizations.ts b/packages/phrases/src/locales/ko/translation/admin-console/organizations.ts index b49811789fb..f5ebf9a2030 100644 --- a/packages/phrases/src/locales/ko/translation/admin-console/organizations.ts +++ b/packages/phrases/src/locales/ko/translation/admin-console/organizations.ts @@ -53,7 +53,10 @@ const organizations = { description: '멀티 테넌트 SaaS 애플리케이션에서는 여러 조직이 종종 권한 및 역할을 포함한 동일한 액세스 제어 템플릿을 공유합니다. 로그토에서는 이를 "조직 템플릿"이라고 합니다.', permission_description: '조직 권한은 조직의 컨텍스트에서 리소스에 대한 권한을 나타냅니다.', - role_description: '조직 역할은 구성원에게 할당할 수 있는 조직 권한의 그룹화입니다.', + role_description_deprecated: + '조직 역할은 구성원에게 할당할 수 있는 조직 권한의 그룹화입니다.', + role_description: + '조직 역할은 구성원에게 할당할 수 있는 조직 권한 또는 API 권한의 그룹입니다.', }, section_3: { title: '조직 역할에 API 권한을 할당할 수 있나요?', diff --git a/packages/phrases/src/locales/pl-pl/translation/admin-console/organization-role-details.ts b/packages/phrases/src/locales/pl-pl/translation/admin-console/organization-role-details.ts index 4fb8bc4311d..d9b71f053b7 100644 --- a/packages/phrases/src/locales/pl-pl/translation/admin-console/organization-role-details.ts +++ b/packages/phrases/src/locales/pl-pl/translation/admin-console/organization-role-details.ts @@ -12,7 +12,7 @@ const organization_role_details = { type_column: 'Typ uprawnienia', type: { api: 'Uprawnienie API', - org: 'Uprawnienie organizacji', + org: 'Uprawnienia organizacyjne', }, assign_permissions: 'Przypisz uprawnienia', remove_permission: 'Usuń uprawnienie', @@ -30,7 +30,7 @@ const organization_role_details = { tab: 'Ogólne', settings: 'Ustawienia', description: - 'Rola organizacji to grupowanie uprawnień, które można przypisać użytkownikom. Uprawnienia muszą pochodzić z predefiniowanych uprawnień organizacji.', + 'Rola organizacyjna to grupowanie uprawnień, które mogą być przypisane użytkownikom. Uprawnienia mogą pochodzić z predefiniowanych uprawnień organizacyjnych i uprawnień API.', name_field: 'Nazwa', description_field: 'Opis', description_field_placeholder: 'Użytkownicy z uprawnieniami tylko do odczytu', diff --git a/packages/phrases/src/locales/pl-pl/translation/admin-console/organizations.ts b/packages/phrases/src/locales/pl-pl/translation/admin-console/organizations.ts index 09c32e0e4ac..5062ed2f316 100644 --- a/packages/phrases/src/locales/pl-pl/translation/admin-console/organizations.ts +++ b/packages/phrases/src/locales/pl-pl/translation/admin-console/organizations.ts @@ -55,8 +55,10 @@ const organizations = { 'W wielomandantowych aplikacjach typu SaaS, wiele organizacji często dzieli ten sam szablon kontroli dostępu, który obejmuje uprawnienia i role. W Logto nazywamy to "szablonem organizacji".', permission_description: 'Uprawnienie organizacji odnosi się do autoryzacji dostępu do zasobu w kontekście organizacji.', - role_description: + role_description_deprecated: 'Rola organizacji to grupowanie uprawnień organizacji, które można przypisać członkom.', + role_description: + 'Rola organizacyjna to grupowanie uprawnień organizacyjnych lub uprawnień API, które mogą być przypisane do członków.', }, section_3: { title: 'Czy mogę przypisać uprawnienia API do ról organizacyjnych?', diff --git a/packages/phrases/src/locales/pt-br/translation/admin-console/organization-role-details.ts b/packages/phrases/src/locales/pt-br/translation/admin-console/organization-role-details.ts index 27a6670b972..9b7a502d410 100644 --- a/packages/phrases/src/locales/pt-br/translation/admin-console/organization-role-details.ts +++ b/packages/phrases/src/locales/pt-br/translation/admin-console/organization-role-details.ts @@ -12,7 +12,7 @@ const organization_role_details = { type_column: 'Tipo de permissão', type: { api: 'Permissão da API', - org: 'Permissão da org', + org: 'Permissão da organização', }, assign_permissions: 'Atribuir permissões', remove_permission: 'Remover permissão', @@ -30,7 +30,7 @@ const organization_role_details = { tab: 'Geral', settings: 'Configurações', description: - 'A função da organização é um agrupamento de permissões que podem ser atribuídas aos usuários. As permissões devem vir das permissões predefinidas da organização.', + 'Função de organização é um agrupamento de permissões que podem ser atribuídas aos usuários. As permissões podem vir das permissões de organização pré-definidas e permissões de API.', name_field: 'Nome', description_field: 'Descrição', description_field_placeholder: 'Usuários com permissões somente de visualização', diff --git a/packages/phrases/src/locales/pt-br/translation/admin-console/organizations.ts b/packages/phrases/src/locales/pt-br/translation/admin-console/organizations.ts index 5a3ade33363..248f7b314d8 100644 --- a/packages/phrases/src/locales/pt-br/translation/admin-console/organizations.ts +++ b/packages/phrases/src/locales/pt-br/translation/admin-console/organizations.ts @@ -55,8 +55,10 @@ const organizations = { 'Em aplicativos SaaS multi-inquilino, várias organizações frequentemente compartilham o mesmo modelo de controle de acesso, que inclui permissões e papéis. No Logto, chamamos isso de "modelo de organização".', permission_description: 'A permissão da organização refere-se à autorização para acessar um recurso no contexto da organização.', - role_description: + role_description_deprecated: 'O papel da organização é um agrupamento de permissões da organização que podem ser atribuídas aos membros.', + role_description: + 'A função da organização é um agrupamento de permissões da organização ou permissões de API que podem ser atribuídas aos membros.', }, section_3: { title: 'Posso atribuir permissões de API a funções de organização?', diff --git a/packages/phrases/src/locales/pt-pt/translation/admin-console/organization-role-details.ts b/packages/phrases/src/locales/pt-pt/translation/admin-console/organization-role-details.ts index 9eed555407b..488bc5c0e8e 100644 --- a/packages/phrases/src/locales/pt-pt/translation/admin-console/organization-role-details.ts +++ b/packages/phrases/src/locales/pt-pt/translation/admin-console/organization-role-details.ts @@ -4,7 +4,7 @@ const organization_role_details = { org_role: 'Função da organização', delete_confirm: 'Ao fazê-lo, serão removidas as permissões associadas a esta função dos utilizadores afetados e serão eliminadas as relações entre funções da organização, membros na organização e permissões da organização.', - deleted: 'O papel da organização {{name}} foi removido com sucesso.', + deleted: 'O papel da organização {{name}} foi eliminado com sucesso.', permissions: { tab: 'Permissões', name_column: 'Permissão', @@ -12,7 +12,7 @@ const organization_role_details = { type_column: 'Tipo de permissão', type: { api: 'Permissão da API', - org: 'Permissão da org', + org: 'Permissão da organização', }, assign_permissions: 'Atribuir permissões', remove_permission: 'Remover permissão', @@ -30,7 +30,7 @@ const organization_role_details = { tab: 'Geral', settings: 'Configurações', description: - 'A função da organização é um agrupamento de permissões que podem ser atribuídas aos usuários. As permissões devem vir das permissões predefinidas da organização.', + 'O papel da organização é um agrupamento de permissões que podem ser atribuídas aos utilizadores. As permissões podem provir das permissões da organização pré-definidas e permissões de API.', name_field: 'Nome', description_field: 'Descrição', description_field_placeholder: 'Utilizadores com permissões apenas de visualização', diff --git a/packages/phrases/src/locales/pt-pt/translation/admin-console/organizations.ts b/packages/phrases/src/locales/pt-pt/translation/admin-console/organizations.ts index 200ae347e2a..18d1ab6b009 100644 --- a/packages/phrases/src/locales/pt-pt/translation/admin-console/organizations.ts +++ b/packages/phrases/src/locales/pt-pt/translation/admin-console/organizations.ts @@ -55,8 +55,10 @@ const organizations = { 'Nas aplicações SaaS multi-inquilinos, muitas organizações frequentemente partilham o mesmo modelo de controlo de acesso, que inclui permissões e funções. Na Logto, chamamos-lhe "modelo de organização."', permission_description: 'A permissão da organização refere-se à autorização para aceder a um recurso no contexto da organização.', - role_description: + role_description_deprecated: 'O papel da organização é um agrupamento de permissões da organização que podem ser atribuídas aos membros.', + role_description: + 'O papel da organização é um agrupamento de permissões da organização ou permissões de API que podem ser atribuídas aos membros.', }, section_3: { title: 'Posso atribuir permissões de API a papéis de organização?', diff --git a/packages/phrases/src/locales/ru/translation/admin-console/organization-role-details.ts b/packages/phrases/src/locales/ru/translation/admin-console/organization-role-details.ts index a8bb053fc91..b22af529d10 100644 --- a/packages/phrases/src/locales/ru/translation/admin-console/organization-role-details.ts +++ b/packages/phrases/src/locales/ru/translation/admin-console/organization-role-details.ts @@ -4,7 +4,7 @@ const organization_role_details = { org_role: 'Роль организации', delete_confirm: 'При этом будут удалены разрешения, связанные с этой ролью, у затронутых пользователей, и будут удалены связи между ролями организации, членами организации и правами организации.', - deleted: 'Роль организации {{name}} успешно удалена.', + deleted: 'Роль в организации {{name}} была успешно удалена.', permissions: { tab: 'Разрешения', name_column: 'Разрешение', @@ -30,7 +30,7 @@ const organization_role_details = { tab: 'Общее', settings: 'Настройки', description: - 'Роль организации - это группировка разрешений, которые можно назначить пользователям. Разрешения должны быть взяты из предопределенных разрешений организации.', + 'Роль организации - это группировка разрешений, которые можно назначить пользователям. Разрешения могут исходить из предопределенных разрешений организации и разрешений API.', name_field: 'Имя', description_field: 'Описание', description_field_placeholder: 'Пользователи с правами только на просмотр', diff --git a/packages/phrases/src/locales/ru/translation/admin-console/organizations.ts b/packages/phrases/src/locales/ru/translation/admin-console/organizations.ts index 6a31c203e21..427440160b7 100644 --- a/packages/phrases/src/locales/ru/translation/admin-console/organizations.ts +++ b/packages/phrases/src/locales/ru/translation/admin-console/organizations.ts @@ -54,8 +54,10 @@ const organizations = { 'В мультиарендных SaaS-приложениях несколько организаций часто разделяют один и тот же шаблон контроля доступа, включая разрешения и роли. В Logto мы называем это "шаблон организации".', permission_description: 'Разрешение организации относится к авторизации доступа к ресурсу в контексте организации.', - role_description: + role_description_deprecated: 'Роль организации - это группировка разрешений организации, которые могут быть назначены участникам.', + role_description: + 'Роль организации представляет собой группировку организационных разрешений или разрешений API, которые могут быть назначены членам.', }, section_3: { title: 'Могу ли я назначить разрешения API организационным ролям?', diff --git a/packages/phrases/src/locales/tr-tr/translation/admin-console/organization-role-details.ts b/packages/phrases/src/locales/tr-tr/translation/admin-console/organization-role-details.ts index bd4a24c0219..12c26925f3f 100644 --- a/packages/phrases/src/locales/tr-tr/translation/admin-console/organization-role-details.ts +++ b/packages/phrases/src/locales/tr-tr/translation/admin-console/organization-role-details.ts @@ -12,7 +12,7 @@ const organization_role_details = { type_column: 'İzin türü', type: { api: 'API izni', - org: 'Kuruluş izni', + org: 'Organizasyon izni', }, assign_permissions: 'İzinleri atama', remove_permission: 'İzni kaldır', @@ -30,7 +30,7 @@ const organization_role_details = { tab: 'Genel', settings: 'Ayarlar', description: - 'Kuruluş rolü, kullanıcılara atanabilecek izinlerin bir gruplamasıdır. İzinler, önceden tanımlanmış kuruluş izinlerinden gelmelidir.', + 'Organizasyon rolü, kullanıcılara atanabilecek izinlerin bir gruplandırılmasıdır. İzinler, önceden tanımlanmış organizasyon izinlerinden ve API izinlerinden gelebilir.', name_field: 'Adı', description_field: 'Açıklama', description_field_placeholder: 'Yalnızca görüntüleme izinlerine sahip kullanıcılar', diff --git a/packages/phrases/src/locales/tr-tr/translation/admin-console/organizations.ts b/packages/phrases/src/locales/tr-tr/translation/admin-console/organizations.ts index b0330c3c986..e58ccb25eb8 100644 --- a/packages/phrases/src/locales/tr-tr/translation/admin-console/organizations.ts +++ b/packages/phrases/src/locales/tr-tr/translation/admin-console/organizations.ts @@ -54,8 +54,10 @@ const organizations = { 'Çok kiracılı SaaS uygulamalarında, birden çok kuruluş genellikle aynı erişim kontrol şablonunu paylaşır; bu şablon izinleri ve rolleri içerir. Logto\'da buna "kuruluş şablonu" diyoruz.', permission_description: 'Kuruluş izni, kuruluş bağlamında bir kaynağa erişim izni anlamına gelir.', - role_description: + role_description_deprecated: 'Kuruluş rolü, kullanıcılara atanabilen kuruluş izinlerinin bir gruplamasıdır.', + role_description: + 'Kuruluş rolü, üyelere atanabilecek kuruluş izinlerinin veya API izinlerinin bir gruplamasıdır.', }, section_3: { title: 'API izinlerini organizasyon rollerine atayabilir miyim?', diff --git a/packages/phrases/src/locales/zh-cn/translation/admin-console/organization-role-details.ts b/packages/phrases/src/locales/zh-cn/translation/admin-console/organization-role-details.ts index 1ec1e480eb4..d657f860d13 100644 --- a/packages/phrases/src/locales/zh-cn/translation/admin-console/organization-role-details.ts +++ b/packages/phrases/src/locales/zh-cn/translation/admin-console/organization-role-details.ts @@ -27,7 +27,7 @@ const organization_role_details = { general: { tab: '常规', settings: '设置', - description: '组织角色是可以分配给用户的权限组。这些权限必须来自预定义的组织权限。', + description: '组织角色是可以分配给用户的权限的分组。权限可以来自预定义的组织权限和API权限。', name_field: '名称', description_field: '描述', description_field_placeholder: '仅具有查看权限的用户', diff --git a/packages/phrases/src/locales/zh-cn/translation/admin-console/organizations.ts b/packages/phrases/src/locales/zh-cn/translation/admin-console/organizations.ts index eabb06da5fd..a649577450a 100644 --- a/packages/phrases/src/locales/zh-cn/translation/admin-console/organizations.ts +++ b/packages/phrases/src/locales/zh-cn/translation/admin-console/organizations.ts @@ -53,7 +53,8 @@ const organizations = { description: '在多租户SaaS应用程序中,多个组织通常共享相同的访问控制模板,其中包括权限和角色。在Logto中,我们称之为“组织模板”。', permission_description: '组织权限是指在组织上下文中访问资源的授权。', - role_description: '组织角色是可以分配给成员的组织权限组。', + role_description_deprecated: '组织角色是可以分配给成员的组织权限组。', + role_description: '组织角色是可以分配给成员的组织权限或API权限的分组。', }, section_3: { title: '我可以将API权限分配给组织角色吗?', diff --git a/packages/phrases/src/locales/zh-hk/translation/admin-console/organization-role-details.ts b/packages/phrases/src/locales/zh-hk/translation/admin-console/organization-role-details.ts index 02c9a82fed1..b11cc005adc 100644 --- a/packages/phrases/src/locales/zh-hk/translation/admin-console/organization-role-details.ts +++ b/packages/phrases/src/locales/zh-hk/translation/admin-console/organization-role-details.ts @@ -27,7 +27,7 @@ const organization_role_details = { general: { tab: '一般', settings: '設置', - description: '組織角色是可以分配給用戶的權限組。這些權限必須來自預定義的組織權限。', + description: '組織角色是可以分配給用戶的權限分組。權限可以來自預定義的組織權限和API權限。', name_field: '名稱', description_field: '描述', description_field_placeholder: '僅擁有檢視權限的使用者', diff --git a/packages/phrases/src/locales/zh-hk/translation/admin-console/organizations.ts b/packages/phrases/src/locales/zh-hk/translation/admin-console/organizations.ts index 2fef41a2e6f..8fd5e891fc0 100644 --- a/packages/phrases/src/locales/zh-hk/translation/admin-console/organizations.ts +++ b/packages/phrases/src/locales/zh-hk/translation/admin-console/organizations.ts @@ -53,7 +53,8 @@ const organizations = { description: '在多租戶 SaaS 應用程式中,多個組織通常共用相同的訪問控制模板,其中包括權限和角色。在 Logto 中,我們稱之為「組織模板」。', permission_description: '組織權限指授權在組織上下文中存取資源。', - role_description: '組織角色是可以分配給成員的組織權限的分組。', + role_description_deprecated: '組織角色是可以分配給成員的組織權限的分組。', + role_description: '組繇角色是可以分配給成員的組繇權限或API權限的分組。', }, section_3: { title: '我可以將API權限分配給組織角色嗎?', diff --git a/packages/phrases/src/locales/zh-tw/translation/admin-console/organization-role-details.ts b/packages/phrases/src/locales/zh-tw/translation/admin-console/organization-role-details.ts index 7951509fa4e..bdce17089eb 100644 --- a/packages/phrases/src/locales/zh-tw/translation/admin-console/organization-role-details.ts +++ b/packages/phrases/src/locales/zh-tw/translation/admin-console/organization-role-details.ts @@ -27,7 +27,7 @@ const organization_role_details = { general: { tab: '一般', settings: '設置', - description: '組織角色是可以分配給用戶的權限組。這些權限必須來自預定義的組織權限。', + description: '組織角色是可以分配給用戶的權限分組。權限可以來自預設的組織權限和API權限。', name_field: '名稱', description_field: '描述', description_field_placeholder: '僅具有查看權限的使用者', diff --git a/packages/phrases/src/locales/zh-tw/translation/admin-console/organizations.ts b/packages/phrases/src/locales/zh-tw/translation/admin-console/organizations.ts index 12321db5898..f8ad4cbc5e7 100644 --- a/packages/phrases/src/locales/zh-tw/translation/admin-console/organizations.ts +++ b/packages/phrases/src/locales/zh-tw/translation/admin-console/organizations.ts @@ -53,7 +53,8 @@ const organizations = { description: '在多租戶 SaaS 應用程式中,多個組織通常共用相同的存取控制模板,其中包括權限和角色。 在 Logto 中,我們稱之為「組繹模板」。', permission_description: '組繹權限是指在組繹上下文中訪問資源的授權。', - role_description: '組繹角色是一組組繹權限,可以分配給成員。', + role_description_deprecated: '組繹角色是一組組繹權限,可以分配給成員。', + role_description: '組織角色是可以分配給成員的組織權限或API權限的分組。', }, section_3: { title: '我可以將API權限指派給組織角色嗎?', From 2de2939e30b697d2033b9dd51acefe0127943063 Mon Sep 17 00:00:00 2001 From: Charles Zhao Date: Wed, 17 Apr 2024 17:55:40 +0800 Subject: [PATCH 284/687] fix(console): cloud collaboration minor bug fixes (#5734) * fix(console): oss version should not check user tenant scopes * fix(console): collaborators should leave immediately if they are removed from tenant --- .../console/src/containers/ConsoleContent/hooks.ts | 14 ++++++++++++-- .../console/src/hooks/use-current-tenant-scopes.ts | 5 +++-- 2 files changed, 15 insertions(+), 4 deletions(-) diff --git a/packages/console/src/containers/ConsoleContent/hooks.ts b/packages/console/src/containers/ConsoleContent/hooks.ts index 69a3543a0f0..d08b9913629 100644 --- a/packages/console/src/containers/ConsoleContent/hooks.ts +++ b/packages/console/src/containers/ConsoleContent/hooks.ts @@ -2,6 +2,7 @@ import { Prompt, useLogto } from '@logto/react'; import { getTenantOrganizationId } from '@logto/schemas'; import { useContext, useEffect, useState } from 'react'; +import { isCloud } from '@/consts/env'; import { TenantsContext } from '@/contexts/TenantsProvider'; import useCurrentTenantScopes from '@/hooks/use-current-tenant-scopes'; import useRedirectUri from '@/hooks/use-redirect-uri'; @@ -17,7 +18,7 @@ import { saveRedirect } from '@/utils/storage'; * Note: This hook should only be used once in the ConsoleContent component. */ const useTenantScopeListener = () => { - const { currentTenantId } = useContext(TenantsContext); + const { currentTenantId, removeTenant, navigateTenant } = useContext(TenantsContext); const { clearAccessToken, clearAllTokens, getOrganizationTokenClaims, signIn } = useLogto(); const [tokenClaims, setTokenClaims] = useState(); const redirectUri = useRedirectUri(); @@ -32,7 +33,16 @@ const useTenantScopeListener = () => { }, [currentTenantId, getOrganizationTokenClaims]); useEffect(() => { - if (isLoading || tokenClaims === undefined) { + if (isCloud && !isLoading && scopes.length === 0) { + // User has no access to the current tenant. Navigate to root and it will return to the + // last visited tenant, or fallback to the page where the user can create a new tenant. + removeTenant(currentTenantId); + navigateTenant(''); + } + }, [currentTenantId, isLoading, navigateTenant, removeTenant, scopes.length]); + + useEffect(() => { + if (!isCloud || isLoading || tokenClaims === undefined) { return; } const hasScopesGranted = scopes.some((scope) => !tokenClaims.includes(scope)); diff --git a/packages/console/src/hooks/use-current-tenant-scopes.ts b/packages/console/src/hooks/use-current-tenant-scopes.ts index 56e98a57930..21d6fea550a 100644 --- a/packages/console/src/hooks/use-current-tenant-scopes.ts +++ b/packages/console/src/hooks/use-current-tenant-scopes.ts @@ -3,13 +3,14 @@ import { useContext, useMemo } from 'react'; import useSWR from 'swr'; import { useAuthedCloudApi } from '@/cloud/hooks/use-cloud-api'; +import { isCloud } from '@/consts/env'; import { TenantsContext } from '@/contexts/TenantsProvider'; import { type RequestError } from './use-api'; import useCurrentUser from './use-current-user'; const useCurrentTenantScopes = () => { - const { currentTenantId, isInitComplete } = useContext(TenantsContext); + const { currentTenantId } = useContext(TenantsContext); const cloudApi = useAuthedCloudApi(); const { user } = useCurrentUser(); const userId = user?.id ?? ''; @@ -19,7 +20,7 @@ const useCurrentTenantScopes = () => { isLoading, mutate, } = useSWR( - userId && isInitComplete && `api/tenants/${currentTenantId}/members/${userId}/scopes`, + isCloud && userId && `api/tenants/${currentTenantId}/members/${userId}/scopes`, async () => { const scopes = await cloudApi.get('/api/tenants/:tenantId/members/:userId/scopes', { params: { tenantId: currentTenantId, userId }, From 52df3ebbbba5b922e753709358da7d4ac1802b52 Mon Sep 17 00:00:00 2001 From: Charles Zhao Date: Wed, 17 Apr 2024 17:55:54 +0800 Subject: [PATCH 285/687] fix(core,console): invitee emails should be case insensitive (#5730) * fix(core,console): invitee email checks should be case insensitive * test: add integration test * chore: add changeset --- .changeset/afraid-stingrays-perform.md | 5 +++++ .../TenantMembers/InviteEmailsInput/hooks.ts | 7 ++++--- packages/core/src/queries/organization/index.ts | 4 ++-- .../api/organization/organization-invitation.get.test.ts | 7 ++++--- 4 files changed, 15 insertions(+), 8 deletions(-) create mode 100644 .changeset/afraid-stingrays-perform.md diff --git a/.changeset/afraid-stingrays-perform.md b/.changeset/afraid-stingrays-perform.md new file mode 100644 index 00000000000..2bfa7f2708e --- /dev/null +++ b/.changeset/afraid-stingrays-perform.md @@ -0,0 +1,5 @@ +--- +"@logto/core": patch +--- + +Bug fix: organization invitation APIs should handle invitee emails case insensitively diff --git a/packages/console/src/pages/TenantSettings/TenantMembers/InviteEmailsInput/hooks.ts b/packages/console/src/pages/TenantSettings/TenantMembers/InviteEmailsInput/hooks.ts index f57aca982fc..e10338ab3f4 100644 --- a/packages/console/src/pages/TenantSettings/TenantMembers/InviteEmailsInput/hooks.ts +++ b/packages/console/src/pages/TenantSettings/TenantMembers/InviteEmailsInput/hooks.ts @@ -44,15 +44,16 @@ const useEmailInputUtils = () => { const validEmails = new Set(); const existingMemberEmails = new Set( - existingMembers.map(({ primaryEmail }) => primaryEmail ?? '').filter(Boolean) + existingMembers.map(({ primaryEmail }) => primaryEmail?.toLowerCase() ?? '').filter(Boolean) ); const existingInvitationEmails = new Set( existingInvitations .filter(({ status }) => status === OrganizationInvitationStatus.Pending) - .map(({ invitee }) => invitee) + .map(({ invitee }) => invitee.toLowerCase()) ); - for (const email of emails) { + for (const userInputEmail of emails) { + const email = userInputEmail.toLowerCase(); if (!emailRegEx.test(email)) { invalidEmails.add(email); } diff --git a/packages/core/src/queries/organization/index.ts b/packages/core/src/queries/organization/index.ts index 266728d4b79..573c824112e 100644 --- a/packages/core/src/queries/organization/index.ts +++ b/packages/core/src/queries/organization/index.ts @@ -165,7 +165,7 @@ class OrganizationInvitationsQueries extends SchemaQueries< return sql`and ${fields.organizationId} = ${id}`; })} ${conditionalSql(invitee, (email) => { - return sql`and ${fields.invitee} = ${email}`; + return sql`and lower(${fields.invitee}) = lower(${email})`; })} `); } @@ -220,7 +220,7 @@ class OrganizationInvitationsQueries extends SchemaQueries< return sql`and ${fields.inviterId} = ${id}`; })} ${conditionalSql(invitee, (email) => { - return sql`and ${fields.invitee} = ${email}`; + return sql`and lower(${fields.invitee}) = lower(${email})`; })} group by ${fields.id} ${conditionalSql(this.orderBy, ({ field, order }) => { diff --git a/packages/integration-tests/src/tests/api/organization/organization-invitation.get.test.ts b/packages/integration-tests/src/tests/api/organization/organization-invitation.get.test.ts index e59e3c4c1a0..16b6bb30e90 100644 --- a/packages/integration-tests/src/tests/api/organization/organization-invitation.get.test.ts +++ b/packages/integration-tests/src/tests/api/organization/organization-invitation.get.test.ts @@ -61,18 +61,19 @@ describe('organization invitation creation', () => { await Promise.all([deleteUser(inviter.id), deleteUser(inviter2.id)]); }); - it('should be able to get invitations by invitee', async () => { + it('should be able to get invitations by invitee email (case insensitive)', async () => { const organization = await organizationApi.create({ name: 'test' }); const invitee = `${randomId()}@example.com`; await invitationApi.create({ organizationId: organization.id, - invitee, + // Deliberately use uppercase email when creating the invitation + invitee: invitee.toUpperCase(), expiresAt: Date.now() + 1_000_000, }); const invitations = await invitationApi.getList(new URLSearchParams({ invitee })); expect(invitations.length).toBe(1); - expect(invitations[0]?.invitee).toBe(invitee); + expect(invitations[0]?.invitee.toLocaleLowerCase()).toBe(invitee.toLowerCase()); }); it('should have no pagination', async () => { From 8a54136b3a99bbc9414ff5dda90339ae4621887a Mon Sep 17 00:00:00 2001 From: Gao Sun Date: Wed, 17 Apr 2024 21:38:30 +0800 Subject: [PATCH 286/687] refactor(console): remove AppInsights --- packages/console/jest.config.ts | 1 - packages/console/package.json | 1 - packages/console/src/App.tsx | 42 ++++++++----------- .../console/src/components/PageMeta/index.tsx | 17 +------- .../src/containers/ConsoleRoutes/index.tsx | 3 -- .../console/src/hooks/use-track-user-id.ts | 42 ------------------- packages/console/src/onboarding/index.tsx | 21 ++++------ .../pages/SignInExperience/index.tsx | 3 +- .../src/onboarding/pages/Welcome/index.tsx | 3 +- .../src/pages/ApiResourceDetails/index.tsx | 3 +- .../console/src/pages/ApiResources/index.tsx | 3 +- .../src/pages/ApplicationDetails/index.tsx | 3 +- .../console/src/pages/Applications/index.tsx | 3 +- .../src/pages/AuditLogDetails/index.tsx | 3 +- .../console/src/pages/AuditLogs/index.tsx | 4 +- .../src/pages/ConnectorDetails/index.tsx | 3 +- .../console/src/pages/Connectors/index.tsx | 3 +- .../console/src/pages/CustomizeJwt/index.tsx | 3 +- .../src/pages/CustomizeJwtDetails/index.tsx | 9 ++-- .../console/src/pages/Dashboard/index.tsx | 3 +- .../console/src/pages/EnterpriseSso/index.tsx | 5 +-- .../src/pages/EnterpriseSsoDetails/index.tsx | 5 +-- .../console/src/pages/GetStarted/index.tsx | 3 +- packages/console/src/pages/Mfa/index.tsx | 3 +- packages/console/src/pages/NotFound/index.tsx | 4 +- .../pages/OrganizationRoleDetails/index.tsx | 3 +- .../src/pages/OrganizationTemplate/index.tsx | 3 +- packages/console/src/pages/Profile/index.tsx | 3 +- .../console/src/pages/RoleDetails/index.tsx | 3 +- packages/console/src/pages/Roles/index.tsx | 3 +- .../src/pages/SignInExperience/index.tsx | 3 +- .../console/src/pages/SigningKeys/index.tsx | 3 +- .../TenantSettings/BillingHistory/index.tsx | 3 +- .../TenantSettings/Subscription/index.tsx | 3 +- .../TenantDomainSettings/index.tsx | 3 +- .../console/src/pages/UserDetails/index.tsx | 3 +- packages/console/src/pages/Users/index.tsx | 3 +- .../src/pages/WebhookDetails/index.tsx | 3 +- packages/console/src/pages/Webhooks/index.tsx | 3 +- pnpm-lock.yaml | 5 +-- 40 files changed, 65 insertions(+), 175 deletions(-) delete mode 100644 packages/console/src/hooks/use-track-user-id.ts diff --git a/packages/console/jest.config.ts b/packages/console/jest.config.ts index 2b732771d05..f1895b93985 100644 --- a/packages/console/jest.config.ts +++ b/packages/console/jest.config.ts @@ -23,7 +23,6 @@ const config: Config.InitialOptions = { }, moduleNameMapper: { '^@/(.*)$': '/src/$1', - '^@logto/app-insights/(.*)$': '/../app-insights/lib/$1', '^@logto/shared/(.*)$': '/../shared/lib/$1', '\\.module\\.(css|sass|scss)$': 'identity-obj-proxy', }, diff --git a/packages/console/package.json b/packages/console/package.json index 54b90176925..11756140279 100644 --- a/packages/console/package.json +++ b/packages/console/package.json @@ -27,7 +27,6 @@ "devDependencies": { "@fontsource/roboto-mono": "^5.0.0", "@jest/types": "^29.5.0", - "@logto/app-insights": "workspace:^1.4.0", "@logto/cloud": "0.2.5-821690c", "@logto/connector-kit": "workspace:^3.0.0", "@logto/core-kit": "workspace:^2.4.0", diff --git a/packages/console/src/App.tsx b/packages/console/src/App.tsx index 451560e44fb..e211dd52a37 100644 --- a/packages/console/src/App.tsx +++ b/packages/console/src/App.tsx @@ -1,4 +1,3 @@ -import { AppInsightsBoundary } from '@logto/app-insights/react'; import { UserScope } from '@logto/core-kit'; import { LogtoProvider, Prompt, useLogto } from '@logto/react'; import { @@ -23,7 +22,6 @@ import AppLoading from '@/components/AppLoading'; import { isCloud } from '@/consts/env'; import { cloudApi, getManagementApi, meApi } from '@/consts/resources'; import { ConsoleRoutes } from '@/containers/ConsoleRoutes'; -import useTrackUserId from '@/hooks/use-track-user-id'; import { OnboardingRoutes } from '@/onboarding'; import useUserOnboardingData from '@/onboarding/hooks/use-user-onboarding-data'; @@ -114,26 +112,24 @@ function Providers() { }} > - - - - - {/** - * If it's not Cloud (OSS), render the tenant app container directly since only default tenant is available; - * if it's Cloud, render the tenant app container only when a tenant ID is available (in a tenant context). - */} - {!isCloud || currentTenantId ? ( - - - - - - ) : ( - - )} - - - + + + + {/** + * If it's not Cloud (OSS), render the tenant app container directly since only default tenant is available; + * if it's Cloud, render the tenant app container only when a tenant ID is available (in a tenant context). + */} + {!isCloud || currentTenantId ? ( + + + + + + ) : ( + + )} + + ); @@ -146,8 +142,6 @@ function AppRoutes() { const { isOnboarding } = useUserOnboardingData(); const { isAuthenticated } = useLogto(); - useTrackUserId(); - // Authenticated user should load onboarding data before rendering the app. // This looks weird and it will be refactored soon by merging the onboarding // routes with the console routes. diff --git a/packages/console/src/components/PageMeta/index.tsx b/packages/console/src/components/PageMeta/index.tsx index 3818d74d145..f7d6ebe650c 100644 --- a/packages/console/src/components/PageMeta/index.tsx +++ b/packages/console/src/components/PageMeta/index.tsx @@ -1,31 +1,16 @@ -import { AppInsightsContext } from '@logto/app-insights/react'; import type { AdminConsoleKey } from '@logto/phrases'; -import { useContext, useEffect, useState } from 'react'; import { Helmet } from 'react-helmet'; import { useTranslation } from 'react-i18next'; export type Props = { titleKey: AdminConsoleKey | AdminConsoleKey[]; - // eslint-disable-next-line react/boolean-prop-naming - trackPageView?: boolean; }; -function PageMeta({ titleKey, trackPageView = true }: Props) { +function PageMeta({ titleKey }: Props) { const { t } = useTranslation(undefined, { keyPrefix: 'admin_console' }); - const { isSetupFinished, appInsights } = useContext(AppInsightsContext); - const [pageViewTracked, setPageViewTracked] = useState(false); const keys = typeof titleKey === 'string' ? [titleKey] : titleKey; - const rawTitle = keys.map((key) => t(key, { lng: 'en' })).join(' - '); const title = keys.map((key) => t(key)).join(' - '); - useEffect(() => { - // Only track once for the same page - if (isSetupFinished && trackPageView && !pageViewTracked) { - appInsights.trackPageView?.({ name: `Console: ${rawTitle}` }); - setPageViewTracked(true); - } - }, [appInsights, isSetupFinished, pageViewTracked, rawTitle, trackPageView]); - return ; } diff --git a/packages/console/src/containers/ConsoleRoutes/index.tsx b/packages/console/src/containers/ConsoleRoutes/index.tsx index ec49548bc1a..9dbb4d7df0c 100644 --- a/packages/console/src/containers/ConsoleRoutes/index.tsx +++ b/packages/console/src/containers/ConsoleRoutes/index.tsx @@ -1,5 +1,3 @@ -import { Component, GeneralEvent } from '@logto/app-insights/custom-event'; -import { TrackOnce } from '@logto/app-insights/react'; import { ossConsolePath } from '@logto/schemas'; import { Navigate, Outlet, Route, Routes } from 'react-router-dom'; import { SWRConfig } from 'swr'; @@ -25,7 +23,6 @@ function Layout() { return ( - diff --git a/packages/console/src/hooks/use-track-user-id.ts b/packages/console/src/hooks/use-track-user-id.ts deleted file mode 100644 index 35f4eca840c..00000000000 --- a/packages/console/src/hooks/use-track-user-id.ts +++ /dev/null @@ -1,42 +0,0 @@ -import { AppInsightsContext } from '@logto/app-insights/react'; -import { useLogto } from '@logto/react'; -import { trySafe } from '@silverhand/essentials'; -import { useContext, useEffect } from 'react'; - -class NoIdTokenClaimsError extends Error { - name = 'NoIdTokenClaimsError'; - message = 'Cloud not fetch ID Token claims where user is authenticated.'; -} - -const useTrackUserId = () => { - const { isAuthenticated, getIdTokenClaims } = useLogto(); - const { isSetupFinished, appInsights } = useContext(AppInsightsContext); - - useEffect(() => { - const setUserId = async () => { - if (!appInsights.instance) { - return; - } - - if (!isAuthenticated) { - appInsights.instance.clearAuthenticatedUserContext(); - - return; - } - - const claims = await trySafe(getIdTokenClaims()); - - if (claims) { - appInsights.instance.setAuthenticatedUserContext(claims.sub, claims.sub, true); - } else { - appInsights.instance.trackException({ exception: new NoIdTokenClaimsError() }); - } - }; - - if (isSetupFinished) { - void setUserId(); - } - }, [getIdTokenClaims, isSetupFinished, isAuthenticated, appInsights.instance]); -}; - -export default useTrackUserId; diff --git a/packages/console/src/onboarding/index.tsx b/packages/console/src/onboarding/index.tsx index 4f3bf45c911..a5f5833d196 100644 --- a/packages/console/src/onboarding/index.tsx +++ b/packages/console/src/onboarding/index.tsx @@ -1,5 +1,3 @@ -import { Component, ConsoleEvent } from '@logto/app-insights/custom-event'; -import { TrackOnce } from '@logto/app-insights/react'; import { Theme } from '@logto/schemas'; import { useContext, useEffect } from 'react'; import { Route, Navigate, Outlet, Routes } from 'react-router-dom'; @@ -64,17 +62,14 @@ function Layout() { } return ( - <> - -
- - - - - - -
- +
+ + + + + + +
); } diff --git a/packages/console/src/onboarding/pages/SignInExperience/index.tsx b/packages/console/src/onboarding/pages/SignInExperience/index.tsx index 7e6e14b11b1..04539f8a02d 100644 --- a/packages/console/src/onboarding/pages/SignInExperience/index.tsx +++ b/packages/console/src/onboarding/pages/SignInExperience/index.tsx @@ -1,4 +1,3 @@ -import { withAppInsights } from '@logto/app-insights/react'; import { ConnectorType, ServiceConnector } from '@logto/connector-kit'; import { SignInIdentifier } from '@logto/schemas'; import type { SignInExperience as SignInExperienceType, ConnectorResponse } from '@logto/schemas'; @@ -250,4 +249,4 @@ function SignInExperience() { ); } -export default withAppInsights(SignInExperience); +export default SignInExperience; diff --git a/packages/console/src/onboarding/pages/Welcome/index.tsx b/packages/console/src/onboarding/pages/Welcome/index.tsx index 205f743e5d0..6c1ab69ac14 100644 --- a/packages/console/src/onboarding/pages/Welcome/index.tsx +++ b/packages/console/src/onboarding/pages/Welcome/index.tsx @@ -1,4 +1,3 @@ -import { withAppInsights } from '@logto/app-insights/react'; import { type Questionnaire, Project } from '@logto/schemas'; import { conditional } from '@silverhand/essentials'; import { useEffect } from 'react'; @@ -130,4 +129,4 @@ function Welcome() { ); } -export default withAppInsights(Welcome); +export default Welcome; diff --git a/packages/console/src/pages/ApiResourceDetails/index.tsx b/packages/console/src/pages/ApiResourceDetails/index.tsx index 7635a3fa129..5e697217192 100644 --- a/packages/console/src/pages/ApiResourceDetails/index.tsx +++ b/packages/console/src/pages/ApiResourceDetails/index.tsx @@ -1,4 +1,3 @@ -import { withAppInsights } from '@logto/app-insights/react'; import type { Resource } from '@logto/schemas'; import { isManagementApi, Theme } from '@logto/schemas'; import { conditionalArray } from '@silverhand/essentials'; @@ -193,4 +192,4 @@ function ApiResourceDetails() { ); } -export default withAppInsights(ApiResourceDetails); +export default ApiResourceDetails; diff --git a/packages/console/src/pages/ApiResources/index.tsx b/packages/console/src/pages/ApiResources/index.tsx index 86b65966ec5..ec680119cc4 100644 --- a/packages/console/src/pages/ApiResources/index.tsx +++ b/packages/console/src/pages/ApiResources/index.tsx @@ -1,4 +1,3 @@ -import { withAppInsights } from '@logto/app-insights/react'; import type { Resource } from '@logto/schemas'; import { Theme, isManagementApi } from '@logto/schemas'; import { useTranslation } from 'react-i18next'; @@ -146,4 +145,4 @@ function ApiResources() { ); } -export default withAppInsights(ApiResources); +export default ApiResources; diff --git a/packages/console/src/pages/ApplicationDetails/index.tsx b/packages/console/src/pages/ApplicationDetails/index.tsx index 8d8974bbaa0..14f6a1e5369 100644 --- a/packages/console/src/pages/ApplicationDetails/index.tsx +++ b/packages/console/src/pages/ApplicationDetails/index.tsx @@ -1,4 +1,3 @@ -import { withAppInsights } from '@logto/app-insights/react'; import { type ApplicationResponse, type SnakeCaseOidcConfig } from '@logto/schemas'; import { useParams } from 'react-router-dom'; import useSWR from 'swr'; @@ -65,4 +64,4 @@ function ApplicationDetails() { ); } -export default withAppInsights(ApplicationDetails); +export default ApplicationDetails; diff --git a/packages/console/src/pages/Applications/index.tsx b/packages/console/src/pages/Applications/index.tsx index 720c1cb66c6..64e8a5ee188 100644 --- a/packages/console/src/pages/Applications/index.tsx +++ b/packages/console/src/pages/Applications/index.tsx @@ -1,4 +1,3 @@ -import { withAppInsights } from '@logto/app-insights/react'; import { joinPath } from '@silverhand/essentials'; import { useTranslation } from 'react-i18next'; import { useLocation } from 'react-router-dom'; @@ -185,4 +184,4 @@ function Applications({ tab }: Props) { ); } -export default withAppInsights(Applications); +export default Applications; diff --git a/packages/console/src/pages/AuditLogDetails/index.tsx b/packages/console/src/pages/AuditLogDetails/index.tsx index b14406e337d..8789187b6f1 100644 --- a/packages/console/src/pages/AuditLogDetails/index.tsx +++ b/packages/console/src/pages/AuditLogDetails/index.tsx @@ -1,4 +1,3 @@ -import { withAppInsights } from '@logto/app-insights/react'; import type { Application, User, Log, Hook } from '@logto/schemas'; import { demoAppApplicationId } from '@logto/schemas'; import { conditional } from '@silverhand/essentials'; @@ -161,4 +160,4 @@ function AuditLogDetails() { ); } -export default withAppInsights(AuditLogDetails); +export default AuditLogDetails; diff --git a/packages/console/src/pages/AuditLogs/index.tsx b/packages/console/src/pages/AuditLogs/index.tsx index 20268c90a1a..f56857c640d 100644 --- a/packages/console/src/pages/AuditLogs/index.tsx +++ b/packages/console/src/pages/AuditLogs/index.tsx @@ -1,5 +1,3 @@ -import { withAppInsights } from '@logto/app-insights/react'; - import AuditLogTable from '@/components/AuditLogTable'; import PageMeta from '@/components/PageMeta'; import CardTitle from '@/ds-components/CardTitle'; @@ -17,4 +15,4 @@ function AuditLogs() { ); } -export default withAppInsights(AuditLogs); +export default AuditLogs; diff --git a/packages/console/src/pages/ConnectorDetails/index.tsx b/packages/console/src/pages/ConnectorDetails/index.tsx index d7aae4de639..63647d56963 100644 --- a/packages/console/src/pages/ConnectorDetails/index.tsx +++ b/packages/console/src/pages/ConnectorDetails/index.tsx @@ -1,4 +1,3 @@ -import { withAppInsights } from '@logto/app-insights/react'; import { ServiceConnector } from '@logto/connector-kit'; import { ConnectorType } from '@logto/schemas'; import type { ConnectorFactoryResponse, ConnectorResponse } from '@logto/schemas'; @@ -232,4 +231,4 @@ function ConnectorDetails() { ); } -export default withAppInsights(ConnectorDetails); +export default ConnectorDetails; diff --git a/packages/console/src/pages/Connectors/index.tsx b/packages/console/src/pages/Connectors/index.tsx index 8d9fa9903c1..fab02b7984e 100644 --- a/packages/console/src/pages/Connectors/index.tsx +++ b/packages/console/src/pages/Connectors/index.tsx @@ -1,4 +1,3 @@ -import { withAppInsights } from '@logto/app-insights/react'; import { ServiceConnector } from '@logto/connector-kit'; import { ConnectorType } from '@logto/schemas'; import type { ConnectorFactoryResponse } from '@logto/schemas'; @@ -243,4 +242,4 @@ function Connectors() { ); } -export default withAppInsights(Connectors); +export default Connectors; diff --git a/packages/console/src/pages/CustomizeJwt/index.tsx b/packages/console/src/pages/CustomizeJwt/index.tsx index e088c23ca37..3377fc8427a 100644 --- a/packages/console/src/pages/CustomizeJwt/index.tsx +++ b/packages/console/src/pages/CustomizeJwt/index.tsx @@ -1,4 +1,3 @@ -import { withAppInsights } from '@logto/app-insights/react/AppInsightsReact'; import { LogtoJwtTokenKeyType } from '@logto/schemas'; import { useTranslation } from 'react-i18next'; @@ -64,4 +63,4 @@ function CustomizeJwt() { ); } -export default withAppInsights(CustomizeJwt); +export default CustomizeJwt; diff --git a/packages/console/src/pages/CustomizeJwtDetails/index.tsx b/packages/console/src/pages/CustomizeJwtDetails/index.tsx index 09421f3ea6c..850f427b74b 100644 --- a/packages/console/src/pages/CustomizeJwtDetails/index.tsx +++ b/packages/console/src/pages/CustomizeJwtDetails/index.tsx @@ -1,4 +1,3 @@ -import { withAppInsights } from '@logto/app-insights/react/AppInsightsReact'; import { type LogtoJwtTokenKeyType } from '@logto/schemas'; import { useMemo, useState } from 'react'; import { useParams } from 'react-router-dom'; @@ -18,7 +17,7 @@ type Props = { action: Action; }; -function CustomizeJwtDetails({ tokenType, action }: Props) { +function Content({ tokenType, action }: Props) { const { isLoading, error, ...rest } = useDataFetch(tokenType, action); const [isMonacoLoaded, setIsMonacoLoaded] = useState(false); @@ -51,7 +50,7 @@ function CustomizeJwtDetails({ tokenType, action }: Props) { } // Guard the parameters to ensure they are valid -function CustomizeJwtDetailsWrapper() { +function CustomizeJwtDetails() { const { tokenType, action } = useParams(); const params = pageParamsGuard.safeParse({ tokenType, action }); @@ -60,7 +59,7 @@ function CustomizeJwtDetailsWrapper() { return ; } - return ; + return ; } -export default withAppInsights(CustomizeJwtDetailsWrapper); +export default CustomizeJwtDetails; diff --git a/packages/console/src/pages/Dashboard/index.tsx b/packages/console/src/pages/Dashboard/index.tsx index e36c8765c40..a0a1a30d9a4 100644 --- a/packages/console/src/pages/Dashboard/index.tsx +++ b/packages/console/src/pages/Dashboard/index.tsx @@ -1,4 +1,3 @@ -import { withAppInsights } from '@logto/app-insights/react'; import { format } from 'date-fns'; import type { ChangeEventHandler } from 'react'; import { useState } from 'react'; @@ -153,4 +152,4 @@ function Dashboard() { ); } -export default withAppInsights(Dashboard); +export default Dashboard; diff --git a/packages/console/src/pages/EnterpriseSso/index.tsx b/packages/console/src/pages/EnterpriseSso/index.tsx index 9dbcff09c49..74d78056a30 100644 --- a/packages/console/src/pages/EnterpriseSso/index.tsx +++ b/packages/console/src/pages/EnterpriseSso/index.tsx @@ -1,4 +1,3 @@ -import { withAppInsights } from '@logto/app-insights/react'; import { type SsoConnectorWithProviderConfig, ReservedPlanId } from '@logto/schemas'; import { conditional } from '@silverhand/essentials'; import { useContext } from 'react'; @@ -32,7 +31,7 @@ const enterpriseSsoPathname = '/enterprise-sso'; const createEnterpriseSsoPathname = `${enterpriseSsoPathname}/create`; const buildDetailsPathname = (id: string) => `${enterpriseSsoPathname}/${id}`; -function EnterpriseSsoConnectors() { +function EnterpriseSso() { const { pathname } = useLocation(); const { navigate } = useTenantPathname(); const { t } = useTranslation(undefined, { keyPrefix: 'admin_console' }); @@ -176,4 +175,4 @@ function EnterpriseSsoConnectors() { ); } -export default withAppInsights(EnterpriseSsoConnectors); +export default EnterpriseSso; diff --git a/packages/console/src/pages/EnterpriseSsoDetails/index.tsx b/packages/console/src/pages/EnterpriseSsoDetails/index.tsx index 9351609be89..9f69ecf66e5 100644 --- a/packages/console/src/pages/EnterpriseSsoDetails/index.tsx +++ b/packages/console/src/pages/EnterpriseSsoDetails/index.tsx @@ -1,4 +1,3 @@ -import { withAppInsights } from '@logto/app-insights/react'; import { type SignInExperience, type SsoConnectorWithProviderConfig } from '@logto/schemas'; import { pick } from '@silverhand/essentials'; import { useEffect, useState } from 'react'; @@ -31,7 +30,7 @@ import useDeleteConnector from './use-delete-connector'; const getSsoConnectorDetailsPathname = (ssoConnectorId: string, tab: EnterpriseSsoDetailsTabs) => `${enterpriseSsoPathname}/${ssoConnectorId}/${tab}`; -function EnterpriseSsoConnectorDetails() { +function EnterpriseSsoDetails() { const { pathname } = useLocation(); const { ssoConnectorId, tab } = useParams(); @@ -175,4 +174,4 @@ function EnterpriseSsoConnectorDetails() { ); } -export default withAppInsights(EnterpriseSsoConnectorDetails); +export default EnterpriseSsoDetails; diff --git a/packages/console/src/pages/GetStarted/index.tsx b/packages/console/src/pages/GetStarted/index.tsx index 7f6c083add5..50bccdb421b 100644 --- a/packages/console/src/pages/GetStarted/index.tsx +++ b/packages/console/src/pages/GetStarted/index.tsx @@ -1,4 +1,3 @@ -import { withAppInsights } from '@logto/app-insights/react'; import { Theme, type Application, type Resource } from '@logto/schemas'; import classNames from 'classnames'; import { useCallback, useContext, useMemo, useRef, useState } from 'react'; @@ -208,4 +207,4 @@ function GetStarted() { ); } -export default withAppInsights(GetStarted); +export default GetStarted; diff --git a/packages/console/src/pages/Mfa/index.tsx b/packages/console/src/pages/Mfa/index.tsx index 45cc18c4c33..457631a5edb 100644 --- a/packages/console/src/pages/Mfa/index.tsx +++ b/packages/console/src/pages/Mfa/index.tsx @@ -1,4 +1,3 @@ -import { withAppInsights } from '@logto/app-insights/react/AppInsightsReact'; import { type SignInExperience } from '@logto/schemas'; import useSWR from 'swr'; @@ -44,4 +43,4 @@ function Mfa() { ); } -export default withAppInsights(Mfa); +export default Mfa; diff --git a/packages/console/src/pages/NotFound/index.tsx b/packages/console/src/pages/NotFound/index.tsx index c574e62016c..2d102d21ac1 100644 --- a/packages/console/src/pages/NotFound/index.tsx +++ b/packages/console/src/pages/NotFound/index.tsx @@ -1,7 +1,6 @@ import { Theme } from '@logto/schemas'; import classNames from 'classnames'; import { useTranslation } from 'react-i18next'; -import { useLocation } from 'react-router-dom'; import NotFoundDarkImage from '@/assets/images/not-found-dark.svg'; import NotFoundImage from '@/assets/images/not-found.svg'; @@ -18,12 +17,11 @@ type Props = { function NotFound({ className }: Props) { const { t } = useTranslation(undefined, { keyPrefix: 'admin_console' }); const theme = useTheme(); - const location = useLocation(); return (
{/* Don't track "not found" for the root path as it will be redirected. */} - + {theme === Theme.Light ? : }
{t('errors.page_not_found')}
diff --git a/packages/console/src/pages/OrganizationRoleDetails/index.tsx b/packages/console/src/pages/OrganizationRoleDetails/index.tsx index e4f9f2e766f..8351198148c 100644 --- a/packages/console/src/pages/OrganizationRoleDetails/index.tsx +++ b/packages/console/src/pages/OrganizationRoleDetails/index.tsx @@ -1,4 +1,3 @@ -import { withAppInsights } from '@logto/app-insights/react/AppInsightsReact'; import { type OrganizationRole } from '@logto/schemas'; import classNames from 'classnames'; import { useEffect, useState } from 'react'; @@ -133,4 +132,4 @@ function OrganizationRoleDetails() { ); } -export default withAppInsights(OrganizationRoleDetails); +export default OrganizationRoleDetails; diff --git a/packages/console/src/pages/OrganizationTemplate/index.tsx b/packages/console/src/pages/OrganizationTemplate/index.tsx index 01c840844a0..8ff02d032e0 100644 --- a/packages/console/src/pages/OrganizationTemplate/index.tsx +++ b/packages/console/src/pages/OrganizationTemplate/index.tsx @@ -1,4 +1,3 @@ -import { withAppInsights } from '@logto/app-insights/react/AppInsightsReact'; import { ReservedPlanId } from '@logto/schemas'; import { cond } from '@silverhand/essentials'; import classNames from 'classnames'; @@ -111,4 +110,4 @@ function OrganizationTemplate() { ); } -export default withAppInsights(OrganizationTemplate); +export default OrganizationTemplate; diff --git a/packages/console/src/pages/Profile/index.tsx b/packages/console/src/pages/Profile/index.tsx index ad84e5980d6..afc6d451d6d 100644 --- a/packages/console/src/pages/Profile/index.tsx +++ b/packages/console/src/pages/Profile/index.tsx @@ -1,4 +1,3 @@ -import { withAppInsights } from '@logto/app-insights/react'; import type { ConnectorResponse } from '@logto/schemas'; import { useState } from 'react'; import { useTranslation } from 'react-i18next'; @@ -99,4 +98,4 @@ function Profile() { ); } -export default withAppInsights(Profile); +export default Profile; diff --git a/packages/console/src/pages/RoleDetails/index.tsx b/packages/console/src/pages/RoleDetails/index.tsx index 9ec727495e3..4cba0d18673 100644 --- a/packages/console/src/pages/RoleDetails/index.tsx +++ b/packages/console/src/pages/RoleDetails/index.tsx @@ -1,4 +1,3 @@ -import { withAppInsights } from '@logto/app-insights/react'; import type { Role } from '@logto/schemas'; import { Theme, RoleType } from '@logto/schemas'; import classNames from 'classnames'; @@ -151,4 +150,4 @@ function RoleDetails() { ); } -export default withAppInsights(RoleDetails); +export default RoleDetails; diff --git a/packages/console/src/pages/Roles/index.tsx b/packages/console/src/pages/Roles/index.tsx index 2a3072ee763..172f8d52e00 100644 --- a/packages/console/src/pages/Roles/index.tsx +++ b/packages/console/src/pages/Roles/index.tsx @@ -1,4 +1,3 @@ -import { withAppInsights } from '@logto/app-insights/react'; import { RoleType, type RoleResponse } from '@logto/schemas'; import { Theme } from '@logto/schemas'; import { conditional } from '@silverhand/essentials'; @@ -211,4 +210,4 @@ function Roles() { ); } -export default withAppInsights(Roles); +export default Roles; diff --git a/packages/console/src/pages/SignInExperience/index.tsx b/packages/console/src/pages/SignInExperience/index.tsx index 589f97e10b1..213313f18bd 100644 --- a/packages/console/src/pages/SignInExperience/index.tsx +++ b/packages/console/src/pages/SignInExperience/index.tsx @@ -1,4 +1,3 @@ -import { withAppInsights } from '@logto/app-insights/react'; import type { SignInExperience as SignInExperienceType } from '@logto/schemas'; import type { ReactNode } from 'react'; import useSWR from 'swr'; @@ -101,4 +100,4 @@ function SignInExperience() { ); } -export default withAppInsights(SignInExperience); +export default SignInExperience; diff --git a/packages/console/src/pages/SigningKeys/index.tsx b/packages/console/src/pages/SigningKeys/index.tsx index f2f3aaba3e2..f90263134a6 100644 --- a/packages/console/src/pages/SigningKeys/index.tsx +++ b/packages/console/src/pages/SigningKeys/index.tsx @@ -1,4 +1,3 @@ -import { withAppInsights } from '@logto/app-insights/react/AppInsightsReact'; import { LogtoOidcConfigKeyType } from '@logto/schemas'; import PageMeta from '@/components/PageMeta'; @@ -27,4 +26,4 @@ function SigningKeys() { ); } -export default withAppInsights(SigningKeys); +export default SigningKeys; diff --git a/packages/console/src/pages/TenantSettings/BillingHistory/index.tsx b/packages/console/src/pages/TenantSettings/BillingHistory/index.tsx index 16c8dfea60b..4ed312ae3cb 100644 --- a/packages/console/src/pages/TenantSettings/BillingHistory/index.tsx +++ b/packages/console/src/pages/TenantSettings/BillingHistory/index.tsx @@ -1,4 +1,3 @@ -import { withAppInsights } from '@logto/app-insights/react'; import { conditional } from '@silverhand/essentials'; import dayjs from 'dayjs'; import { useCallback, useContext, useMemo } from 'react'; @@ -92,4 +91,4 @@ function BillingHistory() { ); } -export default withAppInsights(BillingHistory); +export default BillingHistory; diff --git a/packages/console/src/pages/TenantSettings/Subscription/index.tsx b/packages/console/src/pages/TenantSettings/Subscription/index.tsx index 578eb6449d2..69bb1186566 100644 --- a/packages/console/src/pages/TenantSettings/Subscription/index.tsx +++ b/packages/console/src/pages/TenantSettings/Subscription/index.tsx @@ -1,4 +1,3 @@ -import { withAppInsights } from '@logto/app-insights/react'; import { useContext } from 'react'; import PageMeta from '@/components/PageMeta'; @@ -61,4 +60,4 @@ function Subscription() { ); } -export default withAppInsights(Subscription); +export default Subscription; diff --git a/packages/console/src/pages/TenantSettings/TenantDomainSettings/index.tsx b/packages/console/src/pages/TenantSettings/TenantDomainSettings/index.tsx index b573021acb7..d234ed13f4a 100644 --- a/packages/console/src/pages/TenantSettings/TenantDomainSettings/index.tsx +++ b/packages/console/src/pages/TenantSettings/TenantDomainSettings/index.tsx @@ -1,4 +1,3 @@ -import { withAppInsights } from '@logto/app-insights/react'; import { type Domain, DomainStatus } from '@logto/schemas'; import { Trans, useTranslation } from 'react-i18next'; @@ -92,4 +91,4 @@ function TenantDomainSettings() { ); } -export default withAppInsights(TenantDomainSettings); +export default TenantDomainSettings; diff --git a/packages/console/src/pages/UserDetails/index.tsx b/packages/console/src/pages/UserDetails/index.tsx index 22383a8b6f4..8a7bc0d59eb 100644 --- a/packages/console/src/pages/UserDetails/index.tsx +++ b/packages/console/src/pages/UserDetails/index.tsx @@ -1,4 +1,3 @@ -import { withAppInsights } from '@logto/app-insights/react'; import type { UserProfileResponse, User } from '@logto/schemas'; import classNames from 'classnames'; import { useEffect, useState } from 'react'; @@ -235,4 +234,4 @@ function UserDetails() { ); } -export default withAppInsights(UserDetails); +export default UserDetails; diff --git a/packages/console/src/pages/Users/index.tsx b/packages/console/src/pages/Users/index.tsx index d35ffef16d9..5d7803ac105 100644 --- a/packages/console/src/pages/Users/index.tsx +++ b/packages/console/src/pages/Users/index.tsx @@ -1,4 +1,3 @@ -import { withAppInsights } from '@logto/app-insights/react'; import type { User } from '@logto/schemas'; import { conditional } from '@silverhand/essentials'; import { useTranslation } from 'react-i18next'; @@ -177,4 +176,4 @@ function Users() { ); } -export default withAppInsights(Users); +export default Users; diff --git a/packages/console/src/pages/WebhookDetails/index.tsx b/packages/console/src/pages/WebhookDetails/index.tsx index bab502a8b7d..52771e37f13 100644 --- a/packages/console/src/pages/WebhookDetails/index.tsx +++ b/packages/console/src/pages/WebhookDetails/index.tsx @@ -1,4 +1,3 @@ -import { withAppInsights } from '@logto/app-insights/react'; import { type HookResponse, type Hook } from '@logto/schemas'; import { conditional } from '@silverhand/essentials'; import classNames from 'classnames'; @@ -176,4 +175,4 @@ function WebhookDetails() { ); } -export default withAppInsights(WebhookDetails); +export default WebhookDetails; diff --git a/packages/console/src/pages/Webhooks/index.tsx b/packages/console/src/pages/Webhooks/index.tsx index 8be1c187792..e7e881c9c2b 100644 --- a/packages/console/src/pages/Webhooks/index.tsx +++ b/packages/console/src/pages/Webhooks/index.tsx @@ -1,4 +1,3 @@ -import { withAppInsights } from '@logto/app-insights/react'; import { type HookEvent, type Hook, Theme, type HookResponse } from '@logto/schemas'; import { conditional } from '@silverhand/essentials'; import { toast } from 'react-hot-toast'; @@ -181,4 +180,4 @@ function Webhooks() { ); } -export default withAppInsights(Webhooks); +export default Webhooks; diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 9796db70c65..ecb2191c402 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -2711,9 +2711,6 @@ importers: '@jest/types': specifier: ^29.5.0 version: 29.5.0 - '@logto/app-insights': - specifier: workspace:^1.4.0 - version: link:../app-insights '@logto/cloud': specifier: 0.2.5-821690c version: 0.2.5-821690c(zod@3.22.4) @@ -10589,7 +10586,7 @@ packages: 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) + vitest: 1.4.0(@types/node@20.10.4) transitivePeerDependencies: - supports-color dev: true From e1d5b8a72a4ae69fbd403ecdb98b428f426a949d Mon Sep 17 00:00:00 2001 From: Gao Sun Date: Thu, 18 Apr 2024 14:32:12 +0800 Subject: [PATCH 287/687] refactor: upgrade packages (#5739) * refactor: upgrade packages * refactor: fix type issues * refactor: fix koa-guard --- packages/app-insights/package.json | 8 +- .../src/react/AppInsightsReact.ts | 2 +- .../connector-alipay-native/package.json | 4 +- .../connector-alipay-web/package.json | 4 +- .../connector-aliyun-dm/package.json | 4 +- .../connector-aliyun-sms/package.json | 4 +- .../connectors/connector-apple/package.json | 4 +- .../connectors/connector-aws-ses/package.json | 4 +- .../connectors/connector-azuread/package.json | 4 +- .../connectors/connector-discord/package.json | 4 +- .../connector-facebook/package.json | 4 +- .../connector-feishu-web/package.json | 4 +- .../connectors/connector-github/package.json | 4 +- .../connectors/connector-google/package.json | 4 +- .../connectors/connector-kakao/package.json | 4 +- .../connector-logto-email/package.json | 4 +- .../connector-logto-sms/package.json | 4 +- .../connector-logto-social-demo/package.json | 4 +- .../connectors/connector-mailgun/package.json | 4 +- .../package.json | 4 +- .../connector-mock-email/package.json | 4 +- .../connector-mock-sms/package.json | 4 +- .../connector-mock-social/package.json | 4 +- .../connectors/connector-naver/package.json | 4 +- .../connectors/connector-oauth2/package.json | 4 +- .../connectors/connector-oidc/package.json | 4 +- .../connectors/connector-saml/package.json | 6 +- .../connector-sendgrid-email/package.json | 4 +- .../connectors/connector-smsaero/package.json | 4 +- .../connectors/connector-smtp/package.json | 4 +- .../connector-tencent-sms/package.json | 4 +- .../connector-twilio-sms/package.json | 4 +- .../connector-wechat-native/package.json | 4 +- .../connector-wechat-web/package.json | 4 +- .../connectors/connector-wecom/package.json | 4 +- packages/core/package.json | 20 +- packages/core/src/include.d/koa-body.d.ts | 8 +- .../src/include.d/oidc-provider/index.d.ts | 4 - packages/core/src/libraries/session.ts | 4 +- .../core/src/middleware/koa-guard.test.ts | 21 +- packages/core/src/middleware/koa-guard.ts | 4 +- packages/core/src/oidc/defaults.ts | 4 +- .../core/src/oidc/grants/refresh-token.ts | 4 +- packages/core/src/oidc/init.ts | 2 +- packages/core/src/oidc/resource.ts | 5 +- packages/core/src/routes/callback.ts | 33 +- pnpm-lock.yaml | 3344 +++++++++-------- 47 files changed, 1998 insertions(+), 1599 deletions(-) diff --git a/packages/app-insights/package.json b/packages/app-insights/package.json index dc5229948e2..d862bf8da46 100644 --- a/packages/app-insights/package.json +++ b/packages/app-insights/package.json @@ -56,11 +56,11 @@ }, "prettier": "@silverhand/eslint-config/.prettierrc", "dependencies": { - "@microsoft/applicationinsights-clickanalytics-js": "^3.0.2", - "@microsoft/applicationinsights-react-js": "^17.0.0", - "@microsoft/applicationinsights-web": "^3.0.2", + "@microsoft/applicationinsights-clickanalytics-js": "^3.1.2", + "@microsoft/applicationinsights-react-js": "^17.1.2", + "@microsoft/applicationinsights-web": "^3.1.2", "@silverhand/essentials": "^2.9.0", - "applicationinsights": "^2.7.0" + "applicationinsights": "^2.9.5" }, "peerDependencies": { "history": "^5.3.0", diff --git a/packages/app-insights/src/react/AppInsightsReact.ts b/packages/app-insights/src/react/AppInsightsReact.ts index 69a06851130..a5b90ed685a 100644 --- a/packages/app-insights/src/react/AppInsightsReact.ts +++ b/packages/app-insights/src/react/AppInsightsReact.ts @@ -108,7 +108,7 @@ export class AppInsightsReact { // @see https://github.com/microsoft/ApplicationInsights-JS#example-setting-cloud-role-name // @see https://github.com/microsoft/ApplicationInsights-node.js/blob/a573e40fc66981c6a3106bdc5b783d1d94f64231/Schema/PublicSchema/ContextTagKeys.bond#L83 /* eslint-disable @silverhand/fp/no-mutation */ - item.tags = [...(item.tags ?? []), { 'ai.cloud.role': cloudRole }]; + item.tags = { ...item.tags, 'ai.cloud.role': cloudRole }; /* eslint-enable @silverhand/fp/no-mutation */ }); diff --git a/packages/connectors/connector-alipay-native/package.json b/packages/connectors/connector-alipay-native/package.json index 995613fcbb5..271213f4bbe 100644 --- a/packages/connectors/connector-alipay-native/package.json +++ b/packages/connectors/connector-alipay-native/package.json @@ -21,7 +21,7 @@ "@silverhand/eslint-config": "5.0.0", "@silverhand/ts-config": "5.0.0", "@types/node": "^20.11.20", - "@types/supertest": "^6.0.1", + "@types/supertest": "^6.0.2", "@vitest/coverage-v8": "^1.4.0", "eslint": "^8.44.0", "lint-staged": "^15.0.2", @@ -29,7 +29,7 @@ "prettier": "^3.0.0", "rollup": "^4.12.0", "rollup-plugin-output-size": "^1.3.0", - "supertest": "^6.2.2", + "supertest": "^6.3.4", "typescript": "^5.3.3", "vitest": "^1.4.0" }, diff --git a/packages/connectors/connector-alipay-web/package.json b/packages/connectors/connector-alipay-web/package.json index 814c6109003..8098bf43599 100644 --- a/packages/connectors/connector-alipay-web/package.json +++ b/packages/connectors/connector-alipay-web/package.json @@ -20,7 +20,7 @@ "@silverhand/eslint-config": "5.0.0", "@silverhand/ts-config": "5.0.0", "@types/node": "^20.11.20", - "@types/supertest": "^6.0.1", + "@types/supertest": "^6.0.2", "@vitest/coverage-v8": "^1.4.0", "eslint": "^8.44.0", "lint-staged": "^15.0.2", @@ -28,7 +28,7 @@ "prettier": "^3.0.0", "rollup": "^4.12.0", "rollup-plugin-output-size": "^1.3.0", - "supertest": "^6.2.2", + "supertest": "^6.3.4", "typescript": "^5.3.3", "vitest": "^1.4.0" }, diff --git a/packages/connectors/connector-aliyun-dm/package.json b/packages/connectors/connector-aliyun-dm/package.json index 655adc62b33..d9bc46af982 100644 --- a/packages/connectors/connector-aliyun-dm/package.json +++ b/packages/connectors/connector-aliyun-dm/package.json @@ -58,7 +58,7 @@ "@silverhand/eslint-config": "5.0.0", "@silverhand/ts-config": "5.0.0", "@types/node": "^20.11.20", - "@types/supertest": "^6.0.1", + "@types/supertest": "^6.0.2", "@vitest/coverage-v8": "^1.4.0", "eslint": "^8.44.0", "lint-staged": "^15.0.2", @@ -66,7 +66,7 @@ "prettier": "^3.0.0", "rollup": "^4.12.0", "rollup-plugin-output-size": "^1.3.0", - "supertest": "^6.2.2", + "supertest": "^6.3.4", "typescript": "^5.3.3", "vitest": "^1.4.0" } diff --git a/packages/connectors/connector-aliyun-sms/package.json b/packages/connectors/connector-aliyun-sms/package.json index 825e59b3b65..ca2a6037f69 100644 --- a/packages/connectors/connector-aliyun-sms/package.json +++ b/packages/connectors/connector-aliyun-sms/package.json @@ -58,7 +58,7 @@ "@silverhand/eslint-config": "5.0.0", "@silverhand/ts-config": "5.0.0", "@types/node": "^20.11.20", - "@types/supertest": "^6.0.1", + "@types/supertest": "^6.0.2", "@vitest/coverage-v8": "^1.4.0", "eslint": "^8.44.0", "lint-staged": "^15.0.2", @@ -66,7 +66,7 @@ "prettier": "^3.0.0", "rollup": "^4.12.0", "rollup-plugin-output-size": "^1.3.0", - "supertest": "^6.2.2", + "supertest": "^6.3.4", "typescript": "^5.3.3", "vitest": "^1.4.0" } diff --git a/packages/connectors/connector-apple/package.json b/packages/connectors/connector-apple/package.json index 50b3431bf10..0104b25dc91 100644 --- a/packages/connectors/connector-apple/package.json +++ b/packages/connectors/connector-apple/package.json @@ -60,7 +60,7 @@ "@silverhand/eslint-config": "5.0.0", "@silverhand/ts-config": "5.0.0", "@types/node": "^20.11.20", - "@types/supertest": "^6.0.1", + "@types/supertest": "^6.0.2", "@vitest/coverage-v8": "^1.4.0", "eslint": "^8.44.0", "lint-staged": "^15.0.2", @@ -68,7 +68,7 @@ "prettier": "^3.0.0", "rollup": "^4.12.0", "rollup-plugin-output-size": "^1.3.0", - "supertest": "^6.2.2", + "supertest": "^6.3.4", "typescript": "^5.3.3", "vitest": "^1.4.0" } diff --git a/packages/connectors/connector-aws-ses/package.json b/packages/connectors/connector-aws-ses/package.json index 4ca6a8b7623..f5b4ab7ffa2 100644 --- a/packages/connectors/connector-aws-ses/package.json +++ b/packages/connectors/connector-aws-ses/package.json @@ -61,7 +61,7 @@ "@silverhand/eslint-config": "5.0.0", "@silverhand/ts-config": "5.0.0", "@types/node": "^20.11.20", - "@types/supertest": "^6.0.1", + "@types/supertest": "^6.0.2", "@vitest/coverage-v8": "^1.4.0", "eslint": "^8.44.0", "lint-staged": "^15.0.2", @@ -69,7 +69,7 @@ "prettier": "^3.0.0", "rollup": "^4.12.0", "rollup-plugin-output-size": "^1.3.0", - "supertest": "^6.2.2", + "supertest": "^6.3.4", "typescript": "^5.3.3", "vitest": "^1.4.0" } diff --git a/packages/connectors/connector-azuread/package.json b/packages/connectors/connector-azuread/package.json index d4bb257bbec..b6bf0c7fb94 100644 --- a/packages/connectors/connector-azuread/package.json +++ b/packages/connectors/connector-azuread/package.json @@ -60,7 +60,7 @@ "@silverhand/eslint-config": "5.0.0", "@silverhand/ts-config": "5.0.0", "@types/node": "^20.11.20", - "@types/supertest": "^6.0.1", + "@types/supertest": "^6.0.2", "@vitest/coverage-v8": "^1.4.0", "eslint": "^8.44.0", "lint-staged": "^15.0.2", @@ -68,7 +68,7 @@ "prettier": "^3.0.0", "rollup": "^4.12.0", "rollup-plugin-output-size": "^1.3.0", - "supertest": "^6.2.2", + "supertest": "^6.3.4", "typescript": "^5.3.3", "vitest": "^1.4.0" } diff --git a/packages/connectors/connector-discord/package.json b/packages/connectors/connector-discord/package.json index 6534a5649a1..eac2edc3ceb 100644 --- a/packages/connectors/connector-discord/package.json +++ b/packages/connectors/connector-discord/package.json @@ -59,7 +59,7 @@ "@silverhand/eslint-config": "5.0.0", "@silverhand/ts-config": "5.0.0", "@types/node": "^20.11.20", - "@types/supertest": "^6.0.1", + "@types/supertest": "^6.0.2", "@vitest/coverage-v8": "^1.4.0", "eslint": "^8.44.0", "lint-staged": "^15.0.2", @@ -67,7 +67,7 @@ "prettier": "^3.0.0", "rollup": "^4.12.0", "rollup-plugin-output-size": "^1.3.0", - "supertest": "^6.2.2", + "supertest": "^6.3.4", "typescript": "^5.3.3", "vitest": "^1.4.0" } diff --git a/packages/connectors/connector-facebook/package.json b/packages/connectors/connector-facebook/package.json index 5f30337b490..561bc2ab63f 100644 --- a/packages/connectors/connector-facebook/package.json +++ b/packages/connectors/connector-facebook/package.json @@ -59,7 +59,7 @@ "@silverhand/eslint-config": "5.0.0", "@silverhand/ts-config": "5.0.0", "@types/node": "^20.11.20", - "@types/supertest": "^6.0.1", + "@types/supertest": "^6.0.2", "@vitest/coverage-v8": "^1.4.0", "eslint": "^8.44.0", "lint-staged": "^15.0.2", @@ -67,7 +67,7 @@ "prettier": "^3.0.0", "rollup": "^4.12.0", "rollup-plugin-output-size": "^1.3.0", - "supertest": "^6.2.2", + "supertest": "^6.3.4", "typescript": "^5.3.3", "vitest": "^1.4.0" } diff --git a/packages/connectors/connector-feishu-web/package.json b/packages/connectors/connector-feishu-web/package.json index b37b34ea14f..17cd6148138 100644 --- a/packages/connectors/connector-feishu-web/package.json +++ b/packages/connectors/connector-feishu-web/package.json @@ -59,7 +59,7 @@ "@silverhand/eslint-config": "5.0.0", "@silverhand/ts-config": "5.0.0", "@types/node": "^20.11.20", - "@types/supertest": "^6.0.1", + "@types/supertest": "^6.0.2", "@vitest/coverage-v8": "^1.4.0", "eslint": "^8.44.0", "lint-staged": "^15.0.2", @@ -67,7 +67,7 @@ "prettier": "^3.0.0", "rollup": "^4.12.0", "rollup-plugin-output-size": "^1.3.0", - "supertest": "^6.2.2", + "supertest": "^6.3.4", "typescript": "^5.3.3", "vitest": "^1.4.0" } diff --git a/packages/connectors/connector-github/package.json b/packages/connectors/connector-github/package.json index 11f6877e31f..12dc684a8aa 100644 --- a/packages/connectors/connector-github/package.json +++ b/packages/connectors/connector-github/package.json @@ -60,7 +60,7 @@ "@silverhand/eslint-config": "5.0.0", "@silverhand/ts-config": "5.0.0", "@types/node": "^20.11.20", - "@types/supertest": "^6.0.1", + "@types/supertest": "^6.0.2", "@vitest/coverage-v8": "^1.4.0", "eslint": "^8.44.0", "lint-staged": "^15.0.2", @@ -68,7 +68,7 @@ "prettier": "^3.0.0", "rollup": "^4.12.0", "rollup-plugin-output-size": "^1.3.0", - "supertest": "^6.2.2", + "supertest": "^6.3.4", "typescript": "^5.3.3", "vitest": "^1.4.0" } diff --git a/packages/connectors/connector-google/package.json b/packages/connectors/connector-google/package.json index 4630230fbe2..076ee4b4aab 100644 --- a/packages/connectors/connector-google/package.json +++ b/packages/connectors/connector-google/package.json @@ -59,7 +59,7 @@ "@silverhand/eslint-config": "5.0.0", "@silverhand/ts-config": "5.0.0", "@types/node": "^20.11.20", - "@types/supertest": "^6.0.1", + "@types/supertest": "^6.0.2", "@vitest/coverage-v8": "^1.4.0", "eslint": "^8.44.0", "lint-staged": "^15.0.2", @@ -67,7 +67,7 @@ "prettier": "^3.0.0", "rollup": "^4.12.0", "rollup-plugin-output-size": "^1.3.0", - "supertest": "^6.2.2", + "supertest": "^6.3.4", "typescript": "^5.3.3", "vitest": "^1.4.0" } diff --git a/packages/connectors/connector-kakao/package.json b/packages/connectors/connector-kakao/package.json index 3db84e48cf0..c79592cbb07 100644 --- a/packages/connectors/connector-kakao/package.json +++ b/packages/connectors/connector-kakao/package.json @@ -59,7 +59,7 @@ "@silverhand/eslint-config": "5.0.0", "@silverhand/ts-config": "5.0.0", "@types/node": "^20.11.20", - "@types/supertest": "^6.0.1", + "@types/supertest": "^6.0.2", "@vitest/coverage-v8": "^1.4.0", "eslint": "^8.44.0", "lint-staged": "^15.0.2", @@ -67,7 +67,7 @@ "prettier": "^3.0.0", "rollup": "^4.12.0", "rollup-plugin-output-size": "^1.3.0", - "supertest": "^6.2.2", + "supertest": "^6.3.4", "typescript": "^5.3.3", "vitest": "^1.4.0" } diff --git a/packages/connectors/connector-logto-email/package.json b/packages/connectors/connector-logto-email/package.json index 7ffdfde161b..6d0996108e3 100644 --- a/packages/connectors/connector-logto-email/package.json +++ b/packages/connectors/connector-logto-email/package.json @@ -60,7 +60,7 @@ "@silverhand/eslint-config": "5.0.0", "@silverhand/ts-config": "5.0.0", "@types/node": "^20.11.20", - "@types/supertest": "^6.0.1", + "@types/supertest": "^6.0.2", "@vitest/coverage-v8": "^1.4.0", "eslint": "^8.44.0", "lint-staged": "^15.0.2", @@ -68,7 +68,7 @@ "prettier": "^3.0.0", "rollup": "^4.12.0", "rollup-plugin-output-size": "^1.3.0", - "supertest": "^6.2.2", + "supertest": "^6.3.4", "typescript": "^5.3.3", "vitest": "^1.4.0" } diff --git a/packages/connectors/connector-logto-sms/package.json b/packages/connectors/connector-logto-sms/package.json index 57b50c8bce6..b677b137797 100644 --- a/packages/connectors/connector-logto-sms/package.json +++ b/packages/connectors/connector-logto-sms/package.json @@ -59,7 +59,7 @@ "@silverhand/eslint-config": "5.0.0", "@silverhand/ts-config": "5.0.0", "@types/node": "^20.11.20", - "@types/supertest": "^6.0.1", + "@types/supertest": "^6.0.2", "@vitest/coverage-v8": "^1.4.0", "eslint": "^8.44.0", "lint-staged": "^15.0.2", @@ -67,7 +67,7 @@ "prettier": "^3.0.0", "rollup": "^4.12.0", "rollup-plugin-output-size": "^1.3.0", - "supertest": "^6.2.2", + "supertest": "^6.3.4", "typescript": "^5.3.3", "vitest": "^1.4.0" } diff --git a/packages/connectors/connector-logto-social-demo/package.json b/packages/connectors/connector-logto-social-demo/package.json index 72074379b45..b0bd422e68e 100644 --- a/packages/connectors/connector-logto-social-demo/package.json +++ b/packages/connectors/connector-logto-social-demo/package.json @@ -59,7 +59,7 @@ "@silverhand/eslint-config": "5.0.0", "@silverhand/ts-config": "5.0.0", "@types/node": "^20.11.20", - "@types/supertest": "^6.0.1", + "@types/supertest": "^6.0.2", "@vitest/coverage-v8": "^1.4.0", "eslint": "^8.44.0", "lint-staged": "^15.0.2", @@ -67,7 +67,7 @@ "prettier": "^3.0.0", "rollup": "^4.12.0", "rollup-plugin-output-size": "^1.3.0", - "supertest": "^6.2.2", + "supertest": "^6.3.4", "typescript": "^5.3.3", "vitest": "^1.4.0" } diff --git a/packages/connectors/connector-mailgun/package.json b/packages/connectors/connector-mailgun/package.json index 9a119778492..7b16e753266 100644 --- a/packages/connectors/connector-mailgun/package.json +++ b/packages/connectors/connector-mailgun/package.json @@ -59,7 +59,7 @@ "@silverhand/eslint-config": "5.0.0", "@silverhand/ts-config": "5.0.0", "@types/node": "^20.11.20", - "@types/supertest": "^6.0.1", + "@types/supertest": "^6.0.2", "@vitest/coverage-v8": "^1.4.0", "eslint": "^8.44.0", "lint-staged": "^15.0.2", @@ -67,7 +67,7 @@ "prettier": "^3.0.0", "rollup": "^4.12.0", "rollup-plugin-output-size": "^1.3.0", - "supertest": "^6.2.2", + "supertest": "^6.3.4", "typescript": "^5.3.3", "vitest": "^1.4.0" } diff --git a/packages/connectors/connector-mock-email-alternative/package.json b/packages/connectors/connector-mock-email-alternative/package.json index 18fbdf42b93..c67a8f25c3a 100644 --- a/packages/connectors/connector-mock-email-alternative/package.json +++ b/packages/connectors/connector-mock-email-alternative/package.json @@ -59,7 +59,7 @@ "@silverhand/eslint-config": "5.0.0", "@silverhand/ts-config": "5.0.0", "@types/node": "^20.11.20", - "@types/supertest": "^6.0.1", + "@types/supertest": "^6.0.2", "@vitest/coverage-v8": "^1.4.0", "eslint": "^8.44.0", "lint-staged": "^15.0.2", @@ -67,7 +67,7 @@ "prettier": "^3.0.0", "rollup": "^4.12.0", "rollup-plugin-output-size": "^1.3.0", - "supertest": "^6.2.2", + "supertest": "^6.3.4", "typescript": "^5.3.3", "vitest": "^1.4.0" } diff --git a/packages/connectors/connector-mock-email/package.json b/packages/connectors/connector-mock-email/package.json index 48265e28973..f0c533c297f 100644 --- a/packages/connectors/connector-mock-email/package.json +++ b/packages/connectors/connector-mock-email/package.json @@ -59,7 +59,7 @@ "@silverhand/eslint-config": "5.0.0", "@silverhand/ts-config": "5.0.0", "@types/node": "^20.11.20", - "@types/supertest": "^6.0.1", + "@types/supertest": "^6.0.2", "@vitest/coverage-v8": "^1.4.0", "eslint": "^8.44.0", "lint-staged": "^15.0.2", @@ -67,7 +67,7 @@ "prettier": "^3.0.0", "rollup": "^4.12.0", "rollup-plugin-output-size": "^1.3.0", - "supertest": "^6.2.2", + "supertest": "^6.3.4", "typescript": "^5.3.3", "vitest": "^1.4.0" } diff --git a/packages/connectors/connector-mock-sms/package.json b/packages/connectors/connector-mock-sms/package.json index 00cef54f01b..053de57a616 100644 --- a/packages/connectors/connector-mock-sms/package.json +++ b/packages/connectors/connector-mock-sms/package.json @@ -59,7 +59,7 @@ "@silverhand/eslint-config": "5.0.0", "@silverhand/ts-config": "5.0.0", "@types/node": "^20.11.20", - "@types/supertest": "^6.0.1", + "@types/supertest": "^6.0.2", "@vitest/coverage-v8": "^1.4.0", "eslint": "^8.44.0", "lint-staged": "^15.0.2", @@ -67,7 +67,7 @@ "prettier": "^3.0.0", "rollup": "^4.12.0", "rollup-plugin-output-size": "^1.3.0", - "supertest": "^6.2.2", + "supertest": "^6.3.4", "typescript": "^5.3.3", "vitest": "^1.4.0" } diff --git a/packages/connectors/connector-mock-social/package.json b/packages/connectors/connector-mock-social/package.json index 4480b71c88a..2e58d8e5418 100644 --- a/packages/connectors/connector-mock-social/package.json +++ b/packages/connectors/connector-mock-social/package.json @@ -59,7 +59,7 @@ "@silverhand/eslint-config": "5.0.0", "@silverhand/ts-config": "5.0.0", "@types/node": "^20.11.20", - "@types/supertest": "^6.0.1", + "@types/supertest": "^6.0.2", "@vitest/coverage-v8": "^1.4.0", "eslint": "^8.44.0", "lint-staged": "^15.0.2", @@ -67,7 +67,7 @@ "prettier": "^3.0.0", "rollup": "^4.12.0", "rollup-plugin-output-size": "^1.3.0", - "supertest": "^6.2.2", + "supertest": "^6.3.4", "typescript": "^5.3.3", "vitest": "^1.4.0" } diff --git a/packages/connectors/connector-naver/package.json b/packages/connectors/connector-naver/package.json index 0eed187095d..b9fa9fcc3d7 100644 --- a/packages/connectors/connector-naver/package.json +++ b/packages/connectors/connector-naver/package.json @@ -59,7 +59,7 @@ "@silverhand/eslint-config": "5.0.0", "@silverhand/ts-config": "5.0.0", "@types/node": "^20.11.20", - "@types/supertest": "^6.0.1", + "@types/supertest": "^6.0.2", "@vitest/coverage-v8": "^1.4.0", "eslint": "^8.44.0", "lint-staged": "^15.0.2", @@ -67,7 +67,7 @@ "prettier": "^3.0.0", "rollup": "^4.12.0", "rollup-plugin-output-size": "^1.3.0", - "supertest": "^6.2.2", + "supertest": "^6.3.4", "typescript": "^5.3.3", "vitest": "^1.4.0" } diff --git a/packages/connectors/connector-oauth2/package.json b/packages/connectors/connector-oauth2/package.json index a6886838b1e..5577a5f6855 100644 --- a/packages/connectors/connector-oauth2/package.json +++ b/packages/connectors/connector-oauth2/package.json @@ -60,7 +60,7 @@ "@silverhand/eslint-config": "5.0.0", "@silverhand/ts-config": "5.0.0", "@types/node": "^20.11.20", - "@types/supertest": "^6.0.1", + "@types/supertest": "^6.0.2", "@vitest/coverage-v8": "^1.4.0", "eslint": "^8.44.0", "lint-staged": "^15.0.2", @@ -68,7 +68,7 @@ "prettier": "^3.0.0", "rollup": "^4.12.0", "rollup-plugin-output-size": "^1.3.0", - "supertest": "^6.2.2", + "supertest": "^6.3.4", "typescript": "^5.3.3", "vitest": "^1.4.0" } diff --git a/packages/connectors/connector-oidc/package.json b/packages/connectors/connector-oidc/package.json index ed8145075e0..dfa5f54b94e 100644 --- a/packages/connectors/connector-oidc/package.json +++ b/packages/connectors/connector-oidc/package.json @@ -61,7 +61,7 @@ "@silverhand/eslint-config": "5.0.0", "@silverhand/ts-config": "5.0.0", "@types/node": "^20.11.20", - "@types/supertest": "^6.0.1", + "@types/supertest": "^6.0.2", "@vitest/coverage-v8": "^1.4.0", "eslint": "^8.44.0", "lint-staged": "^15.0.2", @@ -69,7 +69,7 @@ "prettier": "^3.0.0", "rollup": "^4.12.0", "rollup-plugin-output-size": "^1.3.0", - "supertest": "^6.2.2", + "supertest": "^6.3.4", "typescript": "^5.3.3", "vitest": "^1.4.0" } diff --git a/packages/connectors/connector-saml/package.json b/packages/connectors/connector-saml/package.json index 2c39a174b77..60c931a3b58 100644 --- a/packages/connectors/connector-saml/package.json +++ b/packages/connectors/connector-saml/package.json @@ -6,7 +6,7 @@ "dependencies": { "@logto/connector-kit": "workspace:^3.0.0", "@silverhand/essentials": "^2.9.0", - "fast-xml-parser": "^4.2.5", + "fast-xml-parser": "^4.3.6", "got": "^14.0.0", "samlify": "2.8.11", "snakecase-keys": "^8.0.0", @@ -61,7 +61,7 @@ "@silverhand/eslint-config": "5.0.0", "@silverhand/ts-config": "5.0.0", "@types/node": "^20.11.20", - "@types/supertest": "^6.0.1", + "@types/supertest": "^6.0.2", "@vitest/coverage-v8": "^1.4.0", "eslint": "^8.44.0", "lint-staged": "^15.0.2", @@ -69,7 +69,7 @@ "prettier": "^3.0.0", "rollup": "^4.12.0", "rollup-plugin-output-size": "^1.3.0", - "supertest": "^6.2.2", + "supertest": "^6.3.4", "typescript": "^5.3.3", "vitest": "^1.4.0" } diff --git a/packages/connectors/connector-sendgrid-email/package.json b/packages/connectors/connector-sendgrid-email/package.json index b55c5182031..e8e83ddf76a 100644 --- a/packages/connectors/connector-sendgrid-email/package.json +++ b/packages/connectors/connector-sendgrid-email/package.json @@ -59,7 +59,7 @@ "@silverhand/eslint-config": "5.0.0", "@silverhand/ts-config": "5.0.0", "@types/node": "^20.11.20", - "@types/supertest": "^6.0.1", + "@types/supertest": "^6.0.2", "@vitest/coverage-v8": "^1.4.0", "eslint": "^8.44.0", "lint-staged": "^15.0.2", @@ -67,7 +67,7 @@ "prettier": "^3.0.0", "rollup": "^4.12.0", "rollup-plugin-output-size": "^1.3.0", - "supertest": "^6.2.2", + "supertest": "^6.3.4", "typescript": "^5.3.3", "vitest": "^1.4.0" } diff --git a/packages/connectors/connector-smsaero/package.json b/packages/connectors/connector-smsaero/package.json index c254991df71..d32d05ecd5f 100644 --- a/packages/connectors/connector-smsaero/package.json +++ b/packages/connectors/connector-smsaero/package.json @@ -59,7 +59,7 @@ "@silverhand/eslint-config": "5.0.0", "@silverhand/ts-config": "5.0.0", "@types/node": "^20.11.20", - "@types/supertest": "^6.0.1", + "@types/supertest": "^6.0.2", "@vitest/coverage-v8": "^1.4.0", "eslint": "^8.44.0", "lint-staged": "^15.0.2", @@ -67,7 +67,7 @@ "prettier": "^3.0.0", "rollup": "^4.12.0", "rollup-plugin-output-size": "^1.3.0", - "supertest": "^6.2.2", + "supertest": "^6.3.4", "typescript": "^5.3.3", "vitest": "^1.4.0" } diff --git a/packages/connectors/connector-smtp/package.json b/packages/connectors/connector-smtp/package.json index 1b991ee1ccf..ef3dd8052b0 100644 --- a/packages/connectors/connector-smtp/package.json +++ b/packages/connectors/connector-smtp/package.json @@ -20,7 +20,7 @@ "@silverhand/ts-config": "5.0.0", "@types/node": "^20.11.20", "@types/nodemailer": "^6.4.7", - "@types/supertest": "^6.0.1", + "@types/supertest": "^6.0.2", "@vitest/coverage-v8": "^1.4.0", "eslint": "^8.44.0", "lint-staged": "^15.0.2", @@ -28,7 +28,7 @@ "prettier": "^3.0.0", "rollup": "^4.12.0", "rollup-plugin-output-size": "^1.3.0", - "supertest": "^6.2.2", + "supertest": "^6.3.4", "typescript": "^5.3.3", "vitest": "^1.4.0" }, diff --git a/packages/connectors/connector-tencent-sms/package.json b/packages/connectors/connector-tencent-sms/package.json index 24edb6d3700..05cf7f84eb7 100644 --- a/packages/connectors/connector-tencent-sms/package.json +++ b/packages/connectors/connector-tencent-sms/package.json @@ -59,7 +59,7 @@ "@silverhand/eslint-config": "5.0.0", "@silverhand/ts-config": "5.0.0", "@types/node": "^20.11.20", - "@types/supertest": "^6.0.1", + "@types/supertest": "^6.0.2", "@vitest/coverage-v8": "^1.4.0", "eslint": "^8.44.0", "lint-staged": "^15.0.2", @@ -67,7 +67,7 @@ "prettier": "^3.0.0", "rollup": "^4.12.0", "rollup-plugin-output-size": "^1.3.0", - "supertest": "^6.2.2", + "supertest": "^6.3.4", "typescript": "^5.3.3", "vitest": "^1.4.0" } diff --git a/packages/connectors/connector-twilio-sms/package.json b/packages/connectors/connector-twilio-sms/package.json index bc4de046323..f18ec4c10f0 100644 --- a/packages/connectors/connector-twilio-sms/package.json +++ b/packages/connectors/connector-twilio-sms/package.json @@ -59,7 +59,7 @@ "@silverhand/eslint-config": "5.0.0", "@silverhand/ts-config": "5.0.0", "@types/node": "^20.11.20", - "@types/supertest": "^6.0.1", + "@types/supertest": "^6.0.2", "@vitest/coverage-v8": "^1.4.0", "eslint": "^8.44.0", "lint-staged": "^15.0.2", @@ -67,7 +67,7 @@ "prettier": "^3.0.0", "rollup": "^4.12.0", "rollup-plugin-output-size": "^1.3.0", - "supertest": "^6.2.2", + "supertest": "^6.3.4", "typescript": "^5.3.3", "vitest": "^1.4.0" } diff --git a/packages/connectors/connector-wechat-native/package.json b/packages/connectors/connector-wechat-native/package.json index 20ea1d89d71..810718cb875 100644 --- a/packages/connectors/connector-wechat-native/package.json +++ b/packages/connectors/connector-wechat-native/package.json @@ -59,7 +59,7 @@ "@silverhand/eslint-config": "5.0.0", "@silverhand/ts-config": "5.0.0", "@types/node": "^20.11.20", - "@types/supertest": "^6.0.1", + "@types/supertest": "^6.0.2", "@vitest/coverage-v8": "^1.4.0", "eslint": "^8.44.0", "lint-staged": "^15.0.2", @@ -67,7 +67,7 @@ "prettier": "^3.0.0", "rollup": "^4.12.0", "rollup-plugin-output-size": "^1.3.0", - "supertest": "^6.2.2", + "supertest": "^6.3.4", "typescript": "^5.3.3", "vitest": "^1.4.0" } diff --git a/packages/connectors/connector-wechat-web/package.json b/packages/connectors/connector-wechat-web/package.json index 1a716c698ad..9a9e375cd4a 100644 --- a/packages/connectors/connector-wechat-web/package.json +++ b/packages/connectors/connector-wechat-web/package.json @@ -59,7 +59,7 @@ "@silverhand/eslint-config": "5.0.0", "@silverhand/ts-config": "5.0.0", "@types/node": "^20.11.20", - "@types/supertest": "^6.0.1", + "@types/supertest": "^6.0.2", "@vitest/coverage-v8": "^1.4.0", "eslint": "^8.44.0", "lint-staged": "^15.0.2", @@ -67,7 +67,7 @@ "prettier": "^3.0.0", "rollup": "^4.12.0", "rollup-plugin-output-size": "^1.3.0", - "supertest": "^6.2.2", + "supertest": "^6.3.4", "typescript": "^5.3.3", "vitest": "^1.4.0" } diff --git a/packages/connectors/connector-wecom/package.json b/packages/connectors/connector-wecom/package.json index e07bba49516..1584b1dc086 100644 --- a/packages/connectors/connector-wecom/package.json +++ b/packages/connectors/connector-wecom/package.json @@ -59,7 +59,7 @@ "@silverhand/eslint-config": "5.0.0", "@silverhand/ts-config": "5.0.0", "@types/node": "^20.10.4", - "@types/supertest": "^6.0.1", + "@types/supertest": "^6.0.2", "@vitest/coverage-v8": "^1.4.0", "eslint": "^8.44.0", "lint-staged": "^15.0.2", @@ -67,7 +67,7 @@ "prettier": "^3.0.0", "rollup": "^4.12.0", "rollup-plugin-output-size": "^1.3.0", - "supertest": "^6.2.2", + "supertest": "^6.3.4", "typescript": "^5.3.3", "vitest": "^1.4.0" } diff --git a/packages/core/package.json b/packages/core/package.json index 40eaa3b2c6a..d3248f78ec3 100644 --- a/packages/core/package.json +++ b/packages/core/package.json @@ -26,9 +26,9 @@ }, "dependencies": { "@authenio/samlify-node-xmllint": "^2.0.0", - "@aws-sdk/client-s3": "^3.315.0", - "@azure/storage-blob": "^12.13.0", - "@google-cloud/storage": "^7.3.0", + "@aws-sdk/client-s3": "^3.556.0", + "@azure/storage-blob": "^12.17.0", + "@google-cloud/storage": "^7.10.0", "@koa/cors": "^5.0.0", "@logto/affiliate": "^0.1.0", "@logto/app-insights": "workspace:^1.4.0", @@ -56,7 +56,7 @@ "deepmerge": "^4.2.2", "dotenv": "^16.0.0", "etag": "^1.8.1", - "fast-xml-parser": "^4.2.5", + "fast-xml-parser": "^4.3.6", "find-up": "^7.0.0", "got": "^14.0.0", "hash-wasm": "^4.9.0", @@ -65,18 +65,18 @@ "iconv-lite": "0.6.3", "jose": "^5.0.0", "koa": "^2.13.1", - "koa-body": "^5.0.0", + "koa-body": "^6.0.1", "koa-compose": "^4.1.0", "koa-compress": "^5.1.0", "koa-logger": "^3.2.1", "koa-mount": "^4.0.0", - "koa-proxies": "^0.12.1", + "koa-proxies": "^0.12.4", "koa-router": "^12.0.0", "koa-send": "^5.0.1", "ky": "^1.2.3", "lru-cache": "^10.0.0", "nanoid": "^5.0.1", - "oidc-provider": "^8.2.2", + "oidc-provider": "^8.4.5", "openapi-types": "^12.1.3", "otplib": "^12.0.1", "p-retry": "^6.0.0", @@ -106,12 +106,12 @@ "@types/koa-send": "^4.1.3", "@types/koa__cors": "^5.0.0", "@types/node": "^20.9.5", - "@types/oidc-provider": "^8.0.0", + "@types/oidc-provider": "^8.4.4", "@types/pluralize": "^0.0.33", "@types/qrcode": "^1.5.2", "@types/semver": "^7.3.12", "@types/sinon": "^17.0.0", - "@types/supertest": "^6.0.0", + "@types/supertest": "^6.0.2", "eslint": "^8.44.0", "jest": "^29.7.0", "jest-matcher-specific-error": "^1.0.0", @@ -122,7 +122,7 @@ "nodemon": "^3.0.0", "prettier": "^3.0.0", "sinon": "^17.0.0", - "supertest": "^6.2.2", + "supertest": "^6.3.4", "typescript": "^5.3.3" }, "engines": { diff --git a/packages/core/src/include.d/koa-body.d.ts b/packages/core/src/include.d/koa-body.d.ts index 5e616b3de27..2b598d98658 100644 --- a/packages/core/src/include.d/koa-body.d.ts +++ b/packages/core/src/include.d/koa-body.d.ts @@ -1,12 +1,10 @@ declare module 'koa-body' { import type { MiddlewareType } from 'koa'; - import type { IKoaBodyOptions } from 'node_modules/koa-body'; + import type { KoaBodyMiddlewareOptions } from 'node_modules/koa-body/types'; - declare function koaBody< + export function koaBody< StateT = Record, ContextT = Record, ResponseBodyT = unknown, - >(options?: IKoaBodyOptions): MiddlewareType; - - export = koaBody; + >(options?: Partial): MiddlewareType; } diff --git a/packages/core/src/include.d/oidc-provider/index.d.ts b/packages/core/src/include.d/oidc-provider/index.d.ts index 5d315461e53..7f920b0f0df 100644 --- a/packages/core/src/include.d/oidc-provider/index.d.ts +++ b/packages/core/src/include.d/oidc-provider/index.d.ts @@ -1,9 +1,5 @@ import type { CustomClientMetadata } from '@logto/schemas'; -import Provider from 'oidc-provider'; declare module 'oidc-provider' { export interface AllClientMetadata extends CustomClientMetadata {} - - // Have to do this to make TypeScript happy since `@types/` packages are default CJS - export = Provider; } diff --git a/packages/core/src/libraries/session.ts b/packages/core/src/libraries/session.ts index 2b2ba1716b0..eaef720c9a1 100644 --- a/packages/core/src/libraries/session.ts +++ b/packages/core/src/libraries/session.ts @@ -1,6 +1,6 @@ import { conditional } from '@silverhand/essentials'; import type { Context } from 'koa'; -import type { InteractionResults } from 'oidc-provider'; +import type { InteractionResults, PromptDetail } from 'oidc-provider'; import type Provider from 'oidc-provider'; import { z } from 'zod'; @@ -64,7 +64,7 @@ const missingScopesGuard = z.object({ missingResourceScopes: z.object({}).catchall(z.string().array()).optional(), }); -export const getMissingScopes = (prompt: Provider.PromptDetail) => { +export const getMissingScopes = (prompt: PromptDetail) => { return missingScopesGuard.parse(prompt.details); }; diff --git a/packages/core/src/middleware/koa-guard.test.ts b/packages/core/src/middleware/koa-guard.test.ts index 9d30bd42a8d..c91f5341e12 100644 --- a/packages/core/src/middleware/koa-guard.test.ts +++ b/packages/core/src/middleware/koa-guard.test.ts @@ -7,9 +7,9 @@ import ServerError from '#src/errors/ServerError/index.js'; import { emptyMiddleware, createContextWithRouteParameters } from '#src/utils/test-utils.js'; const { jest } = import.meta; -const { mockEsmDefault } = createMockUtils(jest); +const { mockEsm } = createMockUtils(jest); -mockEsmDefault('koa-body', () => emptyMiddleware); +mockEsm('koa-body', () => ({ koaBody: emptyMiddleware })); const { default: koaGuard, isGuardMiddleware } = await import('./koa-guard.js'); describe('koaGuardMiddleware', () => { @@ -237,5 +237,22 @@ describe('koaGuardMiddleware', () => { expect(ctx.guard.query).toHaveProperty('foo', '2'); expect(ctx.guard.params).toHaveProperty('foo', '1'); }); + + it('should fallback to empty object when no body is provided', async () => { + const ctx = { + ...baseCtx, + request: { + ...baseCtx.request, + body: undefined, + }, + guard: { + ...defaultGuard, + body: { foo: '1' }, + }, + }; + + await koaGuard({ body: z.object({ foo: z.string().optional() }) })(ctx, next); + expect(ctx.guard.body).toEqual({}); + }); }); }); diff --git a/packages/core/src/middleware/koa-guard.ts b/packages/core/src/middleware/koa-guard.ts index 79d5bbcdcd7..3395381034b 100644 --- a/packages/core/src/middleware/koa-guard.ts +++ b/packages/core/src/middleware/koa-guard.ts @@ -2,7 +2,7 @@ import { appInsights } from '@logto/app-insights/node'; import type { Optional } from '@silverhand/essentials'; import { has } from '@silverhand/essentials'; import type { MiddlewareType } from 'koa'; -import koaBody from 'koa-body'; +import { koaBody } from 'koa-body'; import type { IMiddleware, IRouterParamContext } from 'koa-router'; import type { ZodType, ZodTypeDef } from 'zod'; @@ -155,7 +155,7 @@ export default function koaGuard< // eslint-disable-next-line @typescript-eslint/consistent-type-assertions, no-restricted-syntax ctx.guard = { query: tryParse('query', query, ctx.request.query), - body: tryParse('body', body, ctx.request.body), + body: tryParse('body', body, ctx.request.body ?? {}), // Fallback to empty object since it's the original behavior of koa-body@5 params: tryParse('params', params, ctx.params), files: tryParse('files', files, ctx.request.files), } as GuardedRequest; // Have to do this since it's too complicated for TS diff --git a/packages/core/src/oidc/defaults.ts b/packages/core/src/oidc/defaults.ts index c7388310d77..55523c3d41f 100644 --- a/packages/core/src/oidc/defaults.ts +++ b/packages/core/src/oidc/defaults.ts @@ -1,5 +1,5 @@ import type Provider from 'oidc-provider'; -import { type KoaContextWithOIDC } from 'oidc-provider'; +import type { TTLFunction, KoaContextWithOIDC } from 'oidc-provider'; /** * Keep the default pre-checks from oidc-provider. @@ -7,7 +7,7 @@ import { type KoaContextWithOIDC } from 'oidc-provider'; * @see {@link https://github.com/panva/node-oidc-provider/blob/d6edf2a0b9efc777081e6f9cc358a0677ccd9897/docs/README.md#ttl | ttl's default value} */ const refreshTokenTtl = ( - ...[ctx, token, client]: Parameters>> + ...[ctx, token, client]: Parameters>> ) => { if ( ctx.oidc.entities.RotatedRefreshToken && diff --git a/packages/core/src/oidc/grants/refresh-token.ts b/packages/core/src/oidc/grants/refresh-token.ts index ae3cc0da13f..26950a9ef27 100644 --- a/packages/core/src/oidc/grants/refresh-token.ts +++ b/packages/core/src/oidc/grants/refresh-token.ts @@ -19,6 +19,8 @@ * The commit hash of the original file is `cf2069cbb31a6a855876e95157372d25dde2511c`. */ +import { type X509Certificate } from 'node:crypto'; + import { UserScope, buildOrganizationUrn } from '@logto/core-kit'; import { type Optional, isKeyInObject, cond } from '@silverhand/essentials'; import type Provider from 'oidc-provider'; @@ -117,7 +119,7 @@ export const buildHandler: ( throw new InvalidGrant('refresh token is expired'); } - let cert: Optional; + let cert: Optional; // eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing -- the original code uses `||` if (client.tlsClientCertificateBoundAccessTokens || refreshToken['x5t#S256']) { cert = getCertificate(ctx); diff --git a/packages/core/src/oidc/init.ts b/packages/core/src/oidc/init.ts index 51e0eaa7233..faedfe5d9b0 100644 --- a/packages/core/src/oidc/init.ts +++ b/packages/core/src/oidc/init.ts @@ -17,7 +17,7 @@ import { } from '@logto/schemas'; import { conditional, trySafe, tryThat } from '@silverhand/essentials'; import i18next from 'i18next'; -import koaBody from 'koa-body'; +import { koaBody } from 'koa-body'; import Provider, { errors } from 'oidc-provider'; import snakecaseKeys from 'snakecase-keys'; diff --git a/packages/core/src/oidc/resource.ts b/packages/core/src/oidc/resource.ts index af1f0e62de9..263495de05e 100644 --- a/packages/core/src/oidc/resource.ts +++ b/packages/core/src/oidc/resource.ts @@ -1,8 +1,7 @@ import { ReservedResource } from '@logto/core-kit'; import { type Resource } from '@logto/schemas'; import { trySafe, type Nullable } from '@silverhand/essentials'; -import { type KoaContextWithOIDC } from 'oidc-provider'; -import type Provider from 'oidc-provider'; +import { type ResourceServer, type KoaContextWithOIDC } from 'oidc-provider'; import { type EnvSet } from '#src/env-set/index.js'; import type Libraries from '#src/tenants/Libraries.js'; @@ -14,7 +13,7 @@ const isReservedResource = (indicator: string): indicator is ReservedResource => export const getSharedResourceServerData = ( envSet: EnvSet -): Pick => ({ +): Pick => ({ accessTokenFormat: 'jwt', jwt: { sign: { alg: envSet.oidc.jwkSigningAlg }, diff --git a/packages/core/src/routes/callback.ts b/packages/core/src/routes/callback.ts index 6ab01e037eb..79111c876cf 100644 --- a/packages/core/src/routes/callback.ts +++ b/packages/core/src/routes/callback.ts @@ -4,22 +4,41 @@ */ import type Koa from 'koa'; -import koaBody from 'koa-body'; +import { koaBody } from 'koa-body'; import Router from 'koa-router'; +import { z } from 'zod'; import RequestError from '#src/errors/RequestError/index.js'; import assertThat from '#src/utils/assert-that.js'; +// Edited from https://stackoverflow.com/a/74743075/12514940 +function isStringRecord(object: unknown): object is Record { + if (typeof object !== 'object' || object === null) { + return false; + } + + if (Array.isArray(object)) { + return false; + } + + if (Object.getOwnPropertySymbols(object).length > 0) { + return false; + } + + return Object.getOwnPropertyNames(object).every( + // @ts-expect-error This is a type guard + (property) => typeof object[property] === 'string' + ); +} + function callbackRoutes(router: T) { router.post('/callback/:connectorId', koaBody(), async (ctx) => { - assertThat( - typeof ctx.request.body === 'object' && ctx.request.body !== null, - new RequestError('oidc.invalid_request') - ); + const parsed = z.record(z.string()).safeParse(ctx.request.body); + + assertThat(parsed.success, new RequestError('oidc.invalid_request')); ctx.status = 303; - // eslint-disable-next-line @typescript-eslint/no-unsafe-argument - ctx.set('Location', ctx.request.path + '?' + new URLSearchParams(ctx.request.body).toString()); + ctx.set('Location', ctx.request.path + '?' + new URLSearchParams(parsed.data).toString()); }); } diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 9796db70c65..162490b99c4 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -17,7 +17,7 @@ importers: version: 2.26.2 '@commitlint/cli': specifier: ^19.0.0 - version: 19.0.3(@types/node@20.11.20)(typescript@5.0.2) + version: 19.0.3(@types/node@20.12.7)(typescript@5.0.2) '@commitlint/config-conventional': specifier: ^19.0.0 version: 19.0.3 @@ -40,20 +40,20 @@ importers: packages/app-insights: dependencies: '@microsoft/applicationinsights-clickanalytics-js': - specifier: ^3.0.2 - version: 3.0.2(tslib@2.4.1)(typescript@5.3.3) + specifier: ^3.1.2 + version: 3.1.2(tslib@2.4.1) '@microsoft/applicationinsights-react-js': - specifier: ^17.0.0 - version: 17.0.0(history@5.3.0)(react@18.2.0)(tslib@2.4.1)(typescript@5.3.3) + specifier: ^17.1.2 + version: 17.1.2(history@5.3.0)(react@18.2.0)(tslib@2.4.1) '@microsoft/applicationinsights-web': - specifier: ^3.0.2 - version: 3.0.2(tslib@2.4.1)(typescript@5.3.3) + specifier: ^3.1.2 + version: 3.1.2(tslib@2.4.1) '@silverhand/essentials': specifier: ^2.9.0 version: 2.9.0 applicationinsights: - specifier: ^2.7.0 - version: 2.7.0 + specifier: ^2.9.5 + version: 2.9.5 tslib: specifier: ^2.4.1 version: 2.4.1 @@ -63,7 +63,7 @@ importers: version: 5.0.0(eslint@8.44.0)(prettier@3.0.0)(typescript@5.3.3) '@silverhand/eslint-config-react': specifier: 5.0.0 - version: 5.0.0(eslint@8.44.0)(postcss@8.4.35)(prettier@3.0.0)(stylelint@15.11.0)(typescript@5.3.3) + version: 5.0.0(eslint@8.44.0)(postcss@8.4.38)(prettier@3.0.0)(stylelint@15.11.0)(typescript@5.3.3) '@silverhand/ts-config': specifier: 5.0.0 version: 5.0.0(typescript@5.3.3) @@ -280,8 +280,8 @@ importers: specifier: ^20.11.20 version: 20.11.20 '@types/supertest': - specifier: ^6.0.1 - version: 6.0.1 + specifier: ^6.0.2 + version: 6.0.2 '@vitest/coverage-v8': specifier: ^1.4.0 version: 1.4.0(vitest@1.4.0) @@ -304,8 +304,8 @@ importers: specifier: ^1.3.0 version: 1.3.0(rollup@4.12.0) supertest: - specifier: ^6.2.2 - version: 6.2.2 + specifier: ^6.3.4 + version: 6.3.4 typescript: specifier: ^5.3.3 version: 5.3.3 @@ -362,8 +362,8 @@ importers: specifier: ^20.11.20 version: 20.11.20 '@types/supertest': - specifier: ^6.0.1 - version: 6.0.1 + specifier: ^6.0.2 + version: 6.0.2 '@vitest/coverage-v8': specifier: ^1.4.0 version: 1.4.0(vitest@1.4.0) @@ -386,8 +386,8 @@ importers: specifier: ^1.3.0 version: 1.3.0(rollup@4.12.0) supertest: - specifier: ^6.2.2 - version: 6.2.2 + specifier: ^6.3.4 + version: 6.3.4 typescript: specifier: ^5.3.3 version: 5.3.3 @@ -435,8 +435,8 @@ importers: specifier: ^20.11.20 version: 20.11.20 '@types/supertest': - specifier: ^6.0.1 - version: 6.0.1 + specifier: ^6.0.2 + version: 6.0.2 '@vitest/coverage-v8': specifier: ^1.4.0 version: 1.4.0(vitest@1.4.0) @@ -459,8 +459,8 @@ importers: specifier: ^1.3.0 version: 1.3.0(rollup@4.12.0) supertest: - specifier: ^6.2.2 - version: 6.2.2 + specifier: ^6.3.4 + version: 6.3.4 typescript: specifier: ^5.3.3 version: 5.3.3 @@ -508,8 +508,8 @@ importers: specifier: ^20.11.20 version: 20.11.20 '@types/supertest': - specifier: ^6.0.1 - version: 6.0.1 + specifier: ^6.0.2 + version: 6.0.2 '@vitest/coverage-v8': specifier: ^1.4.0 version: 1.4.0(vitest@1.4.0) @@ -532,8 +532,8 @@ importers: specifier: ^1.3.0 version: 1.3.0(rollup@4.12.0) supertest: - specifier: ^6.2.2 - version: 6.2.2 + specifier: ^6.3.4 + version: 6.3.4 typescript: specifier: ^5.3.3 version: 5.3.3 @@ -587,8 +587,8 @@ importers: specifier: ^20.11.20 version: 20.11.20 '@types/supertest': - specifier: ^6.0.1 - version: 6.0.1 + specifier: ^6.0.2 + version: 6.0.2 '@vitest/coverage-v8': specifier: ^1.4.0 version: 1.4.0(vitest@1.4.0) @@ -611,8 +611,8 @@ importers: specifier: ^1.3.0 version: 1.3.0(rollup@4.12.0) supertest: - specifier: ^6.2.2 - version: 6.2.2 + specifier: ^6.3.4 + version: 6.3.4 typescript: specifier: ^5.3.3 version: 5.3.3 @@ -666,8 +666,8 @@ importers: specifier: ^20.11.20 version: 20.11.20 '@types/supertest': - specifier: ^6.0.1 - version: 6.0.1 + specifier: ^6.0.2 + version: 6.0.2 '@vitest/coverage-v8': specifier: ^1.4.0 version: 1.4.0(vitest@1.4.0) @@ -690,8 +690,8 @@ importers: specifier: ^1.3.0 version: 1.3.0(rollup@4.12.0) supertest: - specifier: ^6.2.2 - version: 6.2.2 + specifier: ^6.3.4 + version: 6.3.4 typescript: specifier: ^5.3.3 version: 5.3.3 @@ -742,8 +742,8 @@ importers: specifier: ^20.11.20 version: 20.11.20 '@types/supertest': - specifier: ^6.0.1 - version: 6.0.1 + specifier: ^6.0.2 + version: 6.0.2 '@vitest/coverage-v8': specifier: ^1.4.0 version: 1.4.0(vitest@1.4.0) @@ -766,8 +766,8 @@ importers: specifier: ^1.3.0 version: 1.3.0(rollup@4.12.0) supertest: - specifier: ^6.2.2 - version: 6.2.2 + specifier: ^6.3.4 + version: 6.3.4 typescript: specifier: ^5.3.3 version: 5.3.3 @@ -815,8 +815,8 @@ importers: specifier: ^20.11.20 version: 20.11.20 '@types/supertest': - specifier: ^6.0.1 - version: 6.0.1 + specifier: ^6.0.2 + version: 6.0.2 '@vitest/coverage-v8': specifier: ^1.4.0 version: 1.4.0(vitest@1.4.0) @@ -839,8 +839,8 @@ importers: specifier: ^1.3.0 version: 1.3.0(rollup@4.12.0) supertest: - specifier: ^6.2.2 - version: 6.2.2 + specifier: ^6.3.4 + version: 6.3.4 typescript: specifier: ^5.3.3 version: 5.3.3 @@ -888,8 +888,8 @@ importers: specifier: ^20.11.20 version: 20.11.20 '@types/supertest': - specifier: ^6.0.1 - version: 6.0.1 + specifier: ^6.0.2 + version: 6.0.2 '@vitest/coverage-v8': specifier: ^1.4.0 version: 1.4.0(vitest@1.4.0) @@ -912,8 +912,8 @@ importers: specifier: ^1.3.0 version: 1.3.0(rollup@4.12.0) supertest: - specifier: ^6.2.2 - version: 6.2.2 + specifier: ^6.3.4 + version: 6.3.4 typescript: specifier: ^5.3.3 version: 5.3.3 @@ -961,8 +961,8 @@ importers: specifier: ^20.11.20 version: 20.11.20 '@types/supertest': - specifier: ^6.0.1 - version: 6.0.1 + specifier: ^6.0.2 + version: 6.0.2 '@vitest/coverage-v8': specifier: ^1.4.0 version: 1.4.0(vitest@1.4.0) @@ -985,8 +985,8 @@ importers: specifier: ^1.3.0 version: 1.3.0(rollup@4.12.0) supertest: - specifier: ^6.2.2 - version: 6.2.2 + specifier: ^6.3.4 + version: 6.3.4 typescript: specifier: ^5.3.3 version: 5.3.3 @@ -1037,8 +1037,8 @@ importers: specifier: ^20.11.20 version: 20.11.20 '@types/supertest': - specifier: ^6.0.1 - version: 6.0.1 + specifier: ^6.0.2 + version: 6.0.2 '@vitest/coverage-v8': specifier: ^1.4.0 version: 1.4.0(vitest@1.4.0) @@ -1061,8 +1061,8 @@ importers: specifier: ^1.3.0 version: 1.3.0(rollup@4.12.0) supertest: - specifier: ^6.2.2 - version: 6.2.2 + specifier: ^6.3.4 + version: 6.3.4 typescript: specifier: ^5.3.3 version: 5.3.3 @@ -1110,8 +1110,8 @@ importers: specifier: ^20.11.20 version: 20.11.20 '@types/supertest': - specifier: ^6.0.1 - version: 6.0.1 + specifier: ^6.0.2 + version: 6.0.2 '@vitest/coverage-v8': specifier: ^1.4.0 version: 1.4.0(vitest@1.4.0) @@ -1134,8 +1134,8 @@ importers: specifier: ^1.3.0 version: 1.3.0(rollup@4.12.0) supertest: - specifier: ^6.2.2 - version: 6.2.2 + specifier: ^6.3.4 + version: 6.3.4 typescript: specifier: ^5.3.3 version: 5.3.3 @@ -1183,8 +1183,8 @@ importers: specifier: ^20.11.20 version: 20.11.20 '@types/supertest': - specifier: ^6.0.1 - version: 6.0.1 + specifier: ^6.0.2 + version: 6.0.2 '@vitest/coverage-v8': specifier: ^1.4.0 version: 1.4.0(vitest@1.4.0) @@ -1207,8 +1207,8 @@ importers: specifier: ^1.3.0 version: 1.3.0(rollup@4.12.0) supertest: - specifier: ^6.2.2 - version: 6.2.2 + specifier: ^6.3.4 + version: 6.3.4 typescript: specifier: ^5.3.3 version: 5.3.3 @@ -1259,8 +1259,8 @@ importers: specifier: ^20.11.20 version: 20.11.20 '@types/supertest': - specifier: ^6.0.1 - version: 6.0.1 + specifier: ^6.0.2 + version: 6.0.2 '@vitest/coverage-v8': specifier: ^1.4.0 version: 1.4.0(vitest@1.4.0) @@ -1283,8 +1283,8 @@ importers: specifier: ^1.3.0 version: 1.3.0(rollup@4.12.0) supertest: - specifier: ^6.2.2 - version: 6.2.2 + specifier: ^6.3.4 + version: 6.3.4 typescript: specifier: ^5.3.3 version: 5.3.3 @@ -1332,8 +1332,8 @@ importers: specifier: ^20.11.20 version: 20.11.20 '@types/supertest': - specifier: ^6.0.1 - version: 6.0.1 + specifier: ^6.0.2 + version: 6.0.2 '@vitest/coverage-v8': specifier: ^1.4.0 version: 1.4.0(vitest@1.4.0) @@ -1356,8 +1356,8 @@ importers: specifier: ^1.3.0 version: 1.3.0(rollup@4.12.0) supertest: - specifier: ^6.2.2 - version: 6.2.2 + specifier: ^6.3.4 + version: 6.3.4 typescript: specifier: ^5.3.3 version: 5.3.3 @@ -1405,8 +1405,8 @@ importers: specifier: ^20.11.20 version: 20.11.20 '@types/supertest': - specifier: ^6.0.1 - version: 6.0.1 + specifier: ^6.0.2 + version: 6.0.2 '@vitest/coverage-v8': specifier: ^1.4.0 version: 1.4.0(vitest@1.4.0) @@ -1429,8 +1429,8 @@ importers: specifier: ^1.3.0 version: 1.3.0(rollup@4.12.0) supertest: - specifier: ^6.2.2 - version: 6.2.2 + specifier: ^6.3.4 + version: 6.3.4 typescript: specifier: ^5.3.3 version: 5.3.3 @@ -1478,8 +1478,8 @@ importers: specifier: ^20.11.20 version: 20.11.20 '@types/supertest': - specifier: ^6.0.1 - version: 6.0.1 + specifier: ^6.0.2 + version: 6.0.2 '@vitest/coverage-v8': specifier: ^1.4.0 version: 1.4.0(vitest@1.4.0) @@ -1502,8 +1502,8 @@ importers: specifier: ^1.3.0 version: 1.3.0(rollup@4.12.0) supertest: - specifier: ^6.2.2 - version: 6.2.2 + specifier: ^6.3.4 + version: 6.3.4 typescript: specifier: ^5.3.3 version: 5.3.3 @@ -1551,8 +1551,8 @@ importers: specifier: ^20.11.20 version: 20.11.20 '@types/supertest': - specifier: ^6.0.1 - version: 6.0.1 + specifier: ^6.0.2 + version: 6.0.2 '@vitest/coverage-v8': specifier: ^1.4.0 version: 1.4.0(vitest@1.4.0) @@ -1575,8 +1575,8 @@ importers: specifier: ^1.3.0 version: 1.3.0(rollup@4.12.0) supertest: - specifier: ^6.2.2 - version: 6.2.2 + specifier: ^6.3.4 + version: 6.3.4 typescript: specifier: ^5.3.3 version: 5.3.3 @@ -1624,8 +1624,8 @@ importers: specifier: ^20.11.20 version: 20.11.20 '@types/supertest': - specifier: ^6.0.1 - version: 6.0.1 + specifier: ^6.0.2 + version: 6.0.2 '@vitest/coverage-v8': specifier: ^1.4.0 version: 1.4.0(vitest@1.4.0) @@ -1648,8 +1648,8 @@ importers: specifier: ^1.3.0 version: 1.3.0(rollup@4.12.0) supertest: - specifier: ^6.2.2 - version: 6.2.2 + specifier: ^6.3.4 + version: 6.3.4 typescript: specifier: ^5.3.3 version: 5.3.3 @@ -1697,8 +1697,8 @@ importers: specifier: ^20.11.20 version: 20.11.20 '@types/supertest': - specifier: ^6.0.1 - version: 6.0.1 + specifier: ^6.0.2 + version: 6.0.2 '@vitest/coverage-v8': specifier: ^1.4.0 version: 1.4.0(vitest@1.4.0) @@ -1721,8 +1721,8 @@ importers: specifier: ^1.3.0 version: 1.3.0(rollup@4.12.0) supertest: - specifier: ^6.2.2 - version: 6.2.2 + specifier: ^6.3.4 + version: 6.3.4 typescript: specifier: ^5.3.3 version: 5.3.3 @@ -1770,8 +1770,8 @@ importers: specifier: ^20.11.20 version: 20.11.20 '@types/supertest': - specifier: ^6.0.1 - version: 6.0.1 + specifier: ^6.0.2 + version: 6.0.2 '@vitest/coverage-v8': specifier: ^1.4.0 version: 1.4.0(vitest@1.4.0) @@ -1794,8 +1794,8 @@ importers: specifier: ^1.3.0 version: 1.3.0(rollup@4.12.0) supertest: - specifier: ^6.2.2 - version: 6.2.2 + specifier: ^6.3.4 + version: 6.3.4 typescript: specifier: ^5.3.3 version: 5.3.3 @@ -1843,8 +1843,8 @@ importers: specifier: ^20.11.20 version: 20.11.20 '@types/supertest': - specifier: ^6.0.1 - version: 6.0.1 + specifier: ^6.0.2 + version: 6.0.2 '@vitest/coverage-v8': specifier: ^1.4.0 version: 1.4.0(vitest@1.4.0) @@ -1867,8 +1867,8 @@ importers: specifier: ^1.3.0 version: 1.3.0(rollup@4.12.0) supertest: - specifier: ^6.2.2 - version: 6.2.2 + specifier: ^6.3.4 + version: 6.3.4 typescript: specifier: ^5.3.3 version: 5.3.3 @@ -1919,8 +1919,8 @@ importers: specifier: ^20.11.20 version: 20.11.20 '@types/supertest': - specifier: ^6.0.1 - version: 6.0.1 + specifier: ^6.0.2 + version: 6.0.2 '@vitest/coverage-v8': specifier: ^1.4.0 version: 1.4.0(vitest@1.4.0) @@ -1943,8 +1943,8 @@ importers: specifier: ^1.3.0 version: 1.3.0(rollup@4.12.0) supertest: - specifier: ^6.2.2 - version: 6.2.2 + specifier: ^6.3.4 + version: 6.3.4 typescript: specifier: ^5.3.3 version: 5.3.3 @@ -2001,8 +2001,8 @@ importers: specifier: ^20.11.20 version: 20.11.20 '@types/supertest': - specifier: ^6.0.1 - version: 6.0.1 + specifier: ^6.0.2 + version: 6.0.2 '@vitest/coverage-v8': specifier: ^1.4.0 version: 1.4.0(vitest@1.4.0) @@ -2025,8 +2025,8 @@ importers: specifier: ^1.3.0 version: 1.3.0(rollup@4.12.0) supertest: - specifier: ^6.2.2 - version: 6.2.2 + specifier: ^6.3.4 + version: 6.3.4 typescript: specifier: ^5.3.3 version: 5.3.3 @@ -2043,8 +2043,8 @@ importers: specifier: ^2.9.0 version: 2.9.0 fast-xml-parser: - specifier: ^4.2.5 - version: 4.2.5 + specifier: ^4.3.6 + version: 4.3.6 got: specifier: ^14.0.0 version: 14.0.0 @@ -2080,8 +2080,8 @@ importers: specifier: ^20.11.20 version: 20.11.20 '@types/supertest': - specifier: ^6.0.1 - version: 6.0.1 + specifier: ^6.0.2 + version: 6.0.2 '@vitest/coverage-v8': specifier: ^1.4.0 version: 1.4.0(vitest@1.4.0) @@ -2104,8 +2104,8 @@ importers: specifier: ^1.3.0 version: 1.3.0(rollup@4.12.0) supertest: - specifier: ^6.2.2 - version: 6.2.2 + specifier: ^6.3.4 + version: 6.3.4 typescript: specifier: ^5.3.3 version: 5.3.3 @@ -2153,8 +2153,8 @@ importers: specifier: ^20.11.20 version: 20.11.20 '@types/supertest': - specifier: ^6.0.1 - version: 6.0.1 + specifier: ^6.0.2 + version: 6.0.2 '@vitest/coverage-v8': specifier: ^1.4.0 version: 1.4.0(vitest@1.4.0) @@ -2177,8 +2177,8 @@ importers: specifier: ^1.3.0 version: 1.3.0(rollup@4.12.0) supertest: - specifier: ^6.2.2 - version: 6.2.2 + specifier: ^6.3.4 + version: 6.3.4 typescript: specifier: ^5.3.3 version: 5.3.3 @@ -2226,8 +2226,8 @@ importers: specifier: ^20.11.20 version: 20.11.20 '@types/supertest': - specifier: ^6.0.1 - version: 6.0.1 + specifier: ^6.0.2 + version: 6.0.2 '@vitest/coverage-v8': specifier: ^1.4.0 version: 1.4.0(vitest@1.4.0) @@ -2250,8 +2250,8 @@ importers: specifier: ^1.3.0 version: 1.3.0(rollup@4.12.0) supertest: - specifier: ^6.2.2 - version: 6.2.2 + specifier: ^6.3.4 + version: 6.3.4 typescript: specifier: ^5.3.3 version: 5.3.3 @@ -2305,8 +2305,8 @@ importers: specifier: ^6.4.7 version: 6.4.7 '@types/supertest': - specifier: ^6.0.1 - version: 6.0.1 + specifier: ^6.0.2 + version: 6.0.2 '@vitest/coverage-v8': specifier: ^1.4.0 version: 1.4.0(vitest@1.4.0) @@ -2329,8 +2329,8 @@ importers: specifier: ^1.3.0 version: 1.3.0(rollup@4.12.0) supertest: - specifier: ^6.2.2 - version: 6.2.2 + specifier: ^6.3.4 + version: 6.3.4 typescript: specifier: ^5.3.3 version: 5.3.3 @@ -2378,8 +2378,8 @@ importers: specifier: ^20.11.20 version: 20.11.20 '@types/supertest': - specifier: ^6.0.1 - version: 6.0.1 + specifier: ^6.0.2 + version: 6.0.2 '@vitest/coverage-v8': specifier: ^1.4.0 version: 1.4.0(vitest@1.4.0) @@ -2402,8 +2402,8 @@ importers: specifier: ^1.3.0 version: 1.3.0(rollup@4.12.0) supertest: - specifier: ^6.2.2 - version: 6.2.2 + specifier: ^6.3.4 + version: 6.3.4 typescript: specifier: ^5.3.3 version: 5.3.3 @@ -2451,8 +2451,8 @@ importers: specifier: ^20.11.20 version: 20.11.20 '@types/supertest': - specifier: ^6.0.1 - version: 6.0.1 + specifier: ^6.0.2 + version: 6.0.2 '@vitest/coverage-v8': specifier: ^1.4.0 version: 1.4.0(vitest@1.4.0) @@ -2475,8 +2475,8 @@ importers: specifier: ^1.3.0 version: 1.3.0(rollup@4.12.0) supertest: - specifier: ^6.2.2 - version: 6.2.2 + specifier: ^6.3.4 + version: 6.3.4 typescript: specifier: ^5.3.3 version: 5.3.3 @@ -2524,8 +2524,8 @@ importers: specifier: ^20.11.20 version: 20.11.20 '@types/supertest': - specifier: ^6.0.1 - version: 6.0.1 + specifier: ^6.0.2 + version: 6.0.2 '@vitest/coverage-v8': specifier: ^1.4.0 version: 1.4.0(vitest@1.4.0) @@ -2548,8 +2548,8 @@ importers: specifier: ^1.3.0 version: 1.3.0(rollup@4.12.0) supertest: - specifier: ^6.2.2 - version: 6.2.2 + specifier: ^6.3.4 + version: 6.3.4 typescript: specifier: ^5.3.3 version: 5.3.3 @@ -2597,8 +2597,8 @@ importers: specifier: ^20.11.20 version: 20.11.20 '@types/supertest': - specifier: ^6.0.1 - version: 6.0.1 + specifier: ^6.0.2 + version: 6.0.2 '@vitest/coverage-v8': specifier: ^1.4.0 version: 1.4.0(vitest@1.4.0) @@ -2621,8 +2621,8 @@ importers: specifier: ^1.3.0 version: 1.3.0(rollup@4.12.0) supertest: - specifier: ^6.2.2 - version: 6.2.2 + specifier: ^6.3.4 + version: 6.3.4 typescript: specifier: ^5.3.3 version: 5.3.3 @@ -2670,8 +2670,8 @@ importers: specifier: ^20.10.4 version: 20.10.4 '@types/supertest': - specifier: ^6.0.1 - version: 6.0.1 + specifier: ^6.0.2 + version: 6.0.2 '@vitest/coverage-v8': specifier: ^1.4.0 version: 1.4.0(vitest@1.4.0) @@ -2694,8 +2694,8 @@ importers: specifier: ^1.3.0 version: 1.3.0(rollup@4.12.0) supertest: - specifier: ^6.2.2 - version: 6.2.2 + specifier: ^6.3.4 + version: 6.3.4 typescript: specifier: ^5.3.3 version: 5.3.3 @@ -2746,7 +2746,7 @@ importers: version: 1.6.22(react@18.2.0) '@monaco-editor/react': specifier: ^4.6.0 - version: 4.6.0(monaco-editor@0.46.0)(react-dom@18.2.0)(react@18.2.0) + version: 4.6.0(monaco-editor@0.47.0)(react-dom@18.2.0)(react@18.2.0) '@parcel/compressor-brotli': specifier: 2.9.3 version: 2.9.3(@parcel/core@2.9.3) @@ -2875,7 +2875,7 @@ importers: version: 3.0.0 jest: specifier: ^29.7.0 - version: 29.7.0(@types/node@20.11.20)(ts-node@10.9.2) + version: 29.7.0(@types/node@20.12.7)(ts-node@10.9.2) jest-environment-jsdom: specifier: ^29.0.0 version: 29.2.2 @@ -2941,7 +2941,7 @@ importers: version: 6.1.0(react@18.2.0) react-dnd: specifier: ^16.0.0 - version: 16.0.0(@types/node@20.11.20)(@types/react@18.0.31)(react@18.2.0) + version: 16.0.0(@types/node@20.12.7)(@types/react@18.0.31)(react@18.2.0) react-dnd-html5-backend: specifier: ^16.0.0 version: 16.0.0 @@ -2998,7 +2998,7 @@ importers: version: 4.0.0 ts-node: specifier: ^10.9.2 - version: 10.9.2(@swc/core@1.3.52)(@types/node@20.11.20)(typescript@5.3.3) + version: 10.9.2(@swc/core@1.3.52)(@types/node@20.12.7)(typescript@5.3.3) tslib: specifier: ^2.4.1 version: 2.4.1 @@ -3018,14 +3018,14 @@ importers: specifier: ^2.0.0 version: 2.0.0(samlify@2.8.11) '@aws-sdk/client-s3': - specifier: ^3.315.0 - version: 3.315.0 + specifier: ^3.556.0 + version: 3.556.0 '@azure/storage-blob': - specifier: ^12.13.0 - version: 12.13.0 + specifier: ^12.17.0 + version: 12.17.0 '@google-cloud/storage': - specifier: ^7.3.0 - version: 7.3.0 + specifier: ^7.10.0 + version: 7.10.0 '@koa/cors': specifier: ^5.0.0 version: 5.0.0 @@ -3108,8 +3108,8 @@ importers: specifier: ^1.8.1 version: 1.8.1 fast-xml-parser: - specifier: ^4.2.5 - version: 4.3.2 + specifier: ^4.3.6 + version: 4.3.6 find-up: specifier: ^7.0.0 version: 7.0.0 @@ -3135,8 +3135,8 @@ importers: specifier: ^2.13.1 version: 2.13.4 koa-body: - specifier: ^5.0.0 - version: 5.0.0 + specifier: ^6.0.1 + version: 6.0.1 koa-compose: specifier: ^4.1.0 version: 4.1.0 @@ -3150,8 +3150,8 @@ importers: specifier: ^4.0.0 version: 4.0.0 koa-proxies: - specifier: ^0.12.1 - version: 0.12.1(koa@2.13.4) + specifier: ^0.12.4 + version: 0.12.4(koa@2.13.4) koa-router: specifier: ^12.0.0 version: 12.0.0 @@ -3168,8 +3168,8 @@ importers: specifier: ^5.0.1 version: 5.0.1 oidc-provider: - specifier: ^8.2.2 - version: 8.2.2 + specifier: ^8.4.5 + version: 8.4.5 openapi-types: specifier: ^12.1.3 version: 12.1.3 @@ -3253,8 +3253,8 @@ importers: specifier: ^20.9.5 version: 20.10.4 '@types/oidc-provider': - specifier: ^8.0.0 - version: 8.0.0 + specifier: ^8.4.4 + version: 8.4.4 '@types/pluralize': specifier: ^0.0.33 version: 0.0.33 @@ -3268,8 +3268,8 @@ importers: specifier: ^17.0.0 version: 17.0.2 '@types/supertest': - specifier: ^6.0.0 - version: 6.0.1 + specifier: ^6.0.2 + version: 6.0.2 eslint: specifier: ^8.44.0 version: 8.44.0 @@ -3301,8 +3301,8 @@ importers: specifier: ^17.0.0 version: 17.0.0 supertest: - specifier: ^6.2.2 - version: 6.2.2 + specifier: ^6.3.4 + version: 6.3.4 typescript: specifier: ^5.3.3 version: 5.3.3 @@ -3530,7 +3530,7 @@ importers: version: 3.0.0 jest: specifier: ^29.7.0 - version: 29.7.0(@types/node@20.11.20) + version: 29.7.0(@types/node@20.12.7) jest-environment-jsdom: specifier: ^29.0.0 version: 29.2.2 @@ -4121,7 +4121,7 @@ packages: resolution: {integrity: sha512-IzSgsrxUcsrejQbPVilIKy16kAT52EwB6zSaI+M3xxIhKh5+aldEyvI+z6erM7TCLB2BJsFrtHjp6/4/sr+3dA==} dependencies: '@aws-crypto/util': 3.0.0 - '@aws-sdk/types': 3.310.0 + '@aws-sdk/types': 3.535.0 tslib: 1.14.1 dev: false @@ -4129,7 +4129,7 @@ packages: resolution: {integrity: sha512-ENNPPManmnVJ4BTXlOjAgD7URidbAznURqD0KvfREyc4o20DPYdEldU1f5cQ7Jbj0CJJSPaMIk/9ZshdB3210w==} dependencies: '@aws-crypto/util': 3.0.0 - '@aws-sdk/types': 3.310.0 + '@aws-sdk/types': 3.535.0 tslib: 1.14.1 dev: false @@ -4151,7 +4151,7 @@ packages: '@aws-crypto/ie11-detection': 3.0.0 '@aws-crypto/supports-web-crypto': 3.0.0 '@aws-crypto/util': 3.0.0 - '@aws-sdk/types': 3.310.0 + '@aws-sdk/types': 3.535.0 '@aws-sdk/util-locate-window': 3.295.0 '@aws-sdk/util-utf8-browser': 3.188.0 tslib: 1.14.1 @@ -4177,7 +4177,7 @@ packages: '@aws-crypto/sha256-js': 3.0.0 '@aws-crypto/supports-web-crypto': 3.0.0 '@aws-crypto/util': 3.0.0 - '@aws-sdk/types': 3.310.0 + '@aws-sdk/types': 3.535.0 '@aws-sdk/util-locate-window': 3.295.0 '@aws-sdk/util-utf8-browser': 3.188.0 tslib: 1.14.1 @@ -4195,7 +4195,7 @@ packages: resolution: {integrity: sha512-PnNN7os0+yd1XvXAy23CFOmTbMaDxgxXtTKHybrJ39Y8kGzBATgBFibWJKH6BhytLI/Zyszs87xCOBNyBig6vQ==} dependencies: '@aws-crypto/util': 3.0.0 - '@aws-sdk/types': 3.310.0 + '@aws-sdk/types': 3.535.0 tslib: 1.14.1 dev: false @@ -4222,7 +4222,7 @@ packages: /@aws-crypto/util@3.0.0: resolution: {integrity: sha512-2OJlpeJpCR48CC8r+uKVChzs9Iungj9wkZrl8Z041DWEWvyIHILYKCPNzJghKsivj+S3mLo6BVc7mBNzdxA46w==} dependencies: - '@aws-sdk/types': 3.310.0 + '@aws-sdk/types': 3.535.0 '@aws-sdk/util-utf8-browser': 3.188.0 tslib: 1.14.1 dev: false @@ -4235,80 +4235,68 @@ packages: tslib: 2.5.0 dev: false - /@aws-sdk/abort-controller@3.310.0: - resolution: {integrity: sha512-v1zrRQxDLA1MdPim159Vx/CPHqsB4uybSxRi1CnfHO5ZjHryx3a5htW2gdGAykVCul40+yJXvfpufMrELVxH+g==} - engines: {node: '>=14.0.0'} - dependencies: - '@aws-sdk/types': 3.310.0 - tslib: 2.5.0 - dev: false - - /@aws-sdk/chunked-blob-reader@3.310.0: - resolution: {integrity: sha512-CrJS3exo4mWaLnWxfCH+w88Ou0IcAZSIkk4QbmxiHl/5Dq705OLoxf4385MVyExpqpeVJYOYQ2WaD8i/pQZ2fg==} - dependencies: - tslib: 2.5.0 - dev: false - - /@aws-sdk/client-s3@3.315.0: - resolution: {integrity: sha512-sE2pCFNrhkn1XdqkHx1GEd4eKg/kITk2zHETpkQCUMAVZ1MDuY/uUZzRjbAn9sm9EsJ03Z/vOuK4DkxlLFY+8g==} + /@aws-sdk/client-s3@3.556.0: + resolution: {integrity: sha512-6WF9Kuzz1/8zqX8hKBpqj9+FYwQ5uTsVcOKpTW94AMX2qtIeVRlwlnNnYyywWo61yqD3g59CMNHcqSsaqAwglg==} engines: {node: '>=14.0.0'} dependencies: '@aws-crypto/sha1-browser': 3.0.0 '@aws-crypto/sha256-browser': 3.0.0 '@aws-crypto/sha256-js': 3.0.0 - '@aws-sdk/client-sts': 3.315.0 - '@aws-sdk/config-resolver': 3.310.0 - '@aws-sdk/credential-provider-node': 3.315.0 - '@aws-sdk/eventstream-serde-browser': 3.310.0 - '@aws-sdk/eventstream-serde-config-resolver': 3.310.0 - '@aws-sdk/eventstream-serde-node': 3.310.0 - '@aws-sdk/fetch-http-handler': 3.310.0 - '@aws-sdk/hash-blob-browser': 3.310.0 - '@aws-sdk/hash-node': 3.310.0 - '@aws-sdk/hash-stream-node': 3.310.0 - '@aws-sdk/invalid-dependency': 3.310.0 - '@aws-sdk/md5-js': 3.310.0 - '@aws-sdk/middleware-bucket-endpoint': 3.310.0 - '@aws-sdk/middleware-content-length': 3.310.0 - '@aws-sdk/middleware-endpoint': 3.310.0 - '@aws-sdk/middleware-expect-continue': 3.310.0 - '@aws-sdk/middleware-flexible-checksums': 3.310.0 - '@aws-sdk/middleware-host-header': 3.310.0 - '@aws-sdk/middleware-location-constraint': 3.310.0 - '@aws-sdk/middleware-logger': 3.310.0 - '@aws-sdk/middleware-recursion-detection': 3.310.0 - '@aws-sdk/middleware-retry': 3.310.0 - '@aws-sdk/middleware-sdk-s3': 3.310.0 - '@aws-sdk/middleware-serde': 3.310.0 - '@aws-sdk/middleware-signing': 3.310.0 - '@aws-sdk/middleware-ssec': 3.310.0 - '@aws-sdk/middleware-stack': 3.310.0 - '@aws-sdk/middleware-user-agent': 3.310.0 - '@aws-sdk/node-config-provider': 3.310.0 - '@aws-sdk/node-http-handler': 3.310.0 - '@aws-sdk/protocol-http': 3.310.0 - '@aws-sdk/signature-v4-multi-region': 3.310.0 - '@aws-sdk/smithy-client': 3.315.0 - '@aws-sdk/types': 3.310.0 - '@aws-sdk/url-parser': 3.310.0 - '@aws-sdk/util-base64': 3.310.0 - '@aws-sdk/util-body-length-browser': 3.310.0 - '@aws-sdk/util-body-length-node': 3.310.0 - '@aws-sdk/util-defaults-mode-browser': 3.315.0 - '@aws-sdk/util-defaults-mode-node': 3.315.0 - '@aws-sdk/util-endpoints': 3.310.0 - '@aws-sdk/util-retry': 3.310.0 - '@aws-sdk/util-stream-browser': 3.310.0 - '@aws-sdk/util-stream-node': 3.310.0 - '@aws-sdk/util-user-agent-browser': 3.310.0 - '@aws-sdk/util-user-agent-node': 3.310.0 - '@aws-sdk/util-utf8': 3.310.0 - '@aws-sdk/util-waiter': 3.310.0 - '@aws-sdk/xml-builder': 3.310.0 - fast-xml-parser: 4.1.2 - tslib: 2.5.0 + '@aws-sdk/client-sts': 3.556.0(@aws-sdk/credential-provider-node@3.556.0) + '@aws-sdk/core': 3.556.0 + '@aws-sdk/credential-provider-node': 3.556.0 + '@aws-sdk/middleware-bucket-endpoint': 3.535.0 + '@aws-sdk/middleware-expect-continue': 3.535.0 + '@aws-sdk/middleware-flexible-checksums': 3.535.0 + '@aws-sdk/middleware-host-header': 3.535.0 + '@aws-sdk/middleware-location-constraint': 3.535.0 + '@aws-sdk/middleware-logger': 3.535.0 + '@aws-sdk/middleware-recursion-detection': 3.535.0 + '@aws-sdk/middleware-sdk-s3': 3.556.0 + '@aws-sdk/middleware-signing': 3.556.0 + '@aws-sdk/middleware-ssec': 3.537.0 + '@aws-sdk/middleware-user-agent': 3.540.0 + '@aws-sdk/region-config-resolver': 3.535.0 + '@aws-sdk/signature-v4-multi-region': 3.556.0 + '@aws-sdk/types': 3.535.0 + '@aws-sdk/util-endpoints': 3.540.0 + '@aws-sdk/util-user-agent-browser': 3.535.0 + '@aws-sdk/util-user-agent-node': 3.535.0 + '@aws-sdk/xml-builder': 3.535.0 + '@smithy/config-resolver': 2.2.0 + '@smithy/core': 1.4.2 + '@smithy/eventstream-serde-browser': 2.2.0 + '@smithy/eventstream-serde-config-resolver': 2.2.0 + '@smithy/eventstream-serde-node': 2.2.0 + '@smithy/fetch-http-handler': 2.5.0 + '@smithy/hash-blob-browser': 2.2.0 + '@smithy/hash-node': 2.2.0 + '@smithy/hash-stream-node': 2.2.0 + '@smithy/invalid-dependency': 2.2.0 + '@smithy/md5-js': 2.2.0 + '@smithy/middleware-content-length': 2.2.0 + '@smithy/middleware-endpoint': 2.5.1 + '@smithy/middleware-retry': 2.3.1 + '@smithy/middleware-serde': 2.3.0 + '@smithy/middleware-stack': 2.2.0 + '@smithy/node-config-provider': 2.3.0 + '@smithy/node-http-handler': 2.5.0 + '@smithy/protocol-http': 3.3.0 + '@smithy/smithy-client': 2.5.1 + '@smithy/types': 2.12.0 + '@smithy/url-parser': 2.2.0 + '@smithy/util-base64': 2.3.0 + '@smithy/util-body-length-browser': 2.2.0 + '@smithy/util-body-length-node': 2.3.0 + '@smithy/util-defaults-mode-browser': 2.2.1 + '@smithy/util-defaults-mode-node': 2.3.1 + '@smithy/util-endpoints': 1.2.0 + '@smithy/util-retry': 2.2.0 + '@smithy/util-stream': 2.2.0 + '@smithy/util-utf8': 2.3.0 + '@smithy/util-waiter': 2.2.0 + tslib: 2.6.2 transitivePeerDependencies: - - '@aws-sdk/signature-v4-crt' - aws-crt dev: false @@ -4395,41 +4383,51 @@ packages: - aws-crt dev: false - /@aws-sdk/client-sso-oidc@3.315.0: - resolution: {integrity: sha512-OJgtmx6SpCWHBDCxBBi36Ro44uCqZBufGkThP/PVYrgVnRVnJ4V18d2wNGKmS37zKmCHHJPnhMPlGOgE2qyVPQ==} + /@aws-sdk/client-sso-oidc@3.556.0(@aws-sdk/credential-provider-node@3.556.0): + resolution: {integrity: sha512-AXKd2TB6nNrksu+OfmHl8uI07PdgzOo4o8AxoRO8SHlwoMAGvcT9optDGVSYoVfgOKTymCoE7h8/UoUfPc11wQ==} engines: {node: '>=14.0.0'} + peerDependencies: + '@aws-sdk/credential-provider-node': ^3.556.0 dependencies: '@aws-crypto/sha256-browser': 3.0.0 '@aws-crypto/sha256-js': 3.0.0 - '@aws-sdk/config-resolver': 3.310.0 - '@aws-sdk/fetch-http-handler': 3.310.0 - '@aws-sdk/hash-node': 3.310.0 - '@aws-sdk/invalid-dependency': 3.310.0 - '@aws-sdk/middleware-content-length': 3.310.0 - '@aws-sdk/middleware-endpoint': 3.310.0 - '@aws-sdk/middleware-host-header': 3.310.0 - '@aws-sdk/middleware-logger': 3.310.0 - '@aws-sdk/middleware-recursion-detection': 3.310.0 - '@aws-sdk/middleware-retry': 3.310.0 - '@aws-sdk/middleware-serde': 3.310.0 - '@aws-sdk/middleware-stack': 3.310.0 - '@aws-sdk/middleware-user-agent': 3.310.0 - '@aws-sdk/node-config-provider': 3.310.0 - '@aws-sdk/node-http-handler': 3.310.0 - '@aws-sdk/protocol-http': 3.310.0 - '@aws-sdk/smithy-client': 3.315.0 - '@aws-sdk/types': 3.310.0 - '@aws-sdk/url-parser': 3.310.0 - '@aws-sdk/util-base64': 3.310.0 - '@aws-sdk/util-body-length-browser': 3.310.0 - '@aws-sdk/util-body-length-node': 3.310.0 - '@aws-sdk/util-defaults-mode-browser': 3.315.0 - '@aws-sdk/util-defaults-mode-node': 3.315.0 - '@aws-sdk/util-endpoints': 3.310.0 - '@aws-sdk/util-retry': 3.310.0 - '@aws-sdk/util-user-agent-browser': 3.310.0 - '@aws-sdk/util-user-agent-node': 3.310.0 - '@aws-sdk/util-utf8': 3.310.0 + '@aws-sdk/client-sts': 3.556.0(@aws-sdk/credential-provider-node@3.556.0) + '@aws-sdk/core': 3.556.0 + '@aws-sdk/credential-provider-node': 3.556.0 + '@aws-sdk/middleware-host-header': 3.535.0 + '@aws-sdk/middleware-logger': 3.535.0 + '@aws-sdk/middleware-recursion-detection': 3.535.0 + '@aws-sdk/middleware-user-agent': 3.540.0 + '@aws-sdk/region-config-resolver': 3.535.0 + '@aws-sdk/types': 3.535.0 + '@aws-sdk/util-endpoints': 3.540.0 + '@aws-sdk/util-user-agent-browser': 3.535.0 + '@aws-sdk/util-user-agent-node': 3.535.0 + '@smithy/config-resolver': 2.2.0 + '@smithy/core': 1.4.2 + '@smithy/fetch-http-handler': 2.5.0 + '@smithy/hash-node': 2.2.0 + '@smithy/invalid-dependency': 2.2.0 + '@smithy/middleware-content-length': 2.2.0 + '@smithy/middleware-endpoint': 2.5.1 + '@smithy/middleware-retry': 2.3.1 + '@smithy/middleware-serde': 2.3.0 + '@smithy/middleware-stack': 2.2.0 + '@smithy/node-config-provider': 2.3.0 + '@smithy/node-http-handler': 2.5.0 + '@smithy/protocol-http': 3.3.0 + '@smithy/smithy-client': 2.5.1 + '@smithy/types': 2.12.0 + '@smithy/url-parser': 2.2.0 + '@smithy/util-base64': 2.3.0 + '@smithy/util-body-length-browser': 2.2.0 + '@smithy/util-body-length-node': 2.3.0 + '@smithy/util-defaults-mode-browser': 2.2.1 + '@smithy/util-defaults-mode-node': 2.3.1 + '@smithy/util-endpoints': 1.2.0 + '@smithy/util-middleware': 2.2.0 + '@smithy/util-retry': 2.2.0 + '@smithy/util-utf8': 2.3.0 tslib: 2.6.2 transitivePeerDependencies: - aws-crt @@ -4475,42 +4473,48 @@ packages: - aws-crt dev: false - /@aws-sdk/client-sso@3.315.0: - resolution: {integrity: sha512-P3QOOyHQER7EDVCzXOsAaJE2p/qfdsSFsYv8k2S8LqEKGH0fViQ4Ph540uKlmaOt1kEhwH1wI6cLRMJJX9XV4Q==} + /@aws-sdk/client-sso@3.556.0: + resolution: {integrity: sha512-unXdWS7uvHqCcOyC1de+Fr8m3F2vMg2m24GPea0bg7rVGTYmiyn9mhUX11VCt+ozydrw+F50FQwL6OqoqPocmw==} engines: {node: '>=14.0.0'} dependencies: '@aws-crypto/sha256-browser': 3.0.0 '@aws-crypto/sha256-js': 3.0.0 - '@aws-sdk/config-resolver': 3.310.0 - '@aws-sdk/fetch-http-handler': 3.310.0 - '@aws-sdk/hash-node': 3.310.0 - '@aws-sdk/invalid-dependency': 3.310.0 - '@aws-sdk/middleware-content-length': 3.310.0 - '@aws-sdk/middleware-endpoint': 3.310.0 - '@aws-sdk/middleware-host-header': 3.310.0 - '@aws-sdk/middleware-logger': 3.310.0 - '@aws-sdk/middleware-recursion-detection': 3.310.0 - '@aws-sdk/middleware-retry': 3.310.0 - '@aws-sdk/middleware-serde': 3.310.0 - '@aws-sdk/middleware-stack': 3.310.0 - '@aws-sdk/middleware-user-agent': 3.310.0 - '@aws-sdk/node-config-provider': 3.310.0 - '@aws-sdk/node-http-handler': 3.310.0 - '@aws-sdk/protocol-http': 3.310.0 - '@aws-sdk/smithy-client': 3.315.0 - '@aws-sdk/types': 3.310.0 - '@aws-sdk/url-parser': 3.310.0 - '@aws-sdk/util-base64': 3.310.0 - '@aws-sdk/util-body-length-browser': 3.310.0 - '@aws-sdk/util-body-length-node': 3.310.0 - '@aws-sdk/util-defaults-mode-browser': 3.315.0 - '@aws-sdk/util-defaults-mode-node': 3.315.0 - '@aws-sdk/util-endpoints': 3.310.0 - '@aws-sdk/util-retry': 3.310.0 - '@aws-sdk/util-user-agent-browser': 3.310.0 - '@aws-sdk/util-user-agent-node': 3.310.0 - '@aws-sdk/util-utf8': 3.310.0 - tslib: 2.5.0 + '@aws-sdk/core': 3.556.0 + '@aws-sdk/middleware-host-header': 3.535.0 + '@aws-sdk/middleware-logger': 3.535.0 + '@aws-sdk/middleware-recursion-detection': 3.535.0 + '@aws-sdk/middleware-user-agent': 3.540.0 + '@aws-sdk/region-config-resolver': 3.535.0 + '@aws-sdk/types': 3.535.0 + '@aws-sdk/util-endpoints': 3.540.0 + '@aws-sdk/util-user-agent-browser': 3.535.0 + '@aws-sdk/util-user-agent-node': 3.535.0 + '@smithy/config-resolver': 2.2.0 + '@smithy/core': 1.4.2 + '@smithy/fetch-http-handler': 2.5.0 + '@smithy/hash-node': 2.2.0 + '@smithy/invalid-dependency': 2.2.0 + '@smithy/middleware-content-length': 2.2.0 + '@smithy/middleware-endpoint': 2.5.1 + '@smithy/middleware-retry': 2.3.1 + '@smithy/middleware-serde': 2.3.0 + '@smithy/middleware-stack': 2.2.0 + '@smithy/node-config-provider': 2.3.0 + '@smithy/node-http-handler': 2.5.0 + '@smithy/protocol-http': 3.3.0 + '@smithy/smithy-client': 2.5.1 + '@smithy/types': 2.12.0 + '@smithy/url-parser': 2.2.0 + '@smithy/util-base64': 2.3.0 + '@smithy/util-body-length-browser': 2.2.0 + '@smithy/util-body-length-node': 2.3.0 + '@smithy/util-defaults-mode-browser': 2.2.1 + '@smithy/util-defaults-mode-node': 2.3.1 + '@smithy/util-endpoints': 1.2.0 + '@smithy/util-middleware': 2.2.0 + '@smithy/util-retry': 2.2.0 + '@smithy/util-utf8': 2.3.0 + tslib: 2.6.2 transitivePeerDependencies: - aws-crt dev: false @@ -4559,46 +4563,51 @@ packages: - aws-crt dev: false - /@aws-sdk/client-sts@3.315.0: - resolution: {integrity: sha512-e34plg6m0hScADIPiu5kCKoiJVXRLRiAuens+iwMse0oPUmrv41hdjgufwWGA/pcNkEGzMdVS88Z4khxB3LHBw==} + /@aws-sdk/client-sts@3.556.0(@aws-sdk/credential-provider-node@3.556.0): + resolution: {integrity: sha512-TsK3js7Suh9xEmC886aY+bv0KdLLYtzrcmVt6sJ/W6EnDXYQhBuKYFhp03NrN2+vSvMGpqJwR62DyfKe1G0QzQ==} engines: {node: '>=14.0.0'} + peerDependencies: + '@aws-sdk/credential-provider-node': ^3.556.0 dependencies: '@aws-crypto/sha256-browser': 3.0.0 '@aws-crypto/sha256-js': 3.0.0 - '@aws-sdk/config-resolver': 3.310.0 - '@aws-sdk/credential-provider-node': 3.315.0 - '@aws-sdk/fetch-http-handler': 3.310.0 - '@aws-sdk/hash-node': 3.310.0 - '@aws-sdk/invalid-dependency': 3.310.0 - '@aws-sdk/middleware-content-length': 3.310.0 - '@aws-sdk/middleware-endpoint': 3.310.0 - '@aws-sdk/middleware-host-header': 3.310.0 - '@aws-sdk/middleware-logger': 3.310.0 - '@aws-sdk/middleware-recursion-detection': 3.310.0 - '@aws-sdk/middleware-retry': 3.310.0 - '@aws-sdk/middleware-sdk-sts': 3.310.0 - '@aws-sdk/middleware-serde': 3.310.0 - '@aws-sdk/middleware-signing': 3.310.0 - '@aws-sdk/middleware-stack': 3.310.0 - '@aws-sdk/middleware-user-agent': 3.310.0 - '@aws-sdk/node-config-provider': 3.310.0 - '@aws-sdk/node-http-handler': 3.310.0 - '@aws-sdk/protocol-http': 3.310.0 - '@aws-sdk/smithy-client': 3.315.0 - '@aws-sdk/types': 3.310.0 - '@aws-sdk/url-parser': 3.310.0 - '@aws-sdk/util-base64': 3.310.0 - '@aws-sdk/util-body-length-browser': 3.310.0 - '@aws-sdk/util-body-length-node': 3.310.0 - '@aws-sdk/util-defaults-mode-browser': 3.315.0 - '@aws-sdk/util-defaults-mode-node': 3.315.0 - '@aws-sdk/util-endpoints': 3.310.0 - '@aws-sdk/util-retry': 3.310.0 - '@aws-sdk/util-user-agent-browser': 3.310.0 - '@aws-sdk/util-user-agent-node': 3.310.0 - '@aws-sdk/util-utf8': 3.310.0 - fast-xml-parser: 4.1.2 - tslib: 2.5.0 + '@aws-sdk/core': 3.556.0 + '@aws-sdk/credential-provider-node': 3.556.0 + '@aws-sdk/middleware-host-header': 3.535.0 + '@aws-sdk/middleware-logger': 3.535.0 + '@aws-sdk/middleware-recursion-detection': 3.535.0 + '@aws-sdk/middleware-user-agent': 3.540.0 + '@aws-sdk/region-config-resolver': 3.535.0 + '@aws-sdk/types': 3.535.0 + '@aws-sdk/util-endpoints': 3.540.0 + '@aws-sdk/util-user-agent-browser': 3.535.0 + '@aws-sdk/util-user-agent-node': 3.535.0 + '@smithy/config-resolver': 2.2.0 + '@smithy/core': 1.4.2 + '@smithy/fetch-http-handler': 2.5.0 + '@smithy/hash-node': 2.2.0 + '@smithy/invalid-dependency': 2.2.0 + '@smithy/middleware-content-length': 2.2.0 + '@smithy/middleware-endpoint': 2.5.1 + '@smithy/middleware-retry': 2.3.1 + '@smithy/middleware-serde': 2.3.0 + '@smithy/middleware-stack': 2.2.0 + '@smithy/node-config-provider': 2.3.0 + '@smithy/node-http-handler': 2.5.0 + '@smithy/protocol-http': 3.3.0 + '@smithy/smithy-client': 2.5.1 + '@smithy/types': 2.12.0 + '@smithy/url-parser': 2.2.0 + '@smithy/util-base64': 2.3.0 + '@smithy/util-body-length-browser': 2.2.0 + '@smithy/util-body-length-node': 2.3.0 + '@smithy/util-defaults-mode-browser': 2.2.1 + '@smithy/util-defaults-mode-node': 2.3.1 + '@smithy/util-endpoints': 1.2.0 + '@smithy/util-middleware': 2.2.0 + '@smithy/util-retry': 2.2.0 + '@smithy/util-utf8': 2.3.0 + tslib: 2.6.2 transitivePeerDependencies: - aws-crt dev: false @@ -4614,14 +4623,17 @@ packages: tslib: 2.5.0 dev: false - /@aws-sdk/config-resolver@3.310.0: - resolution: {integrity: sha512-8vsT+/50lOqfDxka9m/rRt6oxv1WuGZoP8oPMk0Dt+TxXMbAzf4+rejBgiB96wshI1k3gLokYRjSQZn+dDtT8g==} + /@aws-sdk/core@3.556.0: + resolution: {integrity: sha512-vJaSaHw2kPQlo11j/Rzuz0gk1tEaKdz+2ser0f0qZ5vwFlANjt08m/frU17ctnVKC1s58bxpctO/1P894fHLrA==} engines: {node: '>=14.0.0'} dependencies: - '@aws-sdk/types': 3.310.0 - '@aws-sdk/util-config-provider': 3.310.0 - '@aws-sdk/util-middleware': 3.310.0 - tslib: 2.5.0 + '@smithy/core': 1.4.2 + '@smithy/protocol-http': 3.3.0 + '@smithy/signature-v4': 2.3.0 + '@smithy/smithy-client': 2.5.1 + '@smithy/types': 2.12.0 + fast-xml-parser: 4.2.5 + tslib: 2.6.2 dev: false /@aws-sdk/credential-provider-env@3.224.0: @@ -4633,13 +4645,29 @@ packages: tslib: 2.5.0 dev: false - /@aws-sdk/credential-provider-env@3.310.0: - resolution: {integrity: sha512-vvIPQpI16fj95xwS7M3D48F7QhZJBnnCgB5lR+b7So+vsG9ibm1mZRVGzVpdxCvgyOhHFbvrby9aalNJmmIP1A==} + /@aws-sdk/credential-provider-env@3.535.0: + resolution: {integrity: sha512-XppwO8c0GCGSAvdzyJOhbtktSEaShg14VJKg8mpMa1XcgqzmcqqHQjtDWbx5rZheY1VdpXZhpEzJkB6LpQejpA==} engines: {node: '>=14.0.0'} dependencies: - '@aws-sdk/property-provider': 3.310.0 - '@aws-sdk/types': 3.310.0 - tslib: 2.5.0 + '@aws-sdk/types': 3.535.0 + '@smithy/property-provider': 2.2.0 + '@smithy/types': 2.12.0 + tslib: 2.6.2 + dev: false + + /@aws-sdk/credential-provider-http@3.552.0: + resolution: {integrity: sha512-vsmu7Cz1i45pFEqzVb4JcFmAmVnWFNLsGheZc8SCptlqCO5voETrZZILHYIl4cjKkSDk3pblBOf0PhyjqWW6WQ==} + engines: {node: '>=14.0.0'} + dependencies: + '@aws-sdk/types': 3.535.0 + '@smithy/fetch-http-handler': 2.5.0 + '@smithy/node-http-handler': 2.5.0 + '@smithy/property-provider': 2.2.0 + '@smithy/protocol-http': 3.3.0 + '@smithy/smithy-client': 2.5.1 + '@smithy/types': 2.12.0 + '@smithy/util-stream': 2.2.0 + tslib: 2.6.2 dev: false /@aws-sdk/credential-provider-imds@3.224.0: @@ -4653,17 +4681,6 @@ packages: tslib: 2.5.0 dev: false - /@aws-sdk/credential-provider-imds@3.310.0: - resolution: {integrity: sha512-baxK7Zp6dai5AGW01FIW27xS2KAaPUmKLIXv5SvFYsUgXXvNW55im4uG3b+2gA0F7V+hXvVBH08OEqmwW6we5w==} - engines: {node: '>=14.0.0'} - dependencies: - '@aws-sdk/node-config-provider': 3.310.0 - '@aws-sdk/property-provider': 3.310.0 - '@aws-sdk/types': 3.310.0 - '@aws-sdk/url-parser': 3.310.0 - tslib: 2.5.0 - dev: false - /@aws-sdk/credential-provider-ini@3.224.0: resolution: {integrity: sha512-YaAHoHJVspqy5f8C6EXBifMfodKXl88IHuL6eBComigTPR3s1Ed1+3AJdjA1X7SjAHfrYna/WvZEH3e8NCSzFA==} engines: {node: '>=14.0.0'} @@ -4680,20 +4697,23 @@ packages: - aws-crt dev: false - /@aws-sdk/credential-provider-ini@3.315.0: - resolution: {integrity: sha512-TZbYNbQkNgANx3KsWmJEyBsnfUBq/XKqYYc/VQf1L4eI+GMUw2eKpNV0MTsyviViy2st7W4SiSgtsvXyeVp9xg==} + /@aws-sdk/credential-provider-ini@3.556.0(@aws-sdk/credential-provider-node@3.556.0): + resolution: {integrity: sha512-0Nz4ErOlXhe3muxWYMbPwRMgfKmVbBp36BAE2uv/z5wTbfdBkcgUwaflEvlKCLUTdHzuZsQk+BFS/gVyaUeOuA==} engines: {node: '>=14.0.0'} dependencies: - '@aws-sdk/credential-provider-env': 3.310.0 - '@aws-sdk/credential-provider-imds': 3.310.0 - '@aws-sdk/credential-provider-process': 3.310.0 - '@aws-sdk/credential-provider-sso': 3.315.0 - '@aws-sdk/credential-provider-web-identity': 3.310.0 - '@aws-sdk/property-provider': 3.310.0 - '@aws-sdk/shared-ini-file-loader': 3.310.0 - '@aws-sdk/types': 3.310.0 - tslib: 2.5.0 + '@aws-sdk/client-sts': 3.556.0(@aws-sdk/credential-provider-node@3.556.0) + '@aws-sdk/credential-provider-env': 3.535.0 + '@aws-sdk/credential-provider-process': 3.535.0 + '@aws-sdk/credential-provider-sso': 3.556.0(@aws-sdk/credential-provider-node@3.556.0) + '@aws-sdk/credential-provider-web-identity': 3.556.0(@aws-sdk/credential-provider-node@3.556.0) + '@aws-sdk/types': 3.535.0 + '@smithy/credential-provider-imds': 2.3.0 + '@smithy/property-provider': 2.2.0 + '@smithy/shared-ini-file-loader': 2.4.0 + '@smithy/types': 2.12.0 + tslib: 2.6.2 transitivePeerDependencies: + - '@aws-sdk/credential-provider-node' - aws-crt dev: false @@ -4715,20 +4735,22 @@ packages: - aws-crt dev: false - /@aws-sdk/credential-provider-node@3.315.0: - resolution: {integrity: sha512-OuzKAIg+xPAzBrb/Big5VKDpJmBhVR+N0Hfflrjj2BunQGWO7zxtkKFCz921MtP9ZunDV+UxzTpar8U5TAPtzA==} + /@aws-sdk/credential-provider-node@3.556.0: + resolution: {integrity: sha512-s1xVtKjyGc60O8qcNIzS1X3H+pWEwEfZ7TgNznVDNyuXvLrlNWiAcigPWGl2aAkc8tGcsSG0Qpyw2KYC939LFg==} engines: {node: '>=14.0.0'} dependencies: - '@aws-sdk/credential-provider-env': 3.310.0 - '@aws-sdk/credential-provider-imds': 3.310.0 - '@aws-sdk/credential-provider-ini': 3.315.0 - '@aws-sdk/credential-provider-process': 3.310.0 - '@aws-sdk/credential-provider-sso': 3.315.0 - '@aws-sdk/credential-provider-web-identity': 3.310.0 - '@aws-sdk/property-provider': 3.310.0 - '@aws-sdk/shared-ini-file-loader': 3.310.0 - '@aws-sdk/types': 3.310.0 - tslib: 2.5.0 + '@aws-sdk/credential-provider-env': 3.535.0 + '@aws-sdk/credential-provider-http': 3.552.0 + '@aws-sdk/credential-provider-ini': 3.556.0(@aws-sdk/credential-provider-node@3.556.0) + '@aws-sdk/credential-provider-process': 3.535.0 + '@aws-sdk/credential-provider-sso': 3.556.0(@aws-sdk/credential-provider-node@3.556.0) + '@aws-sdk/credential-provider-web-identity': 3.556.0(@aws-sdk/credential-provider-node@3.556.0) + '@aws-sdk/types': 3.535.0 + '@smithy/credential-provider-imds': 2.3.0 + '@smithy/property-provider': 2.2.0 + '@smithy/shared-ini-file-loader': 2.4.0 + '@smithy/types': 2.12.0 + tslib: 2.6.2 transitivePeerDependencies: - aws-crt dev: false @@ -4743,14 +4765,15 @@ packages: tslib: 2.5.0 dev: false - /@aws-sdk/credential-provider-process@3.310.0: - resolution: {integrity: sha512-h73sg6GPMUWC+3zMCbA1nZ2O03nNJt7G96JdmnantiXBwHpRKWW8nBTLzx5uhXn6hTuTaoQRP/P+oxQJKYdMmA==} + /@aws-sdk/credential-provider-process@3.535.0: + resolution: {integrity: sha512-9O1OaprGCnlb/kYl8RwmH7Mlg8JREZctB8r9sa1KhSsWFq/SWO0AuJTyowxD7zL5PkeS4eTvzFFHWCa3OO5epA==} engines: {node: '>=14.0.0'} dependencies: - '@aws-sdk/property-provider': 3.310.0 - '@aws-sdk/shared-ini-file-loader': 3.310.0 - '@aws-sdk/types': 3.310.0 - tslib: 2.5.0 + '@aws-sdk/types': 3.535.0 + '@smithy/property-provider': 2.2.0 + '@smithy/shared-ini-file-loader': 2.4.0 + '@smithy/types': 2.12.0 + tslib: 2.6.2 dev: false /@aws-sdk/credential-provider-sso@3.224.0: @@ -4767,17 +4790,19 @@ packages: - aws-crt dev: false - /@aws-sdk/credential-provider-sso@3.315.0: - resolution: {integrity: sha512-oMDGwT67cLgLiLEj5UwAiOVo7mb0l4vi2nk+5pgPMpC3cBlAfA0y1IJe4FHp+Vz52F0nvURZZbdWhX6RgMMaqQ==} + /@aws-sdk/credential-provider-sso@3.556.0(@aws-sdk/credential-provider-node@3.556.0): + resolution: {integrity: sha512-ETuBgcnpfxqadEAqhQFWpKoV1C/NAgvs5CbBc5EJbelJ8f4prTdErIHjrRtVT8c02MXj92QwczsiNYd5IoOqyw==} engines: {node: '>=14.0.0'} dependencies: - '@aws-sdk/client-sso': 3.315.0 - '@aws-sdk/property-provider': 3.310.0 - '@aws-sdk/shared-ini-file-loader': 3.310.0 - '@aws-sdk/token-providers': 3.315.0 - '@aws-sdk/types': 3.310.0 - tslib: 2.5.0 + '@aws-sdk/client-sso': 3.556.0 + '@aws-sdk/token-providers': 3.556.0(@aws-sdk/credential-provider-node@3.556.0) + '@aws-sdk/types': 3.535.0 + '@smithy/property-provider': 2.2.0 + '@smithy/shared-ini-file-loader': 2.4.0 + '@smithy/types': 2.12.0 + tslib: 2.6.2 transitivePeerDependencies: + - '@aws-sdk/credential-provider-node' - aws-crt dev: false @@ -4790,57 +4815,18 @@ packages: tslib: 2.5.0 dev: false - /@aws-sdk/credential-provider-web-identity@3.310.0: - resolution: {integrity: sha512-H4SzuZXILNhK6/IR1uVvsUDZvzc051hem7GLyYghBCu8mU+tq28YhKE8MfSroi6eL2e5Vujloij1OM2EQQkPkw==} - engines: {node: '>=14.0.0'} - dependencies: - '@aws-sdk/property-provider': 3.310.0 - '@aws-sdk/types': 3.310.0 - tslib: 2.5.0 - dev: false - - /@aws-sdk/eventstream-codec@3.310.0: - resolution: {integrity: sha512-clIeSgWbZbxwtsxZ/yoedNM0/kJFSIjjHPikuDGhxhqc+vP6TN3oYyVMFrYwFaTFhk2+S5wZcWYMw8Op1pWo+A==} - dependencies: - '@aws-crypto/crc32': 3.0.0 - '@aws-sdk/types': 3.310.0 - '@aws-sdk/util-hex-encoding': 3.310.0 - tslib: 2.5.0 - dev: false - - /@aws-sdk/eventstream-serde-browser@3.310.0: - resolution: {integrity: sha512-3S6ziuQVALgEyz0TANGtYDVeG8ArK4Y05mcgrs8qUTmsvlDIXX37cR/DvmVbNB76M4IrsZeSAIajL9644CywkA==} - engines: {node: '>=14.0.0'} - dependencies: - '@aws-sdk/eventstream-serde-universal': 3.310.0 - '@aws-sdk/types': 3.310.0 - tslib: 2.5.0 - dev: false - - /@aws-sdk/eventstream-serde-config-resolver@3.310.0: - resolution: {integrity: sha512-8s1Qdn9STj+sV75nUp9yt0W6fHS4BZ2jTm4Z/1Pcbvh2Gqs0WjH5n2StS+pDW5Y9J/HSGBl0ogmUr5lC5bXFHg==} - engines: {node: '>=14.0.0'} - dependencies: - '@aws-sdk/types': 3.310.0 - tslib: 2.5.0 - dev: false - - /@aws-sdk/eventstream-serde-node@3.310.0: - resolution: {integrity: sha512-kSnRomCgW43K9TmQYuwN9+AoYPnhyOKroanUMyZEzJk7rpCPMj4OzaUpXfDYOvznFNYn7NLaH6nHLJAr0VPlJA==} - engines: {node: '>=14.0.0'} - dependencies: - '@aws-sdk/eventstream-serde-universal': 3.310.0 - '@aws-sdk/types': 3.310.0 - tslib: 2.5.0 - dev: false - - /@aws-sdk/eventstream-serde-universal@3.310.0: - resolution: {integrity: sha512-Qyjt5k/waV5cDukpgT824ISZAz5U0pwzLz5ztR409u85AGNkF/9n7MS+LSyBUBSb0WJ5pUeSD47WBk+nLq9Nhw==} + /@aws-sdk/credential-provider-web-identity@3.556.0(@aws-sdk/credential-provider-node@3.556.0): + resolution: {integrity: sha512-R/YAL8Uh8i+dzVjzMnbcWLIGeeRi2mioHVGnVF+minmaIkCiQMZg2HPrdlKm49El+RljT28Nl5YHRuiqzEIwMA==} engines: {node: '>=14.0.0'} dependencies: - '@aws-sdk/eventstream-codec': 3.310.0 - '@aws-sdk/types': 3.310.0 - tslib: 2.5.0 + '@aws-sdk/client-sts': 3.556.0(@aws-sdk/credential-provider-node@3.556.0) + '@aws-sdk/types': 3.535.0 + '@smithy/property-provider': 2.2.0 + '@smithy/types': 2.12.0 + tslib: 2.6.2 + transitivePeerDependencies: + - '@aws-sdk/credential-provider-node' + - aws-crt dev: false /@aws-sdk/fetch-http-handler@3.224.0: @@ -4853,24 +4839,6 @@ packages: tslib: 2.5.0 dev: false - /@aws-sdk/fetch-http-handler@3.310.0: - resolution: {integrity: sha512-Bi9vIwzdkw1zMcvi/zGzlWS9KfIEnAq4NNhsnCxbQ4OoIRU9wvU+WGZdBBhxg0ZxZmpp1j1aZhU53lLjA07MHw==} - dependencies: - '@aws-sdk/protocol-http': 3.310.0 - '@aws-sdk/querystring-builder': 3.310.0 - '@aws-sdk/types': 3.310.0 - '@aws-sdk/util-base64': 3.310.0 - tslib: 2.5.0 - dev: false - - /@aws-sdk/hash-blob-browser@3.310.0: - resolution: {integrity: sha512-OoR8p0cbypToysLT0v3o2oyjy6+DKrY7GNCAzHOHJK9xmqXCt+DsjKoPeiY7o1sWX2aN6Plmvubj/zWxMKEn/A==} - dependencies: - '@aws-sdk/chunked-blob-reader': 3.310.0 - '@aws-sdk/types': 3.310.0 - tslib: 2.5.0 - dev: false - /@aws-sdk/hash-node@3.224.0: resolution: {integrity: sha512-y7TXMDOSy5E2VZPvmsvRfyXkcQWcjTLFTd85yc70AAeFZiffff1nvZifQSzD78bW6ELJsWHXA2O8yxdBURyoBg==} engines: {node: '>=14.0.0'} @@ -4880,25 +4848,6 @@ packages: tslib: 2.5.0 dev: false - /@aws-sdk/hash-node@3.310.0: - resolution: {integrity: sha512-NvE2fhRc8GRwCXBfDehxVAWCmVwVMILliAKVPAEr4yz2CkYs0tqU51S48x23dtna07H4qHtgpeNqVTthcIQOEQ==} - engines: {node: '>=14.0.0'} - dependencies: - '@aws-sdk/types': 3.310.0 - '@aws-sdk/util-buffer-from': 3.310.0 - '@aws-sdk/util-utf8': 3.310.0 - tslib: 2.5.0 - dev: false - - /@aws-sdk/hash-stream-node@3.310.0: - resolution: {integrity: sha512-ZoXdybNgvMz1Hl6k/e32xVL3jmG5p2IEk5mTtLfFEuskTJ74Z+VMYKkkF1whyy7KQfH83H+TQGnsGtlRCchQKw==} - engines: {node: '>=14.0.0'} - dependencies: - '@aws-sdk/types': 3.310.0 - '@aws-sdk/util-utf8': 3.310.0 - tslib: 2.5.0 - dev: false - /@aws-sdk/invalid-dependency@3.224.0: resolution: {integrity: sha512-6huV8LBYQYx84uMhQ2SS7nqEkhTkAufwhKceXnysrcrLDuUmyth09Y7fcFblFIDTr4wTgSI0mf6DKVF4nqYCwQ==} dependencies: @@ -4906,13 +4855,6 @@ packages: tslib: 2.5.0 dev: false - /@aws-sdk/invalid-dependency@3.310.0: - resolution: {integrity: sha512-1s5RG5rSPXoa/aZ/Kqr5U/7lqpx+Ry81GprQ2bxWqJvWQIJ0IRUwo5pk8XFxbKVr/2a+4lZT/c3OGoBOM1yRRA==} - dependencies: - '@aws-sdk/types': 3.310.0 - tslib: 2.5.0 - dev: false - /@aws-sdk/is-array-buffer@3.201.0: resolution: {integrity: sha512-UPez5qLh3dNgt0DYnPD/q0mVJY84rA17QE26hVNOW3fAji8W2wrwrxdacWOxyXvlxWsVRcKmr+lay1MDqpAMfg==} engines: {node: '>=14.0.0'} @@ -4920,30 +4862,17 @@ packages: tslib: 2.5.0 dev: false - /@aws-sdk/is-array-buffer@3.310.0: - resolution: {integrity: sha512-urnbcCR+h9NWUnmOtet/s4ghvzsidFmspfhYaHAmSRdy9yDjdjBJMFjjsn85A1ODUktztm+cVncXjQ38WCMjMQ==} - engines: {node: '>=14.0.0'} - dependencies: - tslib: 2.5.0 - dev: false - - /@aws-sdk/md5-js@3.310.0: - resolution: {integrity: sha512-x5sRBUrEfLWAS1EhwbbDQ7cXq6uvBxh3qR2XAsnGvFFceTeAadk7cVogWxlk3PC+OCeeym7c3/6Bv2HQ2f1YyQ==} - dependencies: - '@aws-sdk/types': 3.310.0 - '@aws-sdk/util-utf8': 3.310.0 - tslib: 2.5.0 - dev: false - - /@aws-sdk/middleware-bucket-endpoint@3.310.0: - resolution: {integrity: sha512-uJJfHI7v4AgbJZRLtyI8ap2QRWkBokGc3iyUoQ+dVNT3/CE2ZCu694A6W+H0dRqg79dIE+f9CRNdtLGa/Ehhvg==} + /@aws-sdk/middleware-bucket-endpoint@3.535.0: + resolution: {integrity: sha512-7sijlfQsc4UO9Fsl11mU26Y5f9E7g6UoNg/iJUBpC5pgvvmdBRO5UEhbB/gnqvOEPsBXyhmfzbstebq23Qdz7A==} engines: {node: '>=14.0.0'} dependencies: - '@aws-sdk/protocol-http': 3.310.0 - '@aws-sdk/types': 3.310.0 - '@aws-sdk/util-arn-parser': 3.310.0 - '@aws-sdk/util-config-provider': 3.310.0 - tslib: 2.5.0 + '@aws-sdk/types': 3.535.0 + '@aws-sdk/util-arn-parser': 3.535.0 + '@smithy/node-config-provider': 2.3.0 + '@smithy/protocol-http': 3.3.0 + '@smithy/types': 2.12.0 + '@smithy/util-config-provider': 2.3.0 + tslib: 2.6.2 dev: false /@aws-sdk/middleware-content-length@3.224.0: @@ -4955,15 +4884,6 @@ packages: tslib: 2.5.0 dev: false - /@aws-sdk/middleware-content-length@3.310.0: - resolution: {integrity: sha512-P8tQZxgDt6CAh1wd/W6WPzjc+uWPJwQkm+F7rAwRlM+k9q17HrhnksGDKcpuuLyIhPQYdmOMIkpKVgXGa4avhQ==} - engines: {node: '>=14.0.0'} - dependencies: - '@aws-sdk/protocol-http': 3.310.0 - '@aws-sdk/types': 3.310.0 - tslib: 2.5.0 - dev: false - /@aws-sdk/middleware-endpoint@3.224.0: resolution: {integrity: sha512-Y+FkQmRyhQUX1E1tviodFwTrfAVjgteoALkFgIb7bxT7fmyQ/AQvdAytkDqIApTgkR61niNDSsAu7lHekDxQgg==} engines: {node: '>=14.0.0'} @@ -4978,37 +4898,28 @@ packages: tslib: 2.5.0 dev: false - /@aws-sdk/middleware-endpoint@3.310.0: - resolution: {integrity: sha512-Z+N2vOL8K354/lstkClxLLsr6hCpVRh+0tCMXrVj66/NtKysCEZ/0b9LmqOwD9pWHNiI2mJqXwY0gxNlKAroUg==} - engines: {node: '>=14.0.0'} - dependencies: - '@aws-sdk/middleware-serde': 3.310.0 - '@aws-sdk/types': 3.310.0 - '@aws-sdk/url-parser': 3.310.0 - '@aws-sdk/util-middleware': 3.310.0 - tslib: 2.5.0 - dev: false - - /@aws-sdk/middleware-expect-continue@3.310.0: - resolution: {integrity: sha512-l3d1z2gt+gINJDnPSyu84IxfzjzPfCQrqC1sunw2cZGo/sXtEiq698Q3SiTcO2PGP4LBQAy2RHb5wVBJP708CQ==} + /@aws-sdk/middleware-expect-continue@3.535.0: + resolution: {integrity: sha512-hFKyqUBky0NWCVku8iZ9+PACehx0p6vuMw5YnZf8FVgHP0fode0b/NwQY6UY7oor/GftvRsAlRUAWGNFEGUpwA==} engines: {node: '>=14.0.0'} dependencies: - '@aws-sdk/protocol-http': 3.310.0 - '@aws-sdk/types': 3.310.0 - tslib: 2.5.0 + '@aws-sdk/types': 3.535.0 + '@smithy/protocol-http': 3.3.0 + '@smithy/types': 2.12.0 + tslib: 2.6.2 dev: false - /@aws-sdk/middleware-flexible-checksums@3.310.0: - resolution: {integrity: sha512-5ndnLgzgGVpWkmHBAiYkagHqiSuow8q62J4J6E2PzaQ77+fm8W3nfdy7hK5trHokEyouCZdxT/XK/IRhgj/4PA==} + /@aws-sdk/middleware-flexible-checksums@3.535.0: + resolution: {integrity: sha512-rBIzldY9jjRATxICDX7t77aW6ctqmVDgnuAOgbVT5xgHftt4o7PGWKoMvl/45hYqoQgxVFnCBof9bxkqSBebVA==} engines: {node: '>=14.0.0'} dependencies: '@aws-crypto/crc32': 3.0.0 '@aws-crypto/crc32c': 3.0.0 - '@aws-sdk/is-array-buffer': 3.310.0 - '@aws-sdk/protocol-http': 3.310.0 - '@aws-sdk/types': 3.310.0 - '@aws-sdk/util-utf8': 3.310.0 - tslib: 2.5.0 + '@aws-sdk/types': 3.535.0 + '@smithy/is-array-buffer': 2.2.0 + '@smithy/protocol-http': 3.3.0 + '@smithy/types': 2.12.0 + '@smithy/util-utf8': 2.3.0 + tslib: 2.6.2 dev: false /@aws-sdk/middleware-host-header@3.224.0: @@ -5020,21 +4931,23 @@ packages: tslib: 2.5.0 dev: false - /@aws-sdk/middleware-host-header@3.310.0: - resolution: {integrity: sha512-QWSA+46/hXorXyWa61ic2K7qZzwHTiwfk2e9mRRjeIRepUgI3qxFjsYqrWtrOGBjmFmq0pYIY8Bb/DCJuQqcoA==} + /@aws-sdk/middleware-host-header@3.535.0: + resolution: {integrity: sha512-0h6TWjBWtDaYwHMQJI9ulafeS4lLaw1vIxRjbpH0svFRt6Eve+Sy8NlVhECfTU2hNz/fLubvrUxsXoThaLBIew==} engines: {node: '>=14.0.0'} dependencies: - '@aws-sdk/protocol-http': 3.310.0 - '@aws-sdk/types': 3.310.0 - tslib: 2.5.0 + '@aws-sdk/types': 3.535.0 + '@smithy/protocol-http': 3.3.0 + '@smithy/types': 2.12.0 + tslib: 2.6.2 dev: false - /@aws-sdk/middleware-location-constraint@3.310.0: - resolution: {integrity: sha512-LFm0JTQWwTPWL/tZU2wsQTl8J5PpDEkXjEhaXVKamtyH0xhysRqd+0n92n65dc8oztAuQkb9xUbErGn5b6gsew==} + /@aws-sdk/middleware-location-constraint@3.535.0: + resolution: {integrity: sha512-SxfS9wfidUZZ+WnlKRTCRn3h+XTsymXRXPJj8VV6hNRNeOwzNweoG3YhQbTowuuNfXf89m9v6meYkBBtkdacKw==} engines: {node: '>=14.0.0'} dependencies: - '@aws-sdk/types': 3.310.0 - tslib: 2.5.0 + '@aws-sdk/types': 3.535.0 + '@smithy/types': 2.12.0 + tslib: 2.6.2 dev: false /@aws-sdk/middleware-logger@3.224.0: @@ -5045,12 +4958,13 @@ packages: tslib: 2.5.0 dev: false - /@aws-sdk/middleware-logger@3.310.0: - resolution: {integrity: sha512-Lurm8XofrASBRnAVtiSNuDSRsRqPNg27RIFLLsLp/pqog9nFJ0vz0kgdb9S5Z+zw83Mm+UlqOe6D8NTUNp4fVg==} + /@aws-sdk/middleware-logger@3.535.0: + resolution: {integrity: sha512-huNHpONOrEDrdRTvSQr1cJiRMNf0S52NDXtaPzdxiubTkP+vni2MohmZANMOai/qT0olmEVX01LhZ0ZAOgmg6A==} engines: {node: '>=14.0.0'} dependencies: - '@aws-sdk/types': 3.310.0 - tslib: 2.5.0 + '@aws-sdk/types': 3.535.0 + '@smithy/types': 2.12.0 + tslib: 2.6.2 dev: false /@aws-sdk/middleware-recursion-detection@3.224.0: @@ -5062,13 +4976,14 @@ packages: tslib: 2.5.0 dev: false - /@aws-sdk/middleware-recursion-detection@3.310.0: - resolution: {integrity: sha512-SuB75/xk/gyue24gkriTwO2jFd7YcUGZDClQYuRejgbXSa3CO0lWyawQtfLcSSEBp9izrEVXuFH24K1eAft5nQ==} + /@aws-sdk/middleware-recursion-detection@3.535.0: + resolution: {integrity: sha512-am2qgGs+gwqmR4wHLWpzlZ8PWhm4ktj5bYSgDrsOfjhdBlWNxvPoID9/pDAz5RWL48+oH7I6SQzMqxXsFDikrw==} engines: {node: '>=14.0.0'} dependencies: - '@aws-sdk/protocol-http': 3.310.0 - '@aws-sdk/types': 3.310.0 - tslib: 2.5.0 + '@aws-sdk/types': 3.535.0 + '@smithy/protocol-http': 3.3.0 + '@smithy/types': 2.12.0 + tslib: 2.6.2 dev: false /@aws-sdk/middleware-retry@3.224.0: @@ -5083,27 +4998,19 @@ packages: uuid: 8.3.2 dev: false - /@aws-sdk/middleware-retry@3.310.0: - resolution: {integrity: sha512-oTPsRy2W4s+dfxbJPW7Km+hHtv/OMsNsVfThAq8DDYKC13qlr1aAyOqGLD+dpBy2aKe7ss517Sy2HcHtHqm7/g==} - engines: {node: '>=14.0.0'} - dependencies: - '@aws-sdk/protocol-http': 3.310.0 - '@aws-sdk/service-error-classification': 3.310.0 - '@aws-sdk/types': 3.310.0 - '@aws-sdk/util-middleware': 3.310.0 - '@aws-sdk/util-retry': 3.310.0 - tslib: 2.5.0 - uuid: 8.3.2 - dev: false - - /@aws-sdk/middleware-sdk-s3@3.310.0: - resolution: {integrity: sha512-QK9x9g2ksg0hOjjYgqddeFcn5ctUEGdxJVu4OumPXceulefMcSO2jyH2qTybYSA93nqNQFdFmg5wQfvIRUWFCQ==} + /@aws-sdk/middleware-sdk-s3@3.556.0: + resolution: {integrity: sha512-4W/dnxqj1B6/uS/5Z+3UHaqDDGjNPgEVlqf5d3ToOFZ31ZfpANwhcCmyX39JklC4aolCEi9renQ5wHnTCC8K8g==} engines: {node: '>=14.0.0'} dependencies: - '@aws-sdk/protocol-http': 3.310.0 - '@aws-sdk/types': 3.310.0 - '@aws-sdk/util-arn-parser': 3.310.0 - tslib: 2.5.0 + '@aws-sdk/types': 3.535.0 + '@aws-sdk/util-arn-parser': 3.535.0 + '@smithy/node-config-provider': 2.3.0 + '@smithy/protocol-http': 3.3.0 + '@smithy/signature-v4': 2.3.0 + '@smithy/smithy-client': 2.5.1 + '@smithy/types': 2.12.0 + '@smithy/util-config-provider': 2.3.0 + tslib: 2.6.2 dev: false /@aws-sdk/middleware-sdk-sts@3.224.0: @@ -5118,15 +5025,6 @@ packages: tslib: 2.5.0 dev: false - /@aws-sdk/middleware-sdk-sts@3.310.0: - resolution: {integrity: sha512-+5PFwlYNLvLLIfw0ASAoWV/iIF8Zv6R6QGtyP0CclhRSvNjgbQDVnV0g95MC5qvh+GB/Yjlkt8qAjLSPjHfsrQ==} - engines: {node: '>=14.0.0'} - dependencies: - '@aws-sdk/middleware-signing': 3.310.0 - '@aws-sdk/types': 3.310.0 - tslib: 2.5.0 - dev: false - /@aws-sdk/middleware-serde@3.224.0: resolution: {integrity: sha512-4wHJ4DyhvyqQ853zfIw6sRw909VB+hFEqatmXYvO5OYap03Eed92wslsR2Gtfw1B2/zjDscPpwPyHoCIk30sHA==} engines: {node: '>=14.0.0'} @@ -5135,16 +5033,8 @@ packages: tslib: 2.5.0 dev: false - /@aws-sdk/middleware-serde@3.310.0: - resolution: {integrity: sha512-RNeeTVWSLTaentUeCgQKZhAl+C6hxtwD78cQWS10UymWpQFwbaxztzKUu4UQS5xA2j6PxwPRRUjqa4jcFjfLsg==} - engines: {node: '>=14.0.0'} - dependencies: - '@aws-sdk/types': 3.310.0 - tslib: 2.5.0 - dev: false - - /@aws-sdk/middleware-signing@3.224.0: - resolution: {integrity: sha512-6T+dybVn5EYsxkNc4eVKAeoj6x6FfRXkZWMRxkepDoOJufMUNTfpoDEl6PcgJU6Wq4odbqV737x/3j53VZc6dA==} + /@aws-sdk/middleware-signing@3.224.0: + resolution: {integrity: sha512-6T+dybVn5EYsxkNc4eVKAeoj6x6FfRXkZWMRxkepDoOJufMUNTfpoDEl6PcgJU6Wq4odbqV737x/3j53VZc6dA==} engines: {node: '>=14.0.0'} dependencies: '@aws-sdk/property-provider': 3.224.0 @@ -5155,24 +5045,26 @@ packages: tslib: 2.5.0 dev: false - /@aws-sdk/middleware-signing@3.310.0: - resolution: {integrity: sha512-f9mKq+XMdW207Af3hKjdTnpNhdtwqWuvFs/ZyXoOkp/g1MY1O6L23Jy6i52m29LxbT4AuNRG1oKODfXM0vYVjQ==} + /@aws-sdk/middleware-signing@3.556.0: + resolution: {integrity: sha512-kWrPmU8qd3gI5qzpuW9LtWFaH80cOz1ZJDavXx6PRpYZJ5JaKdUHghwfDlVTzzFYAeJmVsWIkPcLT5d5mY5ZTQ==} engines: {node: '>=14.0.0'} dependencies: - '@aws-sdk/property-provider': 3.310.0 - '@aws-sdk/protocol-http': 3.310.0 - '@aws-sdk/signature-v4': 3.310.0 - '@aws-sdk/types': 3.310.0 - '@aws-sdk/util-middleware': 3.310.0 - tslib: 2.5.0 + '@aws-sdk/types': 3.535.0 + '@smithy/property-provider': 2.2.0 + '@smithy/protocol-http': 3.3.0 + '@smithy/signature-v4': 2.3.0 + '@smithy/types': 2.12.0 + '@smithy/util-middleware': 2.2.0 + tslib: 2.6.2 dev: false - /@aws-sdk/middleware-ssec@3.310.0: - resolution: {integrity: sha512-CnEwNKVpd5bXnrCKPaePF8mWTA9ET21OMBb54y9b0fd8K02zoOcdBz4DWfh1SjFD4HkgCdja4egd8l2ivyvqmw==} + /@aws-sdk/middleware-ssec@3.537.0: + resolution: {integrity: sha512-2QWMrbwd5eBy5KCYn9a15JEWBgrK2qFEKQN2lqb/6z0bhtevIOxIRfC99tzvRuPt6nixFQ+ynKuBjcfT4ZFrdQ==} engines: {node: '>=14.0.0'} dependencies: - '@aws-sdk/types': 3.310.0 - tslib: 2.5.0 + '@aws-sdk/types': 3.535.0 + '@smithy/types': 2.12.0 + tslib: 2.6.2 dev: false /@aws-sdk/middleware-stack@3.224.0: @@ -5182,13 +5074,6 @@ packages: tslib: 2.5.0 dev: false - /@aws-sdk/middleware-stack@3.310.0: - resolution: {integrity: sha512-010O1PD+UAcZVKRvqEusE1KJqN96wwrf6QsqbRM0ywsKQ21NDweaHvEDlds2VHpgmofxkRLRu/IDrlPkKRQrRg==} - engines: {node: '>=14.0.0'} - dependencies: - tslib: 2.5.0 - dev: false - /@aws-sdk/middleware-user-agent@3.224.0: resolution: {integrity: sha512-YXHC/n8k4qeIkqFVACPmF/QfJyKSOMD1HjM7iUZmJ9yGqDRFeGgn4o2Jktd0dor7sTv6pfUDkLqspxURAsokzA==} engines: {node: '>=14.0.0'} @@ -5198,14 +5083,15 @@ packages: tslib: 2.5.0 dev: false - /@aws-sdk/middleware-user-agent@3.310.0: - resolution: {integrity: sha512-x3IOwSwSbwKidlxRk3CNVHVUb06SRuaELxggCaR++QVI8NU6qD/l4VHXKVRvbTHiC/cYxXE/GaBDgQVpDR7V/g==} + /@aws-sdk/middleware-user-agent@3.540.0: + resolution: {integrity: sha512-8Rd6wPeXDnOYzWj1XCmOKcx/Q87L0K1/EHqOBocGjLVbN3gmRxBvpmR1pRTjf7IsWfnnzN5btqtcAkfDPYQUMQ==} engines: {node: '>=14.0.0'} dependencies: - '@aws-sdk/protocol-http': 3.310.0 - '@aws-sdk/types': 3.310.0 - '@aws-sdk/util-endpoints': 3.310.0 - tslib: 2.5.0 + '@aws-sdk/types': 3.535.0 + '@aws-sdk/util-endpoints': 3.540.0 + '@smithy/protocol-http': 3.3.0 + '@smithy/types': 2.12.0 + tslib: 2.6.2 dev: false /@aws-sdk/node-config-provider@3.224.0: @@ -5218,16 +5104,6 @@ packages: tslib: 2.5.0 dev: false - /@aws-sdk/node-config-provider@3.310.0: - resolution: {integrity: sha512-T/Pp6htc6hq/Cq+MLNDSyiwWCMVF6GqbBbXKVlO5L8rdHx4sq9xPdoPveZhGWrxvkanjA6eCwUp6E0riBOSVng==} - engines: {node: '>=14.0.0'} - dependencies: - '@aws-sdk/property-provider': 3.310.0 - '@aws-sdk/shared-ini-file-loader': 3.310.0 - '@aws-sdk/types': 3.310.0 - tslib: 2.5.0 - dev: false - /@aws-sdk/node-http-handler@3.224.0: resolution: {integrity: sha512-8h4jWsfVRUcJKkqZ9msSN4LhldBpXdNlMcA8ku8IVEBHf5waxqpIhupwR0uCMmV3FDINLqkf/8EwEYAODeRjrw==} engines: {node: '>=14.0.0'} @@ -5239,17 +5115,6 @@ packages: tslib: 2.5.0 dev: false - /@aws-sdk/node-http-handler@3.310.0: - resolution: {integrity: sha512-irv9mbcM9xC2xYjArQF5SYmHBMu4ciMWtGsoHII1nRuFOl9FoT4ffTvEPuLlfC6pznzvKt9zvnm6xXj7gDChKg==} - engines: {node: '>=14.0.0'} - dependencies: - '@aws-sdk/abort-controller': 3.310.0 - '@aws-sdk/protocol-http': 3.310.0 - '@aws-sdk/querystring-builder': 3.310.0 - '@aws-sdk/types': 3.310.0 - tslib: 2.5.0 - dev: false - /@aws-sdk/property-provider@3.224.0: resolution: {integrity: sha512-1F1Hepndlmj6wykNv0ynlS9YTaT3LRF/mqXhCRGLbCWSmCiaW9BUH/ddMdBZJiSw7kcPePKid5ueW84fAO/nKg==} engines: {node: '>=14.0.0'} @@ -5258,14 +5123,6 @@ packages: tslib: 2.5.0 dev: false - /@aws-sdk/property-provider@3.310.0: - resolution: {integrity: sha512-3lxDb0akV6BBzmFe4nLPaoliQbAifyWJhuvuDOu7e8NzouvpQXs0275w9LePhhcgjKAEVXUIse05ZW2DLbxo/g==} - engines: {node: '>=14.0.0'} - dependencies: - '@aws-sdk/types': 3.310.0 - tslib: 2.5.0 - dev: false - /@aws-sdk/protocol-http@3.224.0: resolution: {integrity: sha512-myp31UkADbktZtIZLc4cNfr5zSNVJjPReoH37NPpvgREKOGg7ZB6Lb3UyKbjzrmIv985brMOunlMgIBIJhuPIg==} engines: {node: '>=14.0.0'} @@ -5274,14 +5131,6 @@ packages: tslib: 2.5.0 dev: false - /@aws-sdk/protocol-http@3.310.0: - resolution: {integrity: sha512-fgZ1aw/irQtnrsR58pS8ThKOWo57Py3xX6giRvwSgZDEcxHfVzuQjy9yPuV++v04fdmdtgpbGf8WfvAAJ11yXQ==} - engines: {node: '>=14.0.0'} - dependencies: - '@aws-sdk/types': 3.310.0 - tslib: 2.5.0 - dev: false - /@aws-sdk/querystring-builder@3.224.0: resolution: {integrity: sha512-Fwzt42wWRhf04TetQPqDL03jX5W2cAkRFQewOkIRYVFV17b72z4BFhKID6bpLEtNb4YagyllCWosNg1xooDURQ==} engines: {node: '>=14.0.0'} @@ -5291,15 +5140,6 @@ packages: tslib: 2.5.0 dev: false - /@aws-sdk/querystring-builder@3.310.0: - resolution: {integrity: sha512-ZHH8GV/80+pWGo7DzsvwvXR5xVxUHXUvPJPFAkhr6nCf78igdoF8gR10ScFoEKbtEapoNTaZlKHPXxpD8aPG7A==} - engines: {node: '>=14.0.0'} - dependencies: - '@aws-sdk/types': 3.310.0 - '@aws-sdk/util-uri-escape': 3.310.0 - tslib: 2.5.0 - dev: false - /@aws-sdk/querystring-parser@3.224.0: resolution: {integrity: sha512-UIJZ76ClFtALXRIQS3Za4R76JTsjCYReSBEQ7ag7RF1jwVZLAggdfED9w3XDrN7jbaK6i+aI3Y+eFeq0sB2fcA==} engines: {node: '>=14.0.0'} @@ -5308,12 +5148,16 @@ packages: tslib: 2.5.0 dev: false - /@aws-sdk/querystring-parser@3.310.0: - resolution: {integrity: sha512-YkIznoP6lsiIUHinx++/lbb3tlMURGGqMpo0Pnn32zYzGrJXA6eC3D0as2EcMjo55onTfuLcIiX4qzXes2MYOA==} + /@aws-sdk/region-config-resolver@3.535.0: + resolution: {integrity: sha512-IXOznDiaItBjsQy4Fil0kzX/J3HxIOknEphqHbOfUf+LpA5ugcsxuQQONrbEQusCBnfJyymrldBvBhFmtlU9Wg==} engines: {node: '>=14.0.0'} dependencies: - '@aws-sdk/types': 3.310.0 - tslib: 2.5.0 + '@aws-sdk/types': 3.535.0 + '@smithy/node-config-provider': 2.3.0 + '@smithy/types': 2.12.0 + '@smithy/util-config-provider': 2.3.0 + '@smithy/util-middleware': 2.2.0 + tslib: 2.6.2 dev: false /@aws-sdk/service-error-classification@3.224.0: @@ -5321,11 +5165,6 @@ packages: engines: {node: '>=14.0.0'} dev: false - /@aws-sdk/service-error-classification@3.310.0: - resolution: {integrity: sha512-PuyC7k3qfIKeH2LCnDwbttMOKq3qAx4buvg0yfnJtQOz6t1AR8gsnAq0CjKXXyfkXwNKWTqCpE6lVNUIkXgsMw==} - engines: {node: '>=14.0.0'} - dev: false - /@aws-sdk/shared-ini-file-loader@3.224.0: resolution: {integrity: sha512-6a/XP3lRRcX5ic+bXzF2f644KERVqMx+s0JRrGsPAwTMaMiV0A7Ifl4HKggx6dnxh8j/MXUMsWMtuxt/kCu86A==} engines: {node: '>=14.0.0'} @@ -5334,27 +5173,16 @@ packages: tslib: 2.5.0 dev: false - /@aws-sdk/shared-ini-file-loader@3.310.0: - resolution: {integrity: sha512-N0q9pG0xSjQwc690YQND5bofm+4nfUviQ/Ppgan2kU6aU0WUq8KwgHJBto/YEEI+VlrME30jZJnxtOvcZJc2XA==} + /@aws-sdk/signature-v4-multi-region@3.556.0: + resolution: {integrity: sha512-bWDSK0ggK7QzAOmPZGv29UAIZocL1MNY7XyOvm3P3P1U3tFMoIBilQQBLabXyHoZ9J3Ik0Vv4n95htUhRQ35ow==} engines: {node: '>=14.0.0'} dependencies: - '@aws-sdk/types': 3.310.0 - tslib: 2.5.0 - dev: false - - /@aws-sdk/signature-v4-multi-region@3.310.0: - resolution: {integrity: sha512-q8W+RIomTS/q85Ntgks/CoDElwqkC9+4OCicee5YznNHjQ4gtNWhUkYIyIRWRmXa/qx/AUreW9DM8FAecCOdng==} - engines: {node: '>=14.0.0'} - peerDependencies: - '@aws-sdk/signature-v4-crt': ^3.118.0 - peerDependenciesMeta: - '@aws-sdk/signature-v4-crt': - optional: true - dependencies: - '@aws-sdk/protocol-http': 3.310.0 - '@aws-sdk/signature-v4': 3.310.0 - '@aws-sdk/types': 3.310.0 - tslib: 2.5.0 + '@aws-sdk/middleware-sdk-s3': 3.556.0 + '@aws-sdk/types': 3.535.0 + '@smithy/protocol-http': 3.3.0 + '@smithy/signature-v4': 2.3.0 + '@smithy/types': 2.12.0 + tslib: 2.6.2 dev: false /@aws-sdk/signature-v4@3.224.0: @@ -5369,19 +5197,6 @@ packages: tslib: 2.5.0 dev: false - /@aws-sdk/signature-v4@3.310.0: - resolution: {integrity: sha512-1M60P1ZBNAjCFv9sYW29OF6okktaeibWyW3lMXqzoHF70lHBZh+838iUchznXUA5FLabfn4jBFWMRxlAXJUY2Q==} - engines: {node: '>=14.0.0'} - dependencies: - '@aws-sdk/is-array-buffer': 3.310.0 - '@aws-sdk/types': 3.310.0 - '@aws-sdk/util-hex-encoding': 3.310.0 - '@aws-sdk/util-middleware': 3.310.0 - '@aws-sdk/util-uri-escape': 3.310.0 - '@aws-sdk/util-utf8': 3.310.0 - tslib: 2.5.0 - dev: false - /@aws-sdk/smithy-client@3.224.0: resolution: {integrity: sha512-KXXzzrCBv8ewWdtm/aolZHr2f9NRZOcDutFaWXbfSptEsK50Zi9PNzB9ZVKUHyAXYjwJHb2Sl18WRrwIxH6H4g==} engines: {node: '>=14.0.0'} @@ -5391,15 +5206,6 @@ packages: tslib: 2.5.0 dev: false - /@aws-sdk/smithy-client@3.315.0: - resolution: {integrity: sha512-qTm0lwTh6IZMiWs3U9k2veoF6gV9yE0B9Z34yMxagOfQFQgxMih0aiH25MD25eRigjJ3sfUeZ+B0mRycmJZdkQ==} - engines: {node: '>=14.0.0'} - dependencies: - '@aws-sdk/middleware-stack': 3.310.0 - '@aws-sdk/types': 3.310.0 - tslib: 2.5.0 - dev: false - /@aws-sdk/token-providers@3.224.0: resolution: {integrity: sha512-cswWqA4n1v3JIALYRA8Tq/4uHcFpBg5cgi2khNHBCF/H09Hu3dynGup6Ji8cCzf3fTak4eBQipcWaWUGE0hTGw==} engines: {node: '>=14.0.0'} @@ -5413,16 +5219,18 @@ packages: - aws-crt dev: false - /@aws-sdk/token-providers@3.315.0: - resolution: {integrity: sha512-EjLUQ9JLqU3eJfJyzpcVjFnuJ1MCCodZaVJmuX/a/as4TK41bKMvkVojjsU7pDSYzl+tuXE+ceivcWK4H0HQdQ==} + /@aws-sdk/token-providers@3.556.0(@aws-sdk/credential-provider-node@3.556.0): + resolution: {integrity: sha512-tvIiugNF0/+2wfuImMrpKjXMx4nCnFWQjQvouObny+wrif/PGqqQYrybwxPJDvzbd965bu1I+QuSv85/ug7xsg==} engines: {node: '>=14.0.0'} dependencies: - '@aws-sdk/client-sso-oidc': 3.315.0 - '@aws-sdk/property-provider': 3.310.0 - '@aws-sdk/shared-ini-file-loader': 3.310.0 - '@aws-sdk/types': 3.310.0 - tslib: 2.5.0 + '@aws-sdk/client-sso-oidc': 3.556.0(@aws-sdk/credential-provider-node@3.556.0) + '@aws-sdk/types': 3.535.0 + '@smithy/property-provider': 2.2.0 + '@smithy/shared-ini-file-loader': 2.4.0 + '@smithy/types': 2.12.0 + tslib: 2.6.2 transitivePeerDependencies: + - '@aws-sdk/credential-provider-node' - aws-crt dev: false @@ -5445,6 +5253,14 @@ packages: tslib: 2.5.0 dev: false + /@aws-sdk/types@3.535.0: + resolution: {integrity: sha512-aY4MYfduNj+sRR37U7XxYR8wemfbKP6lx00ze2M2uubn7mZotuVrWYAafbMSXrdEMSToE5JDhr28vArSOoLcSg==} + engines: {node: '>=14.0.0'} + dependencies: + '@smithy/types': 2.12.0 + tslib: 2.6.2 + dev: false + /@aws-sdk/url-parser@3.224.0: resolution: {integrity: sha512-DGQoiOxRVq9eEbmcGF7oz/htcHxFtLlUTzKbaX1gFuh1kmhRQwJIzz6vkrMdxOgPjvUYMJuMEcYnsHolDNWbMg==} dependencies: @@ -5453,19 +5269,11 @@ packages: tslib: 2.5.0 dev: false - /@aws-sdk/url-parser@3.310.0: - resolution: {integrity: sha512-mCLnCaSB9rQvAgx33u0DujLvr4d5yEm/W5r789GblwwQnlNXedVu50QRizMLTpltYWyAUoXjJgQnJHmJMaKXhw==} - dependencies: - '@aws-sdk/querystring-parser': 3.310.0 - '@aws-sdk/types': 3.310.0 - tslib: 2.5.0 - dev: false - - /@aws-sdk/util-arn-parser@3.310.0: - resolution: {integrity: sha512-jL8509owp/xB9+Or0pvn3Fe+b94qfklc2yPowZZIFAkFcCSIdkIglz18cPDWnYAcy9JGewpMS1COXKIUhZkJsA==} + /@aws-sdk/util-arn-parser@3.535.0: + resolution: {integrity: sha512-smVo29nUPAOprp8Z5Y3GHuhiOtw6c8/EtLCm5AVMtRsTPw4V414ZXL2H66tzmb5kEeSzQlbfBSBEdIFZoxO9kg==} engines: {node: '>=14.0.0'} dependencies: - tslib: 2.5.0 + tslib: 2.6.2 dev: false /@aws-sdk/util-base64@3.208.0: @@ -5476,26 +5284,12 @@ packages: tslib: 2.5.0 dev: false - /@aws-sdk/util-base64@3.310.0: - resolution: {integrity: sha512-v3+HBKQvqgdzcbL+pFswlx5HQsd9L6ZTlyPVL2LS9nNXnCcR3XgGz9jRskikRUuUvUXtkSG1J88GAOnJ/apTPg==} - engines: {node: '>=14.0.0'} - dependencies: - '@aws-sdk/util-buffer-from': 3.310.0 - tslib: 2.5.0 - dev: false - /@aws-sdk/util-body-length-browser@3.188.0: resolution: {integrity: sha512-8VpnwFWXhnZ/iRSl9mTf+VKOX9wDE8QtN4bj9pBfxwf90H1X7E8T6NkiZD3k+HubYf2J94e7DbeHs7fuCPW5Qg==} dependencies: tslib: 2.5.0 dev: false - /@aws-sdk/util-body-length-browser@3.310.0: - resolution: {integrity: sha512-sxsC3lPBGfpHtNTUoGXMQXLwjmR0zVpx0rSvzTPAuoVILVsp5AU/w5FphNPxD5OVIjNbZv9KsKTuvNTiZjDp9g==} - dependencies: - tslib: 2.5.0 - dev: false - /@aws-sdk/util-body-length-node@3.208.0: resolution: {integrity: sha512-3zj50e5g7t/MQf53SsuuSf0hEELzMtD8RX8C76f12OSRo2Bca4FLLYHe0TZbxcfQHom8/hOaeZEyTyMogMglqg==} engines: {node: '>=14.0.0'} @@ -5503,13 +5297,6 @@ packages: tslib: 2.5.0 dev: false - /@aws-sdk/util-body-length-node@3.310.0: - resolution: {integrity: sha512-2tqGXdyKhyA6w4zz7UPoS8Ip+7sayOg9BwHNidiGm2ikbDxm1YrCfYXvCBdwaJxa4hJfRVz+aL9e+d3GqPI9pQ==} - engines: {node: '>=14.0.0'} - dependencies: - tslib: 2.5.0 - dev: false - /@aws-sdk/util-buffer-from@3.208.0: resolution: {integrity: sha512-7L0XUixNEFcLUGPeBF35enCvB9Xl+K6SQsmbrPk1P3mlV9mguWSDQqbOBwY1Ir0OVbD6H/ZOQU7hI/9RtRI0Zw==} engines: {node: '>=14.0.0'} @@ -5518,14 +5305,6 @@ packages: tslib: 2.5.0 dev: false - /@aws-sdk/util-buffer-from@3.310.0: - resolution: {integrity: sha512-i6LVeXFtGih5Zs8enLrt+ExXY92QV25jtEnTKHsmlFqFAuL3VBeod6boeMXkN2p9lbSVVQ1sAOOYZOHYbYkntw==} - engines: {node: '>=14.0.0'} - dependencies: - '@aws-sdk/is-array-buffer': 3.310.0 - tslib: 2.5.0 - dev: false - /@aws-sdk/util-config-provider@3.208.0: resolution: {integrity: sha512-DSRqwrERUsT34ug+anlMBIFooBEGwM8GejC7q00Y/9IPrQy50KnG5PW2NiTjuLKNi7pdEOlwTSEocJE15eDZIg==} engines: {node: '>=14.0.0'} @@ -5533,13 +5312,6 @@ packages: tslib: 2.5.0 dev: false - /@aws-sdk/util-config-provider@3.310.0: - resolution: {integrity: sha512-xIBaYo8dwiojCw8vnUcIL4Z5tyfb1v3yjqyJKJWV/dqKUFOOS0U591plmXbM+M/QkXyML3ypon1f8+BoaDExrg==} - engines: {node: '>=14.0.0'} - dependencies: - tslib: 2.5.0 - dev: false - /@aws-sdk/util-defaults-mode-browser@3.224.0: resolution: {integrity: sha512-umk+A/pmlbuyvDCgdndgJUa0xitcTUF7XoUt/3qDTpNbzR5Dzgdbz74BgXUAEBJ8kPP5pCo2VE1ZD7fxqYU/dQ==} engines: {node: '>= 10.0.0'} @@ -5550,16 +5322,6 @@ packages: tslib: 2.5.0 dev: false - /@aws-sdk/util-defaults-mode-browser@3.315.0: - resolution: {integrity: sha512-5cqNvfGos3FB/MHNl+g2fr+tPY7s3k3+96V3wOPWLOksdACth10OxPpHfboXXZDHHkR0hmyJwJcfgA4uQrUcGg==} - engines: {node: '>= 10.0.0'} - dependencies: - '@aws-sdk/property-provider': 3.310.0 - '@aws-sdk/types': 3.310.0 - bowser: 2.11.0 - tslib: 2.5.0 - dev: false - /@aws-sdk/util-defaults-mode-node@3.224.0: resolution: {integrity: sha512-ZJQJ1McbQ5Rnf5foCFAKHT8Cbwg4IbM+bb6fCkHRJFH9AXEvwc+hPtSYf0KuI7TmoZFj9WG5JOE9Ns6g7lRHSA==} engines: {node: '>= 10.0.0'} @@ -5572,18 +5334,6 @@ packages: tslib: 2.5.0 dev: false - /@aws-sdk/util-defaults-mode-node@3.315.0: - resolution: {integrity: sha512-vSPIGpzh6NJIMLoh31p7CczSatN46kJdJBrHfODHaIGe4t156x+LfkkcxGQhtifqxglhL7l+fmn5D1fM5exHuA==} - engines: {node: '>= 10.0.0'} - dependencies: - '@aws-sdk/config-resolver': 3.310.0 - '@aws-sdk/credential-provider-imds': 3.310.0 - '@aws-sdk/node-config-provider': 3.310.0 - '@aws-sdk/property-provider': 3.310.0 - '@aws-sdk/types': 3.310.0 - tslib: 2.5.0 - dev: false - /@aws-sdk/util-endpoints@3.224.0: resolution: {integrity: sha512-k5hHbk7AP/cajw5rF7wmKP39B0WQMFdxrn8dcVOHVK0FZeKbaGCEmOf3AYXrQhswR9Xo815Rqffoml9B1z3bCA==} engines: {node: '>=14.0.0'} @@ -5592,12 +5342,14 @@ packages: tslib: 2.5.0 dev: false - /@aws-sdk/util-endpoints@3.310.0: - resolution: {integrity: sha512-zG+/d/O5KPmAaeOMPd6bW1abifdT0H03f42keLjYEoRZzYtHPC5DuPE0UayiWGckI6BCDgy0sRKXCYS49UNFaQ==} + /@aws-sdk/util-endpoints@3.540.0: + resolution: {integrity: sha512-1kMyQFAWx6f8alaI6UT65/5YW/7pDWAKAdNwL6vuJLea03KrZRX3PMoONOSJpAS5m3Ot7HlWZvf3wZDNTLELZw==} engines: {node: '>=14.0.0'} dependencies: - '@aws-sdk/types': 3.310.0 - tslib: 2.5.0 + '@aws-sdk/types': 3.535.0 + '@smithy/types': 2.12.0 + '@smithy/util-endpoints': 1.2.0 + tslib: 2.6.2 dev: false /@aws-sdk/util-hex-encoding@3.201.0: @@ -5607,13 +5359,6 @@ packages: tslib: 2.5.0 dev: false - /@aws-sdk/util-hex-encoding@3.310.0: - resolution: {integrity: sha512-sVN7mcCCDSJ67pI1ZMtk84SKGqyix6/0A1Ab163YKn+lFBQRMKexleZzpYzNGxYzmQS6VanP/cfU7NiLQOaSfA==} - engines: {node: '>=14.0.0'} - dependencies: - tslib: 2.5.0 - dev: false - /@aws-sdk/util-locate-window@3.295.0: resolution: {integrity: sha512-d/s+zhUx5Kh4l/ecMP/TBjzp1GR/g89Q4nWH6+wH5WgdHsK+LG+vmsk6mVNuP/8wsCofYG4NBqp5Ulbztbm9QA==} engines: {node: '>=14.0.0'} @@ -5628,42 +5373,6 @@ packages: tslib: 2.5.0 dev: false - /@aws-sdk/util-middleware@3.310.0: - resolution: {integrity: sha512-FTSUKL/eRb9X6uEZClrTe27QFXUNNp7fxYrPndZwk1hlaOP5ix+MIHBcI7pIiiY/JPfOUmPyZOu+HetlFXjWog==} - engines: {node: '>=14.0.0'} - dependencies: - tslib: 2.5.0 - dev: false - - /@aws-sdk/util-retry@3.310.0: - resolution: {integrity: sha512-FwWGhCBLfoivTMUHu1LIn4NjrN9JLJ/aX5aZmbcPIOhZVFJj638j0qDgZXyfvVqBuBZh7M8kGq0Oahy3dp69OA==} - engines: {node: '>= 14.0.0'} - dependencies: - '@aws-sdk/service-error-classification': 3.310.0 - tslib: 2.5.0 - dev: false - - /@aws-sdk/util-stream-browser@3.310.0: - resolution: {integrity: sha512-bysXZHwFwvbqOTCScCdCnoLk1K3GCo0HRIYEZuL7O7MHrQmfaYRXcaft/p22+GUv9VeFXS/eJJZ5r4u32az94w==} - dependencies: - '@aws-sdk/fetch-http-handler': 3.310.0 - '@aws-sdk/types': 3.310.0 - '@aws-sdk/util-base64': 3.310.0 - '@aws-sdk/util-hex-encoding': 3.310.0 - '@aws-sdk/util-utf8': 3.310.0 - tslib: 2.5.0 - dev: false - - /@aws-sdk/util-stream-node@3.310.0: - resolution: {integrity: sha512-hueAXFK0GVvnfYFgqbF7587xZfMZff5jlIFZOHqx7XVU7bl7qrRUCnphHk8H6yZ7RoQbDPcfmHJgtEoAJg1T1Q==} - engines: {node: '>=14.0.0'} - dependencies: - '@aws-sdk/node-http-handler': 3.310.0 - '@aws-sdk/types': 3.310.0 - '@aws-sdk/util-buffer-from': 3.310.0 - tslib: 2.5.0 - dev: false - /@aws-sdk/util-uri-escape@3.201.0: resolution: {integrity: sha512-TeTWbGx4LU2c5rx0obHeDFeO9HvwYwQtMh1yniBz00pQb6Qt6YVOETVQikRZ+XRQwEyCg/dA375UplIpiy54mA==} engines: {node: '>=14.0.0'} @@ -5671,13 +5380,6 @@ packages: tslib: 2.5.0 dev: false - /@aws-sdk/util-uri-escape@3.310.0: - resolution: {integrity: sha512-drzt+aB2qo2LgtDoiy/3sVG8w63cgLkqFIa2NFlGpUgHFWTXkqtbgf4L5QdjRGKWhmZsnqkbtL7vkSWEcYDJ4Q==} - engines: {node: '>=14.0.0'} - dependencies: - tslib: 2.5.0 - dev: false - /@aws-sdk/util-user-agent-browser@3.224.0: resolution: {integrity: sha512-Dm/30cLUIM1Oam4V//m9sPrXyGOKFslUXP7Mz2AlR1HelUYoreWAIe7Rx44HR6PaXyZmjW5K0ItmcJ7tCgyMpw==} dependencies: @@ -5686,12 +5388,13 @@ packages: tslib: 2.5.0 dev: false - /@aws-sdk/util-user-agent-browser@3.310.0: - resolution: {integrity: sha512-yU/4QnHHuQ5z3vsUqMQVfYLbZGYwpYblPiuZx4Zo9+x0PBkNjYMqctdDcrpoH9Z2xZiDN16AmQGK1tix117ZKw==} + /@aws-sdk/util-user-agent-browser@3.535.0: + resolution: {integrity: sha512-RWMcF/xV5n+nhaA/Ff5P3yNP3Kur/I+VNZngog4TEs92oB/nwOdAg/2JL8bVAhUbMrjTjpwm7PItziYFQoqyig==} dependencies: - '@aws-sdk/types': 3.310.0 + '@aws-sdk/types': 3.535.0 + '@smithy/types': 2.12.0 bowser: 2.11.0 - tslib: 2.5.0 + tslib: 2.6.2 dev: false /@aws-sdk/util-user-agent-node@3.224.0: @@ -5708,8 +5411,8 @@ packages: tslib: 2.5.0 dev: false - /@aws-sdk/util-user-agent-node@3.310.0: - resolution: {integrity: sha512-Ra3pEl+Gn2BpeE7KiDGpi4zj7WJXZA5GXnGo3mjbi9+Y3zrbuhJAbdZO3mO/o7xDgMC6ph4xCTbaSGzU6b6EDg==} + /@aws-sdk/util-user-agent-node@3.535.0: + resolution: {integrity: sha512-dRek0zUuIT25wOWJlsRm97nTkUlh1NDcLsQZIN2Y8KxhwoXXWtJs5vaDPT+qAg+OpcNj80i1zLR/CirqlFg/TQ==} engines: {node: '>=14.0.0'} peerDependencies: aws-crt: '>=1.0.0' @@ -5717,9 +5420,10 @@ packages: aws-crt: optional: true dependencies: - '@aws-sdk/node-config-provider': 3.310.0 - '@aws-sdk/types': 3.310.0 - tslib: 2.5.0 + '@aws-sdk/types': 3.535.0 + '@smithy/node-config-provider': 2.3.0 + '@smithy/types': 2.12.0 + tslib: 2.6.2 dev: false /@aws-sdk/util-utf8-browser@3.188.0: @@ -5736,28 +5440,12 @@ packages: tslib: 2.5.0 dev: false - /@aws-sdk/util-utf8@3.310.0: - resolution: {integrity: sha512-DnLfFT8uCO22uOJc0pt0DsSNau1GTisngBCDw8jQuWT5CqogMJu4b/uXmwEqfj8B3GX6Xsz8zOd6JpRlPftQoA==} + /@aws-sdk/xml-builder@3.535.0: + resolution: {integrity: sha512-VXAq/Jz8KIrU84+HqsOJhIKZqG0PNTdi6n6PFQ4xJf44ZQHD/5C7ouH4qCFX5XgZXcgbRIcMVVYGC6Jye0dRng==} engines: {node: '>=14.0.0'} dependencies: - '@aws-sdk/util-buffer-from': 3.310.0 - tslib: 2.5.0 - dev: false - - /@aws-sdk/util-waiter@3.310.0: - resolution: {integrity: sha512-AV5j3guH/Y4REu+Qh3eXQU9igljHuU4XjX2sADAgf54C0kkhcCCkkiuzk3IsX089nyJCqIcj5idbjdvpnH88Vw==} - engines: {node: '>=14.0.0'} - dependencies: - '@aws-sdk/abort-controller': 3.310.0 - '@aws-sdk/types': 3.310.0 - tslib: 2.5.0 - dev: false - - /@aws-sdk/xml-builder@3.310.0: - resolution: {integrity: sha512-TqELu4mOuSIKQCqj63fGVs86Yh+vBx5nHRpWKNUNhB2nPTpfbziTs5c1X358be3peVWA4wPxW7Nt53KIg1tnNw==} - engines: {node: '>=14.0.0'} - dependencies: - tslib: 2.5.0 + '@smithy/types': 2.12.0 + tslib: 2.6.2 dev: false /@azure/abort-controller@1.1.0: @@ -5767,32 +5455,40 @@ packages: tslib: 2.5.0 dev: false - /@azure/core-auth@1.4.0: - resolution: {integrity: sha512-HFrcTgmuSuukRf/EdPmqBrc5l6Q5Uu+2TbuhaKbgaCpP2TfAeiNaQPAadxO+CYBRHGUzIDteMAjFspFLDLnKVQ==} - engines: {node: '>=12.0.0'} + /@azure/abort-controller@2.1.2: + resolution: {integrity: sha512-nBrLsEWm4J2u5LpAPjxADTlq3trDgVZZXHNKabeXZtpq3d3AbN/KGO82R87rdDz5/lYB024rtEf10/q0urNgsA==} + engines: {node: '>=18.0.0'} dependencies: - '@azure/abort-controller': 1.1.0 - tslib: 2.5.0 + tslib: 2.6.2 + dev: false + + /@azure/core-auth@1.7.2: + resolution: {integrity: sha512-Igm/S3fDYmnMq1uKS38Ae1/m37B3zigdlZw+kocwEhh5GjyKjPrXKO2J6rzpC1wAxrNil/jX9BJRqBshyjnF3g==} + engines: {node: '>=18.0.0'} + dependencies: + '@azure/abort-controller': 2.1.2 + '@azure/core-util': 1.2.0 + tslib: 2.6.2 dev: false - /@azure/core-http@3.0.0: - resolution: {integrity: sha512-BxI2SlGFPPz6J1XyZNIVUf0QZLBKFX+ViFjKOkzqD18J1zOINIQ8JSBKKr+i+v8+MB6LacL6Nn/sP/TE13+s2Q==} + /@azure/core-http@3.0.4: + resolution: {integrity: sha512-Fok9VVhMdxAFOtqiiAtg74fL0UJkt0z3D+ouUUxcRLzZNBioPRAMJFVxiWoJljYpXsRi4GDQHzQHDc9AiYaIUQ==} engines: {node: '>=14.0.0'} dependencies: '@azure/abort-controller': 1.1.0 - '@azure/core-auth': 1.4.0 + '@azure/core-auth': 1.7.2 '@azure/core-tracing': 1.0.0-preview.13 '@azure/core-util': 1.2.0 '@azure/logger': 1.0.4 '@types/node-fetch': 2.6.2 '@types/tunnel': 0.0.3 form-data: 4.0.0 - node-fetch: 2.6.7 + node-fetch: 2.7.0 process: 0.11.10 - tslib: 2.5.0 + tslib: 2.6.2 tunnel: 0.0.6 uuid: 8.3.2 - xml2js: 0.4.23 + xml2js: 0.5.0 transitivePeerDependencies: - encoding dev: false @@ -5803,14 +5499,14 @@ packages: dependencies: '@azure/abort-controller': 1.1.0 '@azure/logger': 1.0.4 - tslib: 2.5.0 + tslib: 2.6.2 dev: false /@azure/core-paging@1.5.0: resolution: {integrity: sha512-zqWdVIt+2Z+3wqxEOGzR5hXFZ8MGKK52x4vFLw8n58pR6ZfKRx3EXYTxTaYxYHc/PexPUTyimcTWFJbji9Z6Iw==} engines: {node: '>=14.0.0'} dependencies: - tslib: 2.5.0 + tslib: 2.6.2 dev: false /@azure/core-rest-pipeline@1.10.1: @@ -5818,14 +5514,14 @@ packages: engines: {node: '>=14.0.0'} dependencies: '@azure/abort-controller': 1.1.0 - '@azure/core-auth': 1.4.0 + '@azure/core-auth': 1.7.2 '@azure/core-tracing': 1.0.1 '@azure/core-util': 1.2.0 '@azure/logger': 1.0.4 form-data: 4.0.0 http-proxy-agent: 5.0.0 https-proxy-agent: 5.0.1 - tslib: 2.5.0 + tslib: 2.6.2 uuid: 8.3.2 transitivePeerDependencies: - supports-color @@ -5835,15 +5531,15 @@ packages: resolution: {integrity: sha512-KxDlhXyMlh2Jhj2ykX6vNEU0Vou4nHr025KoSEiz7cS3BNiHNaZcdECk/DmLkEB0as5T7b/TpRcehJ5yV6NeXQ==} engines: {node: '>=12.0.0'} dependencies: - '@opentelemetry/api': 1.4.0 - tslib: 2.5.0 + '@opentelemetry/api': 1.8.0 + tslib: 2.6.2 dev: false /@azure/core-tracing@1.0.1: resolution: {integrity: sha512-I5CGMoLtX+pI17ZdiFJZgxMJApsK6jjfm85hpgp3oazCdq5Wxgh4wMr7ge/TTWW1B5WBuvIOI1fMU/FrOAMKrw==} engines: {node: '>=12.0.0'} dependencies: - tslib: 2.5.0 + tslib: 2.6.2 dev: false /@azure/core-util@1.2.0: @@ -5875,32 +5571,32 @@ packages: uuid: 8.3.2 dev: false - /@azure/opentelemetry-instrumentation-azure-sdk@1.0.0-beta.4: - resolution: {integrity: sha512-bSF2l47Od7kH+u/O67cmQCj5jmNeC+gUNDKr2cMfLBwSqk12T7B4JZQ34viEq2vhLWoKbZO7j6srPmKiSGPzNg==} + /@azure/opentelemetry-instrumentation-azure-sdk@1.0.0-beta.5: + resolution: {integrity: sha512-fsUarKQDvjhmBO4nIfaZkfNSApm1hZBzcvpNbSrXdcUBxu7lRvKsV5DnwszX7cnhLyVOW9yl1uigtRQ1yDANjA==} engines: {node: '>=14.0.0'} dependencies: '@azure/core-tracing': 1.0.1 '@azure/logger': 1.0.4 - '@opentelemetry/api': 1.4.1 - '@opentelemetry/core': 1.15.0(@opentelemetry/api@1.4.1) - '@opentelemetry/instrumentation': 0.40.0(@opentelemetry/api@1.4.1) - tslib: 2.5.0 + '@opentelemetry/api': 1.8.0 + '@opentelemetry/core': 1.23.0(@opentelemetry/api@1.8.0) + '@opentelemetry/instrumentation': 0.41.2(@opentelemetry/api@1.8.0) + tslib: 2.6.2 transitivePeerDependencies: - supports-color dev: false - /@azure/storage-blob@12.13.0: - resolution: {integrity: sha512-t3Q2lvBMJucgTjQcP5+hvEJMAsJSk0qmAnjDLie2td017IiduZbbC9BOcFfmwzR6y6cJdZOuewLCNFmEx9IrXA==} + /@azure/storage-blob@12.17.0: + resolution: {integrity: sha512-sM4vpsCpcCApagRW5UIjQNlNylo02my2opgp0Emi8x888hZUvJ3dN69Oq20cEGXkMUWnoCrBaB0zyS3yeB87sQ==} engines: {node: '>=14.0.0'} dependencies: '@azure/abort-controller': 1.1.0 - '@azure/core-http': 3.0.0 + '@azure/core-http': 3.0.4 '@azure/core-lro': 2.5.1 '@azure/core-paging': 1.5.0 '@azure/core-tracing': 1.0.0-preview.13 '@azure/logger': 1.0.4 events: 3.3.0 - tslib: 2.4.1 + tslib: 2.6.2 transitivePeerDependencies: - encoding dev: false @@ -5912,8 +5608,16 @@ packages: '@babel/highlight': 7.22.5 dev: true - /@babel/compat-data@7.20.1: - resolution: {integrity: sha512-EWZ4mE2diW3QALKvDMiXnbZpRvlj+nayZ112nK93SnhqOtpdsbVD4W+2tEoT3YNBAG9RBR0ISY758ZkOgsn6pQ==} + /@babel/code-frame@7.24.2: + resolution: {integrity: sha512-y5+tLQyV8pg3fsiln67BVLD1P13Eg4lh5RW9mF0zUuvLrv9uIQ4MCL+CRT+FTsBlBjcIan6PGsLcBN0m3ClUyQ==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/highlight': 7.24.2 + picocolors: 1.0.0 + dev: true + + /@babel/compat-data@7.24.4: + resolution: {integrity: sha512-vg8Gih2MLK+kOkHJp4gBEIkyaIi00jgWot2D9QOmmfLC8jINSOzmCLta6Bvz/JSBCqnegV0L80jhxkol5GWNfQ==} engines: {node: '>=6.9.0'} dev: true @@ -5921,18 +5625,18 @@ packages: resolution: {integrity: sha512-gTXYh3M5wb7FRXQy+FErKFAv90BnlOuNn1QkCK2lREoPAjrQCO49+HVSrFoe5uakFAF5eenS75KbO2vQiLrTMQ==} engines: {node: '>=6.9.0'} dependencies: - '@babel/code-frame': 7.22.5 - '@babel/generator': 7.20.4 - '@babel/helper-module-transforms': 7.20.2 - '@babel/helpers': 7.20.1 - '@babel/parser': 7.20.3 - '@babel/template': 7.18.10 - '@babel/traverse': 7.20.1 - '@babel/types': 7.20.2 + '@babel/code-frame': 7.24.2 + '@babel/generator': 7.24.4 + '@babel/helper-module-transforms': 7.23.3(@babel/core@7.12.9) + '@babel/helpers': 7.24.4 + '@babel/parser': 7.24.4 + '@babel/template': 7.24.0 + '@babel/traverse': 7.24.1 + '@babel/types': 7.24.0 convert-source-map: 1.9.0 debug: 4.3.4 gensync: 1.0.0-beta.2 - json5: 2.2.1 + json5: 2.2.3 lodash: 4.17.21 resolve: 1.22.2 semver: 5.7.2 @@ -5941,24 +5645,24 @@ packages: - supports-color dev: true - /@babel/core@7.20.2: - resolution: {integrity: sha512-w7DbG8DtMrJcFOi4VrLm+8QM4az8Mo+PuLBKLp2zrYRCow8W/f9xiXm5sN53C8HksCyDQwCKha9JiDoIyPjT2g==} + /@babel/core@7.24.4: + resolution: {integrity: sha512-MBVlMXP+kkl5394RBLSxxk/iLTeVGuXTV3cIDXavPpMMqnSnt6apKgan/U8O3USWZCWZT/TbgfEpKa4uMgN4Dg==} engines: {node: '>=6.9.0'} dependencies: '@ampproject/remapping': 2.3.0 - '@babel/code-frame': 7.22.5 - '@babel/generator': 7.20.4 - '@babel/helper-compilation-targets': 7.20.0(@babel/core@7.20.2) - '@babel/helper-module-transforms': 7.20.2 - '@babel/helpers': 7.20.1 - '@babel/parser': 7.20.3 - '@babel/template': 7.18.10 - '@babel/traverse': 7.20.1 - '@babel/types': 7.20.2 - convert-source-map: 1.9.0 + '@babel/code-frame': 7.24.2 + '@babel/generator': 7.24.4 + '@babel/helper-compilation-targets': 7.23.6 + '@babel/helper-module-transforms': 7.23.3(@babel/core@7.24.4) + '@babel/helpers': 7.24.4 + '@babel/parser': 7.24.4 + '@babel/template': 7.24.0 + '@babel/traverse': 7.24.1 + '@babel/types': 7.24.0 + convert-source-map: 2.0.0 debug: 4.3.4 gensync: 1.0.0-beta.2 - json5: 2.2.1 + json5: 2.2.3 semver: 6.3.1 transitivePeerDependencies: - supports-color @@ -5973,60 +5677,80 @@ packages: jsesc: 2.5.2 dev: true - /@babel/helper-compilation-targets@7.20.0(@babel/core@7.20.2): - resolution: {integrity: sha512-0jp//vDGp9e8hZzBc6N/KwA5ZK3Wsm/pfm4CrY7vzegkVxc65SgSn6wYOnwHe9Js9HRQ1YTCKLGPzDtaS3RoLQ==} + /@babel/generator@7.24.4: + resolution: {integrity: sha512-Xd6+v6SnjWVx/nus+y0l1sxMOTOMBkyL4+BIdbALyatQnAe/SRVjANeDPSCYaX+i1iJmuGSKf3Z+E+V/va1Hvw==} engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0 dependencies: - '@babel/compat-data': 7.20.1 - '@babel/core': 7.20.2 - '@babel/helper-validator-option': 7.18.6 - browserslist: 4.21.4 + '@babel/types': 7.24.0 + '@jridgewell/gen-mapping': 0.3.5 + '@jridgewell/trace-mapping': 0.3.25 + jsesc: 2.5.2 + dev: true + + /@babel/helper-compilation-targets@7.23.6: + resolution: {integrity: sha512-9JB548GZoQVmzrFgp8o7KxdgkTGm6xs9DW0o/Pim72UDjzr5ObUQ6ZzYPqA+g9OTS2bBQoctLJrky0RDCAWRgQ==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/compat-data': 7.24.4 + '@babel/helper-validator-option': 7.23.5 + browserslist: 4.23.0 + lru-cache: 5.1.1 semver: 6.3.1 dev: true - /@babel/helper-environment-visitor@7.18.9: - resolution: {integrity: sha512-3r/aACDJ3fhQ/EVgFy0hpj8oHyHpQc+LPtJoY9SzTThAsStm4Ptegq92vqKoE3vD706ZVFWITnMnxucw+S9Ipg==} + /@babel/helper-environment-visitor@7.22.20: + resolution: {integrity: sha512-zfedSIzFhat/gFhWfHtgWvlec0nqB9YEIVrpuwjruLlXfUSnA8cJB0miHKwqDnQ7d32aKo2xt88/xZptwxbfhA==} engines: {node: '>=6.9.0'} dev: true - /@babel/helper-function-name@7.19.0: - resolution: {integrity: sha512-WAwHBINyrpqywkUH0nTnNgI5ina5TFn85HKS0pbPDfxFfhyR/aNQEn4hGi1P1JyT//I0t4OgXUlofzWILRvS5w==} + /@babel/helper-function-name@7.23.0: + resolution: {integrity: sha512-OErEqsrxjZTJciZ4Oo+eoZqeW9UIiOcuYKRJA4ZAgV9myA+pOXhhmpfNCKjEH/auVfEYVFJ6y1Tc4r0eIApqiw==} engines: {node: '>=6.9.0'} dependencies: - '@babel/template': 7.18.10 + '@babel/template': 7.24.0 '@babel/types': 7.24.0 dev: true - /@babel/helper-hoist-variables@7.18.6: - resolution: {integrity: sha512-UlJQPkFqFULIcyW5sbzgbkxn2FKRgwWiRexcuaR8RNJRy8+LLveqPjwZV/bwrLZCN0eUHD/x8D0heK1ozuoo6Q==} + /@babel/helper-hoist-variables@7.22.5: + resolution: {integrity: sha512-wGjk9QZVzvknA6yKIUURb8zY3grXCcOZt+/7Wcy8O2uctxhplmUPkOdlgoNhmdVee2c92JXbf1xpMtVNbfoxRw==} engines: {node: '>=6.9.0'} dependencies: '@babel/types': 7.24.0 dev: true - /@babel/helper-module-imports@7.18.6: - resolution: {integrity: sha512-0NFvs3VkuSYbFi1x2Vd6tKrywq+z/cLeYC/RJNFrIX/30Bf5aiGYbtvGXolEktzJH8o5E5KJ3tT+nkxuuZFVlA==} + /@babel/helper-module-imports@7.24.3: + resolution: {integrity: sha512-viKb0F9f2s0BCS22QSF308z/+1YWKV/76mwt61NBzS5izMzDPwdq1pTrzf+Li3npBWX9KdQbkeCt1jSAM7lZqg==} engines: {node: '>=6.9.0'} dependencies: '@babel/types': 7.24.0 dev: true - /@babel/helper-module-transforms@7.20.2: - resolution: {integrity: sha512-zvBKyJXRbmK07XhMuujYoJ48B5yvvmM6+wcpv6Ivj4Yg6qO7NOZOSnvZN9CRl1zz1Z4cKf8YejmCMh8clOoOeA==} + /@babel/helper-module-transforms@7.23.3(@babel/core@7.12.9): + resolution: {integrity: sha512-7bBs4ED9OmswdfDzpz4MpWgSrV7FXlc3zIagvLFjS5H+Mk7Snr21vQ6QwrsoCGMfNC4e4LQPdoULEt4ykz0SRQ==} engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0 dependencies: - '@babel/helper-environment-visitor': 7.18.9 - '@babel/helper-module-imports': 7.18.6 - '@babel/helper-simple-access': 7.20.2 - '@babel/helper-split-export-declaration': 7.18.6 - '@babel/helper-validator-identifier': 7.22.5 - '@babel/template': 7.18.10 - '@babel/traverse': 7.20.1 - '@babel/types': 7.24.0 - transitivePeerDependencies: - - supports-color + '@babel/core': 7.12.9 + '@babel/helper-environment-visitor': 7.22.20 + '@babel/helper-module-imports': 7.24.3 + '@babel/helper-simple-access': 7.22.5 + '@babel/helper-split-export-declaration': 7.22.6 + '@babel/helper-validator-identifier': 7.22.20 + dev: true + + /@babel/helper-module-transforms@7.23.3(@babel/core@7.24.4): + resolution: {integrity: sha512-7bBs4ED9OmswdfDzpz4MpWgSrV7FXlc3zIagvLFjS5H+Mk7Snr21vQ6QwrsoCGMfNC4e4LQPdoULEt4ykz0SRQ==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0 + dependencies: + '@babel/core': 7.24.4 + '@babel/helper-environment-visitor': 7.22.20 + '@babel/helper-module-imports': 7.24.3 + '@babel/helper-simple-access': 7.22.5 + '@babel/helper-split-export-declaration': 7.22.6 + '@babel/helper-validator-identifier': 7.22.20 dev: true /@babel/helper-plugin-utils@7.10.4: @@ -6038,15 +5762,15 @@ packages: engines: {node: '>=6.9.0'} dev: true - /@babel/helper-simple-access@7.20.2: - resolution: {integrity: sha512-+0woI/WPq59IrqDYbVGfshjT5Dmk/nnbdpcF8SnMhhXObpTq2KNBdLFRFrkVdbDOyUmHBCxzm5FHV1rACIkIbA==} + /@babel/helper-simple-access@7.22.5: + resolution: {integrity: sha512-n0H99E/K+Bika3++WNL17POvo4rKWZ7lZEp1Q+fStVbUi8nxPQEBOlTmCOxW/0JsS56SKKQ+ojAe2pHKJHN35w==} engines: {node: '>=6.9.0'} dependencies: '@babel/types': 7.24.0 dev: true - /@babel/helper-split-export-declaration@7.18.6: - resolution: {integrity: sha512-bde1etTx6ZyTmobl9LLMMQsaizFVZrquTEHOqKeQESMKo4PlObf+8+JA25ZsIpZhT/WEd39+vOdLXAFG/nELpA==} + /@babel/helper-split-export-declaration@7.22.6: + resolution: {integrity: sha512-AsUnxuLhRYsisFiaJwvp1QF+I3KjD5FOxut14q/GzovUe6orHLesW2C7d754kRm53h5gqrz6sFl6sxc4BVtE/g==} engines: {node: '>=6.9.0'} dependencies: '@babel/types': 7.24.0 @@ -6072,17 +5796,17 @@ packages: engines: {node: '>=6.9.0'} dev: true - /@babel/helper-validator-option@7.18.6: - resolution: {integrity: sha512-XO7gESt5ouv/LRJdrVjkShckw6STTaB7l9BrpBaAHDeF5YZT+01PCwmR0SJHnkW6i8OwW/EVWRShfi4j2x+KQw==} + /@babel/helper-validator-option@7.23.5: + resolution: {integrity: sha512-85ttAOMLsr53VgXkTbkx8oA6YTfT4q7/HzXSLEYmjcSTJPMPQtvq1BD79Byep5xMUYbGRzEpDsjUf3dyp54IKw==} engines: {node: '>=6.9.0'} dev: true - /@babel/helpers@7.20.1: - resolution: {integrity: sha512-J77mUVaDTUJFZ5BpP6mMn6OIl3rEWymk2ZxDBQJUG3P+PbmyMcF3bYWvz0ma69Af1oobDqT/iAsvzhB58xhQUg==} + /@babel/helpers@7.24.4: + resolution: {integrity: sha512-FewdlZbSiwaVGlgT1DPANDuCHaDMiOo+D/IDYRFYjHOuv66xMSJ7fQwwODwRNAPkADIO/z1EoF/l2BCWlWABDw==} engines: {node: '>=6.9.0'} dependencies: - '@babel/template': 7.18.10 - '@babel/traverse': 7.20.1 + '@babel/template': 7.24.0 + '@babel/traverse': 7.24.1 '@babel/types': 7.24.0 transitivePeerDependencies: - supports-color @@ -6097,6 +5821,16 @@ packages: js-tokens: 4.0.0 dev: true + /@babel/highlight@7.24.2: + resolution: {integrity: sha512-Yac1ao4flkTxTteCDZLEvdxg2fZfz1v8M4QpaGypq/WPDqg3ijHYbDfs+LG5hvzSoqaSZ9/Z9lKSP3CjZjv+pA==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/helper-validator-identifier': 7.22.20 + chalk: 2.4.2 + js-tokens: 4.0.0 + picocolors: 1.0.0 + dev: true + /@babel/parser@7.20.3: resolution: {integrity: sha512-OP/s5a94frIPXwjzEcv5S/tpQfc6XhxYUnmWpgdqMWGgYCuErA3SzozaRAMQgSZWKeTJxht9aWAkUY+0UzvOFg==} engines: {node: '>=6.0.0'} @@ -6113,6 +5847,14 @@ packages: '@babel/types': 7.24.0 dev: true + /@babel/parser@7.24.4: + resolution: {integrity: sha512-zTvEBcghmeBma9QIGunWevvBAp4/Qu9Bdq+2k0Ot4fVMD6v3dsC9WOcRSKk7tRRyBM/53yKMJko9xOatGQAwSg==} + 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): resolution: {integrity: sha512-s6SowJIjzlhx8o7lsFx5zmY4At6CTtDvgNQDdPzkBQucle58A6b/TTeEBYtyDgmcXjUTM+vE8YOGHZzzbc/ioA==} peerDependencies: @@ -6124,48 +5866,48 @@ packages: '@babel/plugin-transform-parameters': 7.20.3(@babel/core@7.12.9) dev: true - /@babel/plugin-syntax-async-generators@7.8.4(@babel/core@7.20.2): + /@babel/plugin-syntax-async-generators@7.8.4(@babel/core@7.24.4): resolution: {integrity: sha512-tycmZxkGfZaxhMRbXlPXuVFpdWlXpir2W4AMhSJgRKzk/eDlIXOhb2LHWoLpDF7TEHylV5zNhykX6KAgHJmTNw==} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.20.2 + '@babel/core': 7.24.4 '@babel/helper-plugin-utils': 7.20.2 dev: true - /@babel/plugin-syntax-bigint@7.8.3(@babel/core@7.20.2): + /@babel/plugin-syntax-bigint@7.8.3(@babel/core@7.24.4): resolution: {integrity: sha512-wnTnFlG+YxQm3vDxpGE57Pj0srRU4sHE/mDkt1qv2YJJSeUAec2ma4WLUnUPeKjyrfntVwe/N6dCXpU+zL3Npg==} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.20.2 + '@babel/core': 7.24.4 '@babel/helper-plugin-utils': 7.20.2 dev: true - /@babel/plugin-syntax-class-properties@7.12.13(@babel/core@7.20.2): + /@babel/plugin-syntax-class-properties@7.12.13(@babel/core@7.24.4): resolution: {integrity: sha512-fm4idjKla0YahUNgFNLCB0qySdsoPiZP3iQE3rky0mBUtMZ23yDJ9SJdg6dXTSDnulOVqiF3Hgr9nbXvXTQZYA==} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.20.2 + '@babel/core': 7.24.4 '@babel/helper-plugin-utils': 7.20.2 dev: true - /@babel/plugin-syntax-import-meta@7.10.4(@babel/core@7.20.2): + /@babel/plugin-syntax-import-meta@7.10.4(@babel/core@7.24.4): resolution: {integrity: sha512-Yqfm+XDx0+Prh3VSeEQCPU81yC+JWZ2pDPFSS4ZdpfZhp4MkFMaDC1UqseovEKwSUpnIL7+vK+Clp7bfh0iD7g==} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.20.2 + '@babel/core': 7.24.4 '@babel/helper-plugin-utils': 7.20.2 dev: true - /@babel/plugin-syntax-json-strings@7.8.3(@babel/core@7.20.2): + /@babel/plugin-syntax-json-strings@7.8.3(@babel/core@7.24.4): resolution: {integrity: sha512-lY6kdGpWHvjoe2vk4WrAapEuBR69EMxZl+RoGRhrFGNYVK8mOPAW8VfbT/ZgrFbXlDNiiaxQnAtgVCZ6jv30EA==} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.20.2 + '@babel/core': 7.24.4 '@babel/helper-plugin-utils': 7.20.2 dev: true @@ -6178,40 +5920,40 @@ packages: '@babel/helper-plugin-utils': 7.20.2 dev: true - /@babel/plugin-syntax-jsx@7.18.6(@babel/core@7.20.2): + /@babel/plugin-syntax-jsx@7.18.6(@babel/core@7.24.4): resolution: {integrity: sha512-6mmljtAedFGTWu2p/8WIORGwy+61PLgOMPOdazc7YoJ9ZCWUyFy3A6CpPkRKLKD1ToAesxX8KGEViAiLo9N+7Q==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.20.2 + '@babel/core': 7.24.4 '@babel/helper-plugin-utils': 7.20.2 dev: true - /@babel/plugin-syntax-logical-assignment-operators@7.10.4(@babel/core@7.20.2): + /@babel/plugin-syntax-logical-assignment-operators@7.10.4(@babel/core@7.24.4): resolution: {integrity: sha512-d8waShlpFDinQ5MtvGU9xDAOzKH47+FFoney2baFIoMr952hKOLp1HR7VszoZvOsV/4+RRszNY7D17ba0te0ig==} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.20.2 + '@babel/core': 7.24.4 '@babel/helper-plugin-utils': 7.20.2 dev: true - /@babel/plugin-syntax-nullish-coalescing-operator@7.8.3(@babel/core@7.20.2): + /@babel/plugin-syntax-nullish-coalescing-operator@7.8.3(@babel/core@7.24.4): resolution: {integrity: sha512-aSff4zPII1u2QD7y+F8oDsz19ew4IGEJg9SVW+bqwpwtfFleiQDMdzA/R+UlWDzfnHFCxxleFT0PMIrR36XLNQ==} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.20.2 + '@babel/core': 7.24.4 '@babel/helper-plugin-utils': 7.20.2 dev: true - /@babel/plugin-syntax-numeric-separator@7.10.4(@babel/core@7.20.2): + /@babel/plugin-syntax-numeric-separator@7.10.4(@babel/core@7.24.4): resolution: {integrity: sha512-9H6YdfkcK/uOnY/K7/aA2xpzaAgkQn37yzWUMRK7OaPOqOpGS1+n0H5hxT9AUw9EsSjPW8SVyMJwYRtWs3X3ug==} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.20.2 + '@babel/core': 7.24.4 '@babel/helper-plugin-utils': 7.20.2 dev: true @@ -6224,50 +5966,50 @@ packages: '@babel/helper-plugin-utils': 7.20.2 dev: true - /@babel/plugin-syntax-object-rest-spread@7.8.3(@babel/core@7.20.2): + /@babel/plugin-syntax-object-rest-spread@7.8.3(@babel/core@7.24.4): resolution: {integrity: sha512-XoqMijGZb9y3y2XskN+P1wUGiVwWZ5JmoDRwx5+3GmEplNyVM2s2Dg8ILFQm8rWM48orGy5YpI5Bl8U1y7ydlA==} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.20.2 + '@babel/core': 7.24.4 '@babel/helper-plugin-utils': 7.20.2 dev: true - /@babel/plugin-syntax-optional-catch-binding@7.8.3(@babel/core@7.20.2): + /@babel/plugin-syntax-optional-catch-binding@7.8.3(@babel/core@7.24.4): resolution: {integrity: sha512-6VPD0Pc1lpTqw0aKoeRTMiB+kWhAoT24PA+ksWSBrFtl5SIRVpZlwN3NNPQjehA2E/91FV3RjLWoVTglWcSV3Q==} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.20.2 + '@babel/core': 7.24.4 '@babel/helper-plugin-utils': 7.20.2 dev: true - /@babel/plugin-syntax-optional-chaining@7.8.3(@babel/core@7.20.2): + /@babel/plugin-syntax-optional-chaining@7.8.3(@babel/core@7.24.4): resolution: {integrity: sha512-KoK9ErH1MBlCPxV0VANkXW2/dw4vlbGDrFgz8bmUsBGYkFRcbRwMh6cIJubdPrkxRwuGdtCk0v/wPTKbQgBjkg==} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.20.2 + '@babel/core': 7.24.4 '@babel/helper-plugin-utils': 7.20.2 dev: true - /@babel/plugin-syntax-top-level-await@7.14.5(@babel/core@7.20.2): + /@babel/plugin-syntax-top-level-await@7.14.5(@babel/core@7.24.4): resolution: {integrity: sha512-hx++upLv5U1rgYfwe1xBQUhRmU41NEvpUvrp8jkrSCdvGSnM5/qdRMtylJ6PG5OFkBaHkbTAKTnd3/YyESRHFw==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.20.2 + '@babel/core': 7.24.4 '@babel/helper-plugin-utils': 7.20.2 dev: true - /@babel/plugin-syntax-typescript@7.18.6(@babel/core@7.20.2): + /@babel/plugin-syntax-typescript@7.18.6(@babel/core@7.24.4): resolution: {integrity: sha512-mAWAuq4rvOepWCBid55JuRNvpTNf2UGVgoz4JV0fXEKolsVZDzsa4NqCef758WZJj/GDu0gVGItjKFiClTAmZA==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.20.2 + '@babel/core': 7.24.4 '@babel/helper-plugin-utils': 7.20.2 dev: true @@ -6309,17 +6051,26 @@ packages: '@babel/types': 7.24.0 dev: true - /@babel/traverse@7.20.1: - resolution: {integrity: sha512-d3tN8fkVJwFLkHkBN479SOsw4DMZnz8cdbL/gvuDuzy3TS6Nfw80HuQqhw1pITbIruHyh7d1fMA47kWzmcUEGA==} + /@babel/template@7.24.0: + resolution: {integrity: sha512-Bkf2q8lMB0AFpX0NFEqSbx1OkTHf0f+0j82mkw+ZpzBnkk7e9Ql0891vlfgi+kHwOk8tQjiQHpqh4LaSa0fKEA==} engines: {node: '>=6.9.0'} dependencies: - '@babel/code-frame': 7.22.5 - '@babel/generator': 7.20.4 - '@babel/helper-environment-visitor': 7.18.9 - '@babel/helper-function-name': 7.19.0 - '@babel/helper-hoist-variables': 7.18.6 - '@babel/helper-split-export-declaration': 7.18.6 - '@babel/parser': 7.24.0 + '@babel/code-frame': 7.24.2 + '@babel/parser': 7.24.4 + '@babel/types': 7.24.0 + dev: true + + /@babel/traverse@7.24.1: + resolution: {integrity: sha512-xuU6o9m68KeqZbQuDt2TcKSxUw/mrsvavlEqQ1leZ/B+C9tk6E4sRWy97WaXgvq5E+nU3cXMxv3WKOCanVMCmQ==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/code-frame': 7.24.2 + '@babel/generator': 7.24.4 + '@babel/helper-environment-visitor': 7.22.20 + '@babel/helper-function-name': 7.23.0 + '@babel/helper-hoist-variables': 7.22.5 + '@babel/helper-split-export-declaration': 7.22.6 + '@babel/parser': 7.24.4 '@babel/types': 7.24.0 debug: 4.3.4 globals: 11.12.0 @@ -6581,14 +6332,14 @@ packages: prettier: 2.8.4 dev: true - /@commitlint/cli@19.0.3(@types/node@20.11.20)(typescript@5.0.2): + /@commitlint/cli@19.0.3(@types/node@20.12.7)(typescript@5.0.2): resolution: {integrity: sha512-mGhh/aYPib4Vy4h+AGRloMY+CqkmtdeKPV9poMcZeImF5e3knQ5VYaSeAM0mEzps1dbKsHvABwaDpafLUuM96g==} engines: {node: '>=v18'} hasBin: true dependencies: '@commitlint/format': 19.0.3 '@commitlint/lint': 19.0.3 - '@commitlint/load': 19.0.3(@types/node@20.11.20)(typescript@5.0.2) + '@commitlint/load': 19.0.3(@types/node@20.12.7)(typescript@5.0.2) '@commitlint/read': 19.0.3 '@commitlint/types': 19.0.3 execa: 8.0.1 @@ -6657,7 +6408,7 @@ packages: '@commitlint/types': 19.0.3 dev: true - /@commitlint/load@19.0.3(@types/node@20.11.20)(typescript@5.0.2): + /@commitlint/load@19.0.3(@types/node@20.12.7)(typescript@5.0.2): resolution: {integrity: sha512-18Tk/ZcDFRKIoKfEcl7kC+bYkEQ055iyKmGsYDoYWpKf6FUvBrP9bIWapuy/MB+kYiltmP9ITiUx6UXtqC9IRw==} engines: {node: '>=v18'} dependencies: @@ -6667,7 +6418,7 @@ packages: '@commitlint/types': 19.0.3 chalk: 5.3.0 cosmiconfig: 8.3.6(typescript@5.0.2) - cosmiconfig-typescript-loader: 5.0.0(@types/node@20.11.20)(cosmiconfig@8.3.6)(typescript@5.0.2) + cosmiconfig-typescript-loader: 5.0.0(@types/node@20.12.7)(cosmiconfig@8.3.6)(typescript@5.0.2) lodash.isplainobject: 4.0.6 lodash.merge: 4.6.2 lodash.uniq: 4.5.0 @@ -6759,13 +6510,13 @@ packages: '@csstools/css-tokenizer': 2.0.1 dev: true - /@csstools/css-parser-algorithms@2.6.0(@csstools/css-tokenizer@2.2.3): - resolution: {integrity: sha512-YfEHq0eRH98ffb5/EsrrDspVWAuph6gDggAE74ZtjecsmyyWpW768hOyiONa8zwWGbIWYfa2Xp4tRTrpQQ00CQ==} + /@csstools/css-parser-algorithms@2.6.1(@csstools/css-tokenizer@2.2.4): + resolution: {integrity: sha512-ubEkAaTfVZa+WwGhs5jbo5Xfqpeaybr/RvWzvFxRs4jfq16wH8l8Ty/QEEpINxll4xhuGfdMbipRyz5QZh9+FA==} engines: {node: ^14 || ^16 || >=18} peerDependencies: - '@csstools/css-tokenizer': ^2.2.3 + '@csstools/css-tokenizer': ^2.2.4 dependencies: - '@csstools/css-tokenizer': 2.2.3 + '@csstools/css-tokenizer': 2.2.4 dev: true /@csstools/css-tokenizer@2.0.1: @@ -6773,8 +6524,8 @@ packages: engines: {node: ^14 || ^16 || >=18} dev: true - /@csstools/css-tokenizer@2.2.3: - resolution: {integrity: sha512-pp//EvZ9dUmGuGtG1p+n17gTHEOqu9jO+FiCUjNN3BDmyhdA2Jq9QsVeR7K8/2QCK17HSsioPlTW9ZkzoWb3Lg==} + /@csstools/css-tokenizer@2.2.4: + resolution: {integrity: sha512-PuWRAewQLbDhGeTvFuq2oClaSCKPIBmHyIobCV39JHRYN0byDcUWJl5baPeNUcqrjtdMNqFooE0FGl31I3JOqw==} engines: {node: ^14 || ^16 || >=18} dev: true @@ -6789,15 +6540,15 @@ packages: '@csstools/css-tokenizer': 2.0.1 dev: true - /@csstools/media-query-list-parser@2.1.8(@csstools/css-parser-algorithms@2.6.0)(@csstools/css-tokenizer@2.2.3): - resolution: {integrity: sha512-DiD3vG5ciNzeuTEoh74S+JMjQDs50R3zlxHnBnfd04YYfA/kh2KiBCGhzqLxlJcNq+7yNQ3stuZZYLX6wK/U2g==} + /@csstools/media-query-list-parser@2.1.9(@csstools/css-parser-algorithms@2.6.1)(@csstools/css-tokenizer@2.2.4): + resolution: {integrity: sha512-qqGuFfbn4rUmyOB0u8CVISIp5FfJ5GAR3mBrZ9/TKndHakdnm6pY0L/fbLcpPnrzwCyyTEZl1nUcXAYHEWneTA==} engines: {node: ^14 || ^16 || >=18} peerDependencies: - '@csstools/css-parser-algorithms': ^2.6.0 - '@csstools/css-tokenizer': ^2.2.3 + '@csstools/css-parser-algorithms': ^2.6.1 + '@csstools/css-tokenizer': ^2.2.4 dependencies: - '@csstools/css-parser-algorithms': 2.6.0(@csstools/css-tokenizer@2.2.3) - '@csstools/css-tokenizer': 2.2.3 + '@csstools/css-parser-algorithms': 2.6.1(@csstools/css-tokenizer@2.2.4) + '@csstools/css-tokenizer': 2.2.4 dev: true /@csstools/selector-specificity@2.1.1(postcss-selector-parser@6.0.11)(postcss@8.4.31): @@ -6811,13 +6562,13 @@ packages: postcss-selector-parser: 6.0.11 dev: true - /@csstools/selector-specificity@3.0.2(postcss-selector-parser@6.0.15): - resolution: {integrity: sha512-RpHaZ1h9LE7aALeQXmXrJkRG84ZxIsctEN2biEUmFyKpzFM3zZ35eUMcIzZFsw/2olQE6v69+esEqU2f1MKycg==} + /@csstools/selector-specificity@3.0.3(postcss-selector-parser@6.0.16): + resolution: {integrity: sha512-KEPNw4+WW5AVEIyzC80rTbWEUatTW2lXpN8+8ILC8PiPeWPjwUzrPZDIOZ2wwqDmeqOYTdSGyL3+vE5GC3FB3Q==} engines: {node: ^14 || ^16 || >=18} peerDependencies: postcss-selector-parser: ^6.0.13 dependencies: - postcss-selector-parser: 6.0.15 + postcss-selector-parser: 6.0.16 dev: true /@esbuild/aix-ppc64@0.19.12: @@ -7086,8 +6837,8 @@ packages: engines: {node: '>=14'} dev: false - /@google-cloud/storage@7.3.0: - resolution: {integrity: sha512-el97xKaVLEpSyXcPE9ZuEiBjNeX20wY3KJ2E9oebYNSMWa968PRD2GjePl0qGJIKqIbMobSIwpNzUS0fSQ38pw==} + /@google-cloud/storage@7.10.0: + resolution: {integrity: sha512-aBNejLVzHpI7C8eJSMpBpfdq1lxvYuHqG+zy/xvs032RyPRxuu45DLMeXuAbgwyx1VBsxWGYifrPDx+O7hJrmw==} engines: {node: '>=14'} dependencies: '@google-cloud/paginator': 5.0.0 @@ -7095,16 +6846,14 @@ packages: '@google-cloud/promisify': 4.0.0 abort-controller: 3.0.0 async-retry: 1.3.3 - compressible: 2.0.18 - duplexify: 4.1.2 + duplexify: 4.1.3 ent: 2.2.0 - fast-xml-parser: 4.3.2 + fast-xml-parser: 4.3.6 gaxios: 6.1.1 - google-auth-library: 9.1.0 + google-auth-library: 9.8.0 mime: 3.0.0 - mime-types: 2.1.35 p-limit: 3.1.0 - retry-request: 6.0.0 + retry-request: 7.0.2 teeny-request: 9.0.0 uuid: 8.3.2 transitivePeerDependencies: @@ -7428,7 +7177,7 @@ packages: resolution: {integrity: sha512-ok/BTPFzFKVMwO5eOHRrvnBVHdRy9IrsrW1GpMaQ9MCnilNLXQKmAX8s1YXDFaai9xJpac2ySzV0YeRRECr2Vw==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} dependencies: - '@babel/core': 7.20.2 + '@babel/core': 7.24.4 '@jest/types': 29.6.3 '@jridgewell/trace-mapping': 0.3.25 babel-plugin-istanbul: 6.1.1 @@ -7546,13 +7295,6 @@ packages: resolution: {integrity: sha512-4JQNk+3mVzK3xh2rqd6RB4J46qUR19azEHBneZyTZM+c456qOrbbM/5xcR8huNCCcbVt7+UmizG6GuUvPvKUYg==} dev: true - /@koa/cors@4.0.0: - resolution: {integrity: sha512-Y4RrbvGTlAaa04DBoPBWJqDR5gPj32OOz827ULXfgB1F7piD1MB/zwn8JR2LAnvdILhxUbXbkXGWuNVsFuVFCQ==} - engines: {node: '>= 14.0.0'} - dependencies: - vary: 1.1.2 - dev: false - /@koa/cors@5.0.0: resolution: {integrity: sha512-x/iUDjcS90W69PryLDIMgFyV21YLTnG9zOpPXS7Bkt2b8AsY3zZsIpOLBkYr9fBcF3HbkKaER5hOBZLfpLgYNw==} engines: {node: '>= 14.0.0'} @@ -7560,14 +7302,17 @@ packages: vary: 1.1.2 dev: false - /@koa/router@12.0.0: - resolution: {integrity: sha512-cnnxeKHXlt7XARJptflGURdJaO+ITpNkOHmQu7NHmCoRinPbyvFzce/EG/E8Zy81yQ1W9MoSdtklc3nyaDReUw==} + /@koa/router@12.0.1: + resolution: {integrity: sha512-ribfPYfHb+Uw3b27Eiw6NPqjhIhTpVFzEWLwyc/1Xp+DCdwRRyIlAUODX+9bPARF6aQtUu1+/PHzdNvRzcs/+Q==} engines: {node: '>= 12'} dependencies: + debug: 4.3.4 http-errors: 2.0.0 koa-compose: 4.1.0 methods: 1.1.2 path-to-regexp: 6.2.1 + transitivePeerDependencies: + - supports-color dev: false /@lezer/common@0.15.12: @@ -7746,168 +7491,162 @@ packages: resolution: {integrity: sha512-H1rQc1ZOHANWBvPcW+JpGwr+juXSxM8Q8YCkm3GhZd8REu1fHR3z99CErO1p9pkcfcxZnMdIZdIsXkOHY0NilA==} dev: true - /@microsoft/applicationinsights-analytics-js@3.0.2(tslib@2.4.1)(typescript@5.3.3): - resolution: {integrity: sha512-vrgEiT6cKC2Yb0Y6rCp9CXjFStlRZLI/IhIiBEGYaUfzoytLxUj6F/AizUDYBuNQfE+CTYe0jNyqf+RJgEMkJQ==} + /@microsoft/applicationinsights-analytics-js@3.1.2(tslib@2.4.1): + resolution: {integrity: sha512-HIlptHMIX3cGqTOUrdVjWb5FpYvs1xmosrIf7pnU0Y0/BER382fHCb/4BAB5mU32h/UlPX8to/d6Q20fSCtYAw==} peerDependencies: tslib: '*' dependencies: - '@microsoft/applicationinsights-common': 3.0.2(tslib@2.4.1)(typescript@5.3.3) - '@microsoft/applicationinsights-core-js': 3.0.2(tslib@2.4.1)(typescript@5.3.3) - '@microsoft/applicationinsights-shims': 3.0.1(typescript@5.3.3) - '@microsoft/dynamicproto-js': 2.0.2(typescript@5.3.3) - '@nevware21/ts-utils': 0.9.8(typescript@5.3.3) + '@microsoft/applicationinsights-common': 3.1.2(tslib@2.4.1) + '@microsoft/applicationinsights-core-js': 3.1.2(tslib@2.4.1) + '@microsoft/applicationinsights-shims': 3.0.1 + '@microsoft/dynamicproto-js': 2.0.3 + '@nevware21/ts-utils': 0.11.2 tslib: 2.4.1 - transitivePeerDependencies: - - typescript dev: false - /@microsoft/applicationinsights-channel-js@3.0.2(tslib@2.4.1)(typescript@5.3.3): - resolution: {integrity: sha512-jDBNKbCHsJgmpv0CKNhJ/uN9ZphvfGdb93Svk+R4LjO8L3apNNMbDDPxBvXXi0uigRmA1TBcmyBG4IRKjabGhw==} + /@microsoft/applicationinsights-cfgsync-js@3.1.2(tslib@2.4.1): + resolution: {integrity: sha512-tVrIYxu3SCB/vYGdwPg5Inc8Kr1I9PCbqb/mIp+qOJyIRiB90VIHde6qHsttb7/ZHJJbNlztUtY4UcD5jaCBoA==} peerDependencies: tslib: '*' dependencies: - '@microsoft/applicationinsights-common': 3.0.2(tslib@2.4.1)(typescript@5.3.3) - '@microsoft/applicationinsights-core-js': 3.0.2(tslib@2.4.1)(typescript@5.3.3) - '@microsoft/applicationinsights-shims': 3.0.1(typescript@5.3.3) - '@microsoft/dynamicproto-js': 2.0.2(typescript@5.3.3) - '@nevware21/ts-async': 0.2.6(typescript@5.3.3) - '@nevware21/ts-utils': 0.9.8(typescript@5.3.3) + '@microsoft/applicationinsights-common': 3.1.2(tslib@2.4.1) + '@microsoft/applicationinsights-core-js': 3.1.2(tslib@2.4.1) + '@microsoft/applicationinsights-shims': 3.0.1 + '@microsoft/dynamicproto-js': 2.0.3 + '@nevware21/ts-async': 0.5.1 + '@nevware21/ts-utils': 0.11.2 tslib: 2.4.1 - transitivePeerDependencies: - - typescript dev: false - /@microsoft/applicationinsights-clickanalytics-js@3.0.2(tslib@2.4.1)(typescript@5.3.3): - resolution: {integrity: sha512-qeXDyfxBQUf8Bwvs54rGXNDf7n/rtBW6XD/qt+xYPzNElhWsvYYFMcHKck3LSKqNJ7bozZuaeiwfIcOxPqadUA==} + /@microsoft/applicationinsights-channel-js@3.1.2(tslib@2.4.1): + resolution: {integrity: sha512-QyPxpOOhtohFzcl4tzfWp4seN6JaToF66DZ1qjsYkUmEyHAackWSsv9m7qvuaAcCB9WrUzW9y0mRXgGKsEJcAg==} peerDependencies: tslib: '*' dependencies: - '@microsoft/applicationinsights-common': 3.0.2(tslib@2.4.1)(typescript@5.3.3) - '@microsoft/applicationinsights-core-js': 3.0.2(tslib@2.4.1)(typescript@5.3.3) - '@microsoft/applicationinsights-properties-js': 3.0.2(tslib@2.4.1)(typescript@5.3.3) - '@microsoft/applicationinsights-shims': 3.0.1(typescript@5.3.3) - '@microsoft/dynamicproto-js': 2.0.2(typescript@5.3.3) - '@nevware21/ts-utils': 0.9.8(typescript@5.3.3) + '@microsoft/applicationinsights-common': 3.1.2(tslib@2.4.1) + '@microsoft/applicationinsights-core-js': 3.1.2(tslib@2.4.1) + '@microsoft/applicationinsights-shims': 3.0.1 + '@microsoft/dynamicproto-js': 2.0.3 + '@nevware21/ts-async': 0.5.1 + '@nevware21/ts-utils': 0.11.2 tslib: 2.4.1 - transitivePeerDependencies: - - typescript dev: false - /@microsoft/applicationinsights-common@3.0.2(tslib@2.4.1)(typescript@5.3.3): - resolution: {integrity: sha512-y+WXWop+OVim954Cu1uyYMnNx6PWO8okHpZIQi/1YSqtqaYdtJVPv4P0AVzwJdohxzVfgzKvqj9nec/VWqE2Zg==} + /@microsoft/applicationinsights-clickanalytics-js@3.1.2(tslib@2.4.1): + resolution: {integrity: sha512-zlOip0roNUGyrNb0vnsNSYYs5kETbf6Tlgijueyy9nrY14RbWCcIv0AhIxfM4juLIxlnl6Lo0YYdRe41P9yjng==} peerDependencies: tslib: '*' dependencies: - '@microsoft/applicationinsights-core-js': 3.0.2(tslib@2.4.1)(typescript@5.3.3) - '@microsoft/applicationinsights-shims': 3.0.1(typescript@5.3.3) - '@microsoft/dynamicproto-js': 2.0.2(typescript@5.3.3) - '@nevware21/ts-utils': 0.9.8(typescript@5.3.3) + '@microsoft/applicationinsights-common': 3.1.2(tslib@2.4.1) + '@microsoft/applicationinsights-core-js': 3.1.2(tslib@2.4.1) + '@microsoft/applicationinsights-properties-js': 3.1.2(tslib@2.4.1) + '@microsoft/applicationinsights-shims': 3.0.1 + '@microsoft/dynamicproto-js': 2.0.3 + '@nevware21/ts-utils': 0.11.2 tslib: 2.4.1 - transitivePeerDependencies: - - typescript dev: false - /@microsoft/applicationinsights-core-js@3.0.2(tslib@2.4.1)(typescript@5.3.3): - resolution: {integrity: sha512-WQhVhzlRlLDrQzn3OShCW/pL3BW5WC57t0oywSknX3q7lMzI3jDg7Ihh0iuIcNTzGCTbDkuqr4d6IjEDWIMtJQ==} + /@microsoft/applicationinsights-common@3.1.2(tslib@2.4.1): + resolution: {integrity: sha512-ivu3s73xt6Owakepnx2mbrMCry1mVHrA/2TL4nKCRLad6O3IBK3MkruMoeb3hoWpECBhErFRVj+/b0Kh7dl/Lw==} peerDependencies: tslib: '*' dependencies: - '@microsoft/applicationinsights-shims': 3.0.1(typescript@5.3.3) - '@microsoft/dynamicproto-js': 2.0.2(typescript@5.3.3) - '@nevware21/ts-async': 0.2.6(typescript@5.3.3) - '@nevware21/ts-utils': 0.9.8(typescript@5.3.3) + '@microsoft/applicationinsights-core-js': 3.1.2(tslib@2.4.1) + '@microsoft/applicationinsights-shims': 3.0.1 + '@microsoft/dynamicproto-js': 2.0.3 + '@nevware21/ts-utils': 0.11.2 tslib: 2.4.1 - transitivePeerDependencies: - - typescript dev: false - /@microsoft/applicationinsights-dependencies-js@3.0.2(tslib@2.4.1)(typescript@5.3.3): - resolution: {integrity: sha512-b/YTonnbghg9DOFsLg4zdbYPafW8fPIzV+nZxfPPpxjA1LGvPhZz/zVx9YYWJg2RBXjojLQoJxLf1ro5eNGVig==} + /@microsoft/applicationinsights-core-js@3.1.2(tslib@2.4.1): + resolution: {integrity: sha512-xsJAm52tV355S/MogTunV/m1wg6P6tFg9Yhi4AC2OE9p2aa0k/FYHzWmrCrsEAVimCd8n/iTXmMRSrQk5QpxiA==} peerDependencies: tslib: '*' dependencies: - '@microsoft/applicationinsights-common': 3.0.2(tslib@2.4.1)(typescript@5.3.3) - '@microsoft/applicationinsights-core-js': 3.0.2(tslib@2.4.1)(typescript@5.3.3) - '@microsoft/applicationinsights-shims': 3.0.1(typescript@5.3.3) - '@microsoft/dynamicproto-js': 2.0.2(typescript@5.3.3) - '@nevware21/ts-async': 0.2.6(typescript@5.3.3) - '@nevware21/ts-utils': 0.9.8(typescript@5.3.3) + '@microsoft/applicationinsights-shims': 3.0.1 + '@microsoft/dynamicproto-js': 2.0.3 + '@nevware21/ts-async': 0.5.1 + '@nevware21/ts-utils': 0.11.2 tslib: 2.4.1 - transitivePeerDependencies: - - typescript dev: false - /@microsoft/applicationinsights-properties-js@3.0.2(tslib@2.4.1)(typescript@5.3.3): - resolution: {integrity: sha512-PFqicp8q4Tc0hqfPjwfqKo12gEqTk1l4lMyUUIU7ugE1XOuDkZcMPha05KnZWKj+F4zQXJcetcAHoVkyoyCFQw==} + /@microsoft/applicationinsights-dependencies-js@3.1.2(tslib@2.4.1): + resolution: {integrity: sha512-vFf/6s1ACvcmeDpAAMin2JefPQ+7lthfcNThLFOMPxRxsIKIsQMZ1rHhqd55xcZTNITCywhuK4dD+/YkwC9HPw==} peerDependencies: tslib: '*' dependencies: - '@microsoft/applicationinsights-common': 3.0.2(tslib@2.4.1)(typescript@5.3.3) - '@microsoft/applicationinsights-core-js': 3.0.2(tslib@2.4.1)(typescript@5.3.3) - '@microsoft/applicationinsights-shims': 3.0.1(typescript@5.3.3) - '@microsoft/dynamicproto-js': 2.0.2(typescript@5.3.3) - '@nevware21/ts-utils': 0.9.8(typescript@5.3.3) + '@microsoft/applicationinsights-common': 3.1.2(tslib@2.4.1) + '@microsoft/applicationinsights-core-js': 3.1.2(tslib@2.4.1) + '@microsoft/applicationinsights-shims': 3.0.1 + '@microsoft/dynamicproto-js': 2.0.3 + '@nevware21/ts-async': 0.5.1 + '@nevware21/ts-utils': 0.11.2 + tslib: 2.4.1 + dev: false + + /@microsoft/applicationinsights-properties-js@3.1.2(tslib@2.4.1): + resolution: {integrity: sha512-GK+o/7RyIfySxAIHvw2oba5ca4WyvjE40+1gnRL15Pd/qnRn8+6OIOTpJ4kT1wg2l8CTVtPrUmIK4zeN6MqocA==} + peerDependencies: + tslib: '*' + dependencies: + '@microsoft/applicationinsights-common': 3.1.2(tslib@2.4.1) + '@microsoft/applicationinsights-core-js': 3.1.2(tslib@2.4.1) + '@microsoft/applicationinsights-shims': 3.0.1 + '@microsoft/dynamicproto-js': 2.0.3 + '@nevware21/ts-utils': 0.11.2 tslib: 2.4.1 - transitivePeerDependencies: - - typescript dev: false - /@microsoft/applicationinsights-react-js@17.0.0(history@5.3.0)(react@18.2.0)(tslib@2.4.1)(typescript@5.3.3): - resolution: {integrity: sha512-uKsBEvZDx+588I92gMNFfEinnajrLxxIo4JQMef1QZfGQIurgJPeMO+nGBO8n15nMiJ23j8jfAo1E2mmC9qmBA==} + /@microsoft/applicationinsights-react-js@17.1.2(history@5.3.0)(react@18.2.0)(tslib@2.4.1): + resolution: {integrity: sha512-i98Ep/UQvuLeDWWCWOLuvpF1cACOR98gafpTcOVeZSPKYlUtvFAqx6Xkn7HjjqZklxP9h0Hqjs5dreu4D5nM2A==} peerDependencies: history: '>= 4.10.1' react: '>= 17.0.1 || ^18.0.0' tslib: '*' dependencies: - '@microsoft/applicationinsights-common': 3.0.2(tslib@2.4.1)(typescript@5.3.3) - '@microsoft/applicationinsights-core-js': 3.0.2(tslib@2.4.1)(typescript@5.3.3) - '@microsoft/applicationinsights-shims': 3.0.1(typescript@5.3.3) - '@microsoft/dynamicproto-js': 2.0.2(typescript@5.3.3) + '@microsoft/applicationinsights-common': 3.1.2(tslib@2.4.1) + '@microsoft/applicationinsights-core-js': 3.1.2(tslib@2.4.1) + '@microsoft/applicationinsights-shims': 3.0.1 + '@microsoft/dynamicproto-js': 2.0.3 + '@nevware21/ts-utils': 0.11.2 history: 5.3.0 react: 18.2.0 tslib: 2.4.1 - transitivePeerDependencies: - - typescript dev: false - /@microsoft/applicationinsights-shims@3.0.1(typescript@5.3.3): + /@microsoft/applicationinsights-shims@3.0.1: resolution: {integrity: sha512-DKwboF47H1nb33rSUfjqI6ryX29v+2QWcTrRvcQDA32AZr5Ilkr7whOOSsD1aBzwqX0RJEIP1Z81jfE3NBm/Lg==} dependencies: - '@nevware21/ts-utils': 0.9.8(typescript@5.3.3) - transitivePeerDependencies: - - typescript + '@nevware21/ts-utils': 0.11.2 dev: false /@microsoft/applicationinsights-web-snippet@1.0.1: resolution: {integrity: sha512-2IHAOaLauc8qaAitvWS+U931T+ze+7MNWrDHY47IENP5y2UA0vqJDu67kWZDdpCN1fFC77sfgfB+HV7SrKshnQ==} dev: false - /@microsoft/applicationinsights-web@3.0.2(tslib@2.4.1)(typescript@5.3.3): - resolution: {integrity: sha512-pf2zz/3mmGy1RoyaiLZwhHoE2mFZ+AWR3Zf7xPW7HjTG7dEE4BnovNyW3f9Eu6WWkcHUAHmS/ATzqvVlpB3W6A==} + /@microsoft/applicationinsights-web@3.1.2(tslib@2.4.1): + resolution: {integrity: sha512-q+6RUtKChXrMf2+TN/dohK2p+LUTw8EIYKFtrujYG8/jh88fCdVqmgTCPk9bLb4wsH/dd5wLS+Aw7qVQtlYa9Q==} peerDependencies: tslib: '*' dependencies: - '@microsoft/applicationinsights-analytics-js': 3.0.2(tslib@2.4.1)(typescript@5.3.3) - '@microsoft/applicationinsights-channel-js': 3.0.2(tslib@2.4.1)(typescript@5.3.3) - '@microsoft/applicationinsights-common': 3.0.2(tslib@2.4.1)(typescript@5.3.3) - '@microsoft/applicationinsights-core-js': 3.0.2(tslib@2.4.1)(typescript@5.3.3) - '@microsoft/applicationinsights-dependencies-js': 3.0.2(tslib@2.4.1)(typescript@5.3.3) - '@microsoft/applicationinsights-properties-js': 3.0.2(tslib@2.4.1)(typescript@5.3.3) - '@microsoft/applicationinsights-shims': 3.0.1(typescript@5.3.3) - '@microsoft/dynamicproto-js': 2.0.2(typescript@5.3.3) - '@nevware21/ts-async': 0.2.6(typescript@5.3.3) - '@nevware21/ts-utils': 0.9.8(typescript@5.3.3) + '@microsoft/applicationinsights-analytics-js': 3.1.2(tslib@2.4.1) + '@microsoft/applicationinsights-cfgsync-js': 3.1.2(tslib@2.4.1) + '@microsoft/applicationinsights-channel-js': 3.1.2(tslib@2.4.1) + '@microsoft/applicationinsights-common': 3.1.2(tslib@2.4.1) + '@microsoft/applicationinsights-core-js': 3.1.2(tslib@2.4.1) + '@microsoft/applicationinsights-dependencies-js': 3.1.2(tslib@2.4.1) + '@microsoft/applicationinsights-properties-js': 3.1.2(tslib@2.4.1) + '@microsoft/applicationinsights-shims': 3.0.1 + '@microsoft/dynamicproto-js': 2.0.3 + '@nevware21/ts-async': 0.5.1 + '@nevware21/ts-utils': 0.11.2 tslib: 2.4.1 - transitivePeerDependencies: - - typescript dev: false - /@microsoft/dynamicproto-js@2.0.2(typescript@5.3.3): - resolution: {integrity: sha512-MB8trWaFREpmb037k/d0bB7T2BP7Ai24w1e1tbz3ASLB0/lwphsq3Nq8S9I5AsI5vs4zAQT+SB5nC5/dLYTiOg==} + /@microsoft/dynamicproto-js@2.0.3: + resolution: {integrity: sha512-JTWTU80rMy3mdxOjjpaiDQsTLZ6YSGGqsjURsY6AUQtIj0udlF/jYmhdLZu8693ZIC0T1IwYnFa0+QeiMnziBA==} dependencies: - '@nevware21/ts-utils': 0.9.8(typescript@5.3.3) - transitivePeerDependencies: - - typescript + '@nevware21/ts-utils': 0.11.2 dev: false /@mischnic/json-sourcemap@0.1.0: @@ -7919,24 +7658,24 @@ packages: json5: 2.2.1 dev: true - /@monaco-editor/loader@1.4.0(monaco-editor@0.46.0): + /@monaco-editor/loader@1.4.0(monaco-editor@0.47.0): resolution: {integrity: sha512-00ioBig0x642hytVspPl7DbQyaSWRaolYie/UFNjoTdvoKPzo6xrXLhTk9ixgIKcLH5b5vDOjVNiGyY+uDCUlg==} peerDependencies: monaco-editor: '>= 0.21.0 < 1' dependencies: - monaco-editor: 0.46.0 + monaco-editor: 0.47.0 state-local: 1.0.7 dev: true - /@monaco-editor/react@4.6.0(monaco-editor@0.46.0)(react-dom@18.2.0)(react@18.2.0): + /@monaco-editor/react@4.6.0(monaco-editor@0.47.0)(react-dom@18.2.0)(react@18.2.0): resolution: {integrity: sha512-RFkU9/i7cN2bsq/iTkurMWOEErmYcY6JiQI3Jn+WeR/FGISH8JbHERjpS9oRuSOPvDMJI0Z8nJeKkbOs9sBYQw==} peerDependencies: monaco-editor: '>= 0.25.0 < 1' react: ^16.8.0 || ^17.0.0 || ^18.0.0 react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0 dependencies: - '@monaco-editor/loader': 1.4.0(monaco-editor@0.46.0) - monaco-editor: 0.46.0 + '@monaco-editor/loader': 1.4.0(monaco-editor@0.47.0) + monaco-editor: 0.47.0 react: 18.2.0 react-dom: 18.2.0(react@18.2.0) dev: true @@ -7989,21 +7728,14 @@ packages: dev: true optional: true - /@nevware21/ts-async@0.2.6(typescript@5.3.3): - resolution: {integrity: sha512-NCUqEZSbsy7LVtKlUScd/eTst6djkWauLlzoIPVKCOxalEBdO8lrgNRIm4Xy68JNudNN5faqa2WA12X8m0BVhA==} - peerDependencies: - typescript: '>=1' + /@nevware21/ts-async@0.5.1: + resolution: {integrity: sha512-O2kN8n2HpDWJ7Oji+oTMnhITrCndmrNvrHbGDwAIBydx+FWvLE/vrw4QwnRRMvSCa2AJrcP59Ryklxv30KfkWQ==} dependencies: - '@nevware21/ts-utils': 0.9.8(typescript@5.3.3) - typescript: 5.3.3 + '@nevware21/ts-utils': 0.11.2 dev: false - /@nevware21/ts-utils@0.9.8(typescript@5.3.3): - resolution: {integrity: sha512-kZ8s8hcn9jPVX/M7kSsBYrOGlHjqLahmxrG7QeKTk5paeVwfgKdvVCjj5Acb4UGb/ukU1G34U1Z3eb7bbVanyA==} - peerDependencies: - typescript: '>=1' - dependencies: - typescript: 5.3.3 + /@nevware21/ts-utils@0.11.2: + resolution: {integrity: sha512-80W8BkS09kkGuUHJX50Fqq+QqAslxUaOQytH+3JhRacXs1EpEt2JOOkYKytqFZAYir3SeH9fahniEaDzIBxlUw==} dev: false /@nodelib/fs.scandir@2.1.5: @@ -8027,47 +7759,30 @@ packages: fastq: 1.13.0 dev: true - /@opentelemetry/api@1.4.0: - resolution: {integrity: sha512-IgMK9i3sFGNUqPMbjABm0G26g0QCKCUBfglhQ7rQq6WcxbKfEHRcmwsoER4hZcuYqJgkYn2OeuoJIv7Jsftp7g==} + /@opentelemetry/api@1.8.0: + resolution: {integrity: sha512-I/s6F7yKUDdtMsoBWXJe8Qz40Tui5vsuKCWJEWVL+5q9sSWRzzx6v2KeNsOBEwd94j0eWkpWCH4yB6rZg9Mf0w==} engines: {node: '>=8.0.0'} dev: false - /@opentelemetry/api@1.4.1: - resolution: {integrity: sha512-O2yRJce1GOc6PAy3QxFM4NzFiWzvScDC1/5ihYBL6BUEVdq0XMWN01sppE+H6bBXbaFYipjwFLEWLg5PaSOThA==} - engines: {node: '>=8.0.0'} - dev: false - - /@opentelemetry/core@1.15.0(@opentelemetry/api@1.4.0): - resolution: {integrity: sha512-GGTS6BytfaN8OgbCUOnxg/a9WVsVUj0484zXHZuBzvIXx7V4Tmkb0IHnnhS7Q0cBLNLgjNuvrCpQaP8fIvO4bg==} - engines: {node: '>=14'} - peerDependencies: - '@opentelemetry/api': '>=1.0.0 <1.5.0' - dependencies: - '@opentelemetry/api': 1.4.0 - '@opentelemetry/semantic-conventions': 1.15.0 - tslib: 2.5.0 - dev: false - - /@opentelemetry/core@1.15.0(@opentelemetry/api@1.4.1): - resolution: {integrity: sha512-GGTS6BytfaN8OgbCUOnxg/a9WVsVUj0484zXHZuBzvIXx7V4Tmkb0IHnnhS7Q0cBLNLgjNuvrCpQaP8fIvO4bg==} + /@opentelemetry/core@1.23.0(@opentelemetry/api@1.8.0): + resolution: {integrity: sha512-hdQ/a9TMzMQF/BO8Cz1juA43/L5YGtCSiKoOHmrTEf7VMDAZgy8ucpWx3eQTnQ3gBloRcWtzvcrMZABC3PTSKQ==} engines: {node: '>=14'} peerDependencies: - '@opentelemetry/api': '>=1.0.0 <1.5.0' + '@opentelemetry/api': '>=1.0.0 <1.9.0' dependencies: - '@opentelemetry/api': 1.4.1 - '@opentelemetry/semantic-conventions': 1.15.0 - tslib: 2.5.0 + '@opentelemetry/api': 1.8.0 + '@opentelemetry/semantic-conventions': 1.23.0 dev: false - /@opentelemetry/instrumentation@0.40.0(@opentelemetry/api@1.4.1): - resolution: {integrity: sha512-23TzBKPflUS1uEq5SXymnQKQDSda35KvHjnvxdcDQGE+wg6hwDHgScUCWiBmZW4sxAaPcANfs+Wc9B7yDuyT6Q==} + /@opentelemetry/instrumentation@0.41.2(@opentelemetry/api@1.8.0): + resolution: {integrity: sha512-rxU72E0pKNH6ae2w5+xgVYZLzc5mlxAbGzF4shxMVK8YC2QQsfN38B2GPbj0jvrKWWNUElfclQ+YTykkNg/grw==} engines: {node: '>=14'} peerDependencies: '@opentelemetry/api': ^1.3.0 dependencies: - '@opentelemetry/api': 1.4.1 + '@opentelemetry/api': 1.8.0 '@types/shimmer': 1.0.2 - import-in-the-middle: 1.3.5 + import-in-the-middle: 1.4.2 require-in-the-middle: 7.2.0 semver: 7.6.0 shimmer: 1.2.1 @@ -8075,36 +7790,32 @@ packages: - supports-color dev: false - /@opentelemetry/resources@1.15.0(@opentelemetry/api@1.4.0): - resolution: {integrity: sha512-Sb8A6ZXHXDlgHv32UNRE3y8McWE3vkb5dsSttYArYa5ZpwjiF5ge0vnnKUUnG7bY0AgF9VBIOORZE8gsrnD2WA==} + /@opentelemetry/resources@1.23.0(@opentelemetry/api@1.8.0): + resolution: {integrity: sha512-iPRLfVfcEQynYGo7e4Di+ti+YQTAY0h5mQEUJcHlU9JOqpb4x965O6PZ+wMcwYVY63G96KtdS86YCM1BF1vQZg==} engines: {node: '>=14'} peerDependencies: - '@opentelemetry/api': '>=1.0.0 <1.5.0' + '@opentelemetry/api': '>=1.0.0 <1.9.0' dependencies: - '@opentelemetry/api': 1.4.0 - '@opentelemetry/core': 1.15.0(@opentelemetry/api@1.4.0) - '@opentelemetry/semantic-conventions': 1.15.0 - tslib: 2.5.0 + '@opentelemetry/api': 1.8.0 + '@opentelemetry/core': 1.23.0(@opentelemetry/api@1.8.0) + '@opentelemetry/semantic-conventions': 1.23.0 dev: false - /@opentelemetry/sdk-trace-base@1.15.0(@opentelemetry/api@1.4.0): - resolution: {integrity: sha512-udt1c9VHipbZwvCPIQR1VLg25Z4AMR/g0X8KmcInbFruGWQ/lptVPkz3yvWAsGSta5yHNQ3uoPwcyCygGnQ6Lg==} + /@opentelemetry/sdk-trace-base@1.23.0(@opentelemetry/api@1.8.0): + resolution: {integrity: sha512-PzBmZM8hBomUqvCddF/5Olyyviayka44O5nDWq673np3ctnvwMOvNrsUORZjKja1zJbwEuD9niAGbnVrz3jwRQ==} engines: {node: '>=14'} peerDependencies: - '@opentelemetry/api': '>=1.0.0 <1.5.0' + '@opentelemetry/api': '>=1.0.0 <1.9.0' dependencies: - '@opentelemetry/api': 1.4.0 - '@opentelemetry/core': 1.15.0(@opentelemetry/api@1.4.0) - '@opentelemetry/resources': 1.15.0(@opentelemetry/api@1.4.0) - '@opentelemetry/semantic-conventions': 1.15.0 - tslib: 2.5.0 + '@opentelemetry/api': 1.8.0 + '@opentelemetry/core': 1.23.0(@opentelemetry/api@1.8.0) + '@opentelemetry/resources': 1.23.0(@opentelemetry/api@1.8.0) + '@opentelemetry/semantic-conventions': 1.23.0 dev: false - /@opentelemetry/semantic-conventions@1.15.0: - resolution: {integrity: sha512-f3wwFrFyCpGrFBrFs7lCUJSCSCGyeKG52c+EKeobs3Dd29M75yO6GYkt6PkYPfDawxSlV5p+4yJPPk8tPObzTQ==} + /@opentelemetry/semantic-conventions@1.23.0: + resolution: {integrity: sha512-MiqFvfOzfR31t8cc74CTP1OZfz7MbqpAnLCra8NqQoaHJX6ncIRTdYOQYBDQ2uFISDq0WY8Y9dDTWvsgzzBYRg==} engines: {node: '>=14'} - dependencies: - tslib: 2.5.0 dev: false /@otplib/core@12.0.1: @@ -9309,7 +9020,7 @@ packages: - typescript dev: true - /@silverhand/eslint-config-react@5.0.0(eslint@8.44.0)(postcss@8.4.35)(prettier@3.0.0)(stylelint@15.11.0)(typescript@5.3.3): + /@silverhand/eslint-config-react@5.0.0(eslint@8.44.0)(postcss@8.4.38)(prettier@3.0.0)(stylelint@15.11.0)(typescript@5.3.3): resolution: {integrity: sha512-ZHLke0twGmW73b23mPh1r38fw+4L+XL+9dedml21+OnXpftT3XM00igRocUgdfGTGxbGbQy1n5fLN5gizv5InQ==} engines: {node: ^20.9.0} peerDependencies: @@ -9321,7 +9032,7 @@ packages: eslint-plugin-react: 7.32.2(eslint@8.44.0) eslint-plugin-react-hooks: 4.6.0(eslint@8.44.0) stylelint: 15.11.0(typescript@5.3.3) - stylelint-config-xo-scss: 0.15.0(postcss@8.4.35)(stylelint@15.11.0) + stylelint-config-xo-scss: 0.15.0(postcss@8.4.38)(stylelint@15.11.0) transitivePeerDependencies: - '@types/eslint' - eslint @@ -9509,101 +9220,556 @@ packages: resolution: {integrity: sha512-sXXKG+uL9IrKqViTtao2Ws6dy0znu9sOaP1di/jKGW1M6VssO8vlpXCQcpZ+jisQ1tTFAC5Jo/EOzFbggBagFQ==} dev: true - /@svgr/babel-plugin-add-jsx-attribute@6.5.1(@babel/core@7.20.2): + /@smithy/abort-controller@2.2.0: + resolution: {integrity: sha512-wRlta7GuLWpTqtFfGo+nZyOO1vEvewdNR1R4rTxpC8XU6vG/NDyrFBhwLZsqg1NUoR1noVaXJPC/7ZK47QCySw==} + engines: {node: '>=14.0.0'} + dependencies: + '@smithy/types': 2.12.0 + tslib: 2.6.2 + dev: false + + /@smithy/chunked-blob-reader-native@2.2.0: + resolution: {integrity: sha512-VNB5+1oCgX3Fzs072yuRsUoC2N4Zg/LJ11DTxX3+Qu+Paa6AmbIF0E9sc2wthz9Psrk/zcOlTCyuposlIhPjZQ==} + dependencies: + '@smithy/util-base64': 2.3.0 + tslib: 2.6.2 + dev: false + + /@smithy/chunked-blob-reader@2.2.0: + resolution: {integrity: sha512-3GJNvRwXBGdkDZZOGiziVYzDpn4j6zfyULHMDKAGIUo72yHALpE9CbhfQp/XcLNVoc1byfMpn6uW5H2BqPjgaQ==} + dependencies: + tslib: 2.6.2 + dev: false + + /@smithy/config-resolver@2.2.0: + resolution: {integrity: sha512-fsiMgd8toyUba6n1WRmr+qACzXltpdDkPTAaDqc8QqPBUzO+/JKwL6bUBseHVi8tu9l+3JOK+tSf7cay+4B3LA==} + engines: {node: '>=14.0.0'} + dependencies: + '@smithy/node-config-provider': 2.3.0 + '@smithy/types': 2.12.0 + '@smithy/util-config-provider': 2.3.0 + '@smithy/util-middleware': 2.2.0 + tslib: 2.6.2 + dev: false + + /@smithy/core@1.4.2: + resolution: {integrity: sha512-2fek3I0KZHWJlRLvRTqxTEri+qV0GRHrJIoLFuBMZB4EMg4WgeBGfF0X6abnrNYpq55KJ6R4D6x4f0vLnhzinA==} + engines: {node: '>=14.0.0'} + dependencies: + '@smithy/middleware-endpoint': 2.5.1 + '@smithy/middleware-retry': 2.3.1 + '@smithy/middleware-serde': 2.3.0 + '@smithy/protocol-http': 3.3.0 + '@smithy/smithy-client': 2.5.1 + '@smithy/types': 2.12.0 + '@smithy/util-middleware': 2.2.0 + tslib: 2.6.2 + dev: false + + /@smithy/credential-provider-imds@2.3.0: + resolution: {integrity: sha512-BWB9mIukO1wjEOo1Ojgl6LrG4avcaC7T/ZP6ptmAaW4xluhSIPZhY+/PI5YKzlk+jsm+4sQZB45Bt1OfMeQa3w==} + engines: {node: '>=14.0.0'} + dependencies: + '@smithy/node-config-provider': 2.3.0 + '@smithy/property-provider': 2.2.0 + '@smithy/types': 2.12.0 + '@smithy/url-parser': 2.2.0 + tslib: 2.6.2 + dev: false + + /@smithy/eventstream-codec@2.2.0: + resolution: {integrity: sha512-8janZoJw85nJmQZc4L8TuePp2pk1nxLgkxIR0TUjKJ5Dkj5oelB9WtiSSGXCQvNsJl0VSTvK/2ueMXxvpa9GVw==} + dependencies: + '@aws-crypto/crc32': 3.0.0 + '@smithy/types': 2.12.0 + '@smithy/util-hex-encoding': 2.2.0 + tslib: 2.6.2 + dev: false + + /@smithy/eventstream-serde-browser@2.2.0: + resolution: {integrity: sha512-UaPf8jKbcP71BGiO0CdeLmlg+RhWnlN8ipsMSdwvqBFigl5nil3rHOI/5GE3tfiuX8LvY5Z9N0meuU7Rab7jWw==} + engines: {node: '>=14.0.0'} + dependencies: + '@smithy/eventstream-serde-universal': 2.2.0 + '@smithy/types': 2.12.0 + tslib: 2.6.2 + dev: false + + /@smithy/eventstream-serde-config-resolver@2.2.0: + resolution: {integrity: sha512-RHhbTw/JW3+r8QQH7PrganjNCiuiEZmpi6fYUAetFfPLfZ6EkiA08uN3EFfcyKubXQxOwTeJRZSQmDDCdUshaA==} + engines: {node: '>=14.0.0'} + dependencies: + '@smithy/types': 2.12.0 + tslib: 2.6.2 + dev: false + + /@smithy/eventstream-serde-node@2.2.0: + resolution: {integrity: sha512-zpQMtJVqCUMn+pCSFcl9K/RPNtQE0NuMh8sKpCdEHafhwRsjP50Oq/4kMmvxSRy6d8Jslqd8BLvDngrUtmN9iA==} + engines: {node: '>=14.0.0'} + dependencies: + '@smithy/eventstream-serde-universal': 2.2.0 + '@smithy/types': 2.12.0 + tslib: 2.6.2 + dev: false + + /@smithy/eventstream-serde-universal@2.2.0: + resolution: {integrity: sha512-pvoe/vvJY0mOpuF84BEtyZoYfbehiFj8KKWk1ds2AT0mTLYFVs+7sBJZmioOFdBXKd48lfrx1vumdPdmGlCLxA==} + engines: {node: '>=14.0.0'} + dependencies: + '@smithy/eventstream-codec': 2.2.0 + '@smithy/types': 2.12.0 + tslib: 2.6.2 + dev: false + + /@smithy/fetch-http-handler@2.5.0: + resolution: {integrity: sha512-BOWEBeppWhLn/no/JxUL/ghTfANTjT7kg3Ww2rPqTUY9R4yHPXxJ9JhMe3Z03LN3aPwiwlpDIUcVw1xDyHqEhw==} + dependencies: + '@smithy/protocol-http': 3.3.0 + '@smithy/querystring-builder': 2.2.0 + '@smithy/types': 2.12.0 + '@smithy/util-base64': 2.3.0 + tslib: 2.6.2 + dev: false + + /@smithy/hash-blob-browser@2.2.0: + resolution: {integrity: sha512-SGPoVH8mdXBqrkVCJ1Hd1X7vh1zDXojNN1yZyZTZsCno99hVue9+IYzWDjq/EQDDXxmITB0gBmuyPh8oAZSTcg==} + dependencies: + '@smithy/chunked-blob-reader': 2.2.0 + '@smithy/chunked-blob-reader-native': 2.2.0 + '@smithy/types': 2.12.0 + tslib: 2.6.2 + dev: false + + /@smithy/hash-node@2.2.0: + resolution: {integrity: sha512-zLWaC/5aWpMrHKpoDF6nqpNtBhlAYKF/7+9yMN7GpdR8CzohnWfGtMznPybnwSS8saaXBMxIGwJqR4HmRp6b3g==} + engines: {node: '>=14.0.0'} + dependencies: + '@smithy/types': 2.12.0 + '@smithy/util-buffer-from': 2.2.0 + '@smithy/util-utf8': 2.3.0 + tslib: 2.6.2 + dev: false + + /@smithy/hash-stream-node@2.2.0: + resolution: {integrity: sha512-aT+HCATOSRMGpPI7bi7NSsTNVZE/La9IaxLXWoVAYMxHT5hGO3ZOGEMZQg8A6nNL+pdFGtZQtND1eoY084HgHQ==} + engines: {node: '>=14.0.0'} + dependencies: + '@smithy/types': 2.12.0 + '@smithy/util-utf8': 2.3.0 + tslib: 2.6.2 + dev: false + + /@smithy/invalid-dependency@2.2.0: + resolution: {integrity: sha512-nEDASdbKFKPXN2O6lOlTgrEEOO9NHIeO+HVvZnkqc8h5U9g3BIhWsvzFo+UcUbliMHvKNPD/zVxDrkP1Sbgp8Q==} + dependencies: + '@smithy/types': 2.12.0 + tslib: 2.6.2 + dev: false + + /@smithy/is-array-buffer@2.2.0: + resolution: {integrity: sha512-GGP3O9QFD24uGeAXYUjwSTXARoqpZykHadOmA8G5vfJPK0/DC67qa//0qvqrJzL1xc8WQWX7/yc7fwudjPHPhA==} + engines: {node: '>=14.0.0'} + dependencies: + tslib: 2.6.2 + dev: false + + /@smithy/md5-js@2.2.0: + resolution: {integrity: sha512-M26XTtt9IIusVMOWEAhIvFIr9jYj4ISPPGJROqw6vXngO3IYJCnVVSMFn4Tx1rUTG5BiKJNg9u2nxmBiZC5IlQ==} + dependencies: + '@smithy/types': 2.12.0 + '@smithy/util-utf8': 2.3.0 + tslib: 2.6.2 + dev: false + + /@smithy/middleware-content-length@2.2.0: + resolution: {integrity: sha512-5bl2LG1Ah/7E5cMSC+q+h3IpVHMeOkG0yLRyQT1p2aMJkSrZG7RlXHPuAgb7EyaFeidKEnnd/fNaLLaKlHGzDQ==} + engines: {node: '>=14.0.0'} + dependencies: + '@smithy/protocol-http': 3.3.0 + '@smithy/types': 2.12.0 + tslib: 2.6.2 + dev: false + + /@smithy/middleware-endpoint@2.5.1: + resolution: {integrity: sha512-1/8kFp6Fl4OsSIVTWHnNjLnTL8IqpIb/D3sTSczrKFnrE9VMNWxnrRKNvpUHOJ6zpGD5f62TPm7+17ilTJpiCQ==} + engines: {node: '>=14.0.0'} + dependencies: + '@smithy/middleware-serde': 2.3.0 + '@smithy/node-config-provider': 2.3.0 + '@smithy/shared-ini-file-loader': 2.4.0 + '@smithy/types': 2.12.0 + '@smithy/url-parser': 2.2.0 + '@smithy/util-middleware': 2.2.0 + tslib: 2.6.2 + dev: false + + /@smithy/middleware-retry@2.3.1: + resolution: {integrity: sha512-P2bGufFpFdYcWvqpyqqmalRtwFUNUA8vHjJR5iGqbfR6mp65qKOLcUd6lTr4S9Gn/enynSrSf3p3FVgVAf6bXA==} + engines: {node: '>=14.0.0'} + dependencies: + '@smithy/node-config-provider': 2.3.0 + '@smithy/protocol-http': 3.3.0 + '@smithy/service-error-classification': 2.1.5 + '@smithy/smithy-client': 2.5.1 + '@smithy/types': 2.12.0 + '@smithy/util-middleware': 2.2.0 + '@smithy/util-retry': 2.2.0 + tslib: 2.6.2 + uuid: 9.0.1 + dev: false + + /@smithy/middleware-serde@2.3.0: + resolution: {integrity: sha512-sIADe7ojwqTyvEQBe1nc/GXB9wdHhi9UwyX0lTyttmUWDJLP655ZYE1WngnNyXREme8I27KCaUhyhZWRXL0q7Q==} + engines: {node: '>=14.0.0'} + dependencies: + '@smithy/types': 2.12.0 + tslib: 2.6.2 + dev: false + + /@smithy/middleware-stack@2.2.0: + resolution: {integrity: sha512-Qntc3jrtwwrsAC+X8wms8zhrTr0sFXnyEGhZd9sLtsJ/6gGQKFzNB+wWbOcpJd7BR8ThNCoKt76BuQahfMvpeA==} + engines: {node: '>=14.0.0'} + dependencies: + '@smithy/types': 2.12.0 + tslib: 2.6.2 + dev: false + + /@smithy/node-config-provider@2.3.0: + resolution: {integrity: sha512-0elK5/03a1JPWMDPaS726Iw6LpQg80gFut1tNpPfxFuChEEklo2yL823V94SpTZTxmKlXFtFgsP55uh3dErnIg==} + engines: {node: '>=14.0.0'} + dependencies: + '@smithy/property-provider': 2.2.0 + '@smithy/shared-ini-file-loader': 2.4.0 + '@smithy/types': 2.12.0 + tslib: 2.6.2 + dev: false + + /@smithy/node-http-handler@2.5.0: + resolution: {integrity: sha512-mVGyPBzkkGQsPoxQUbxlEfRjrj6FPyA3u3u2VXGr9hT8wilsoQdZdvKpMBFMB8Crfhv5dNkKHIW0Yyuc7eABqA==} + engines: {node: '>=14.0.0'} + dependencies: + '@smithy/abort-controller': 2.2.0 + '@smithy/protocol-http': 3.3.0 + '@smithy/querystring-builder': 2.2.0 + '@smithy/types': 2.12.0 + tslib: 2.6.2 + dev: false + + /@smithy/property-provider@2.2.0: + resolution: {integrity: sha512-+xiil2lFhtTRzXkx8F053AV46QnIw6e7MV8od5Mi68E1ICOjCeCHw2XfLnDEUHnT9WGUIkwcqavXjfwuJbGlpg==} + engines: {node: '>=14.0.0'} + dependencies: + '@smithy/types': 2.12.0 + tslib: 2.6.2 + dev: false + + /@smithy/protocol-http@3.3.0: + resolution: {integrity: sha512-Xy5XK1AFWW2nlY/biWZXu6/krgbaf2dg0q492D8M5qthsnU2H+UgFeZLbM76FnH7s6RO/xhQRkj+T6KBO3JzgQ==} + engines: {node: '>=14.0.0'} + dependencies: + '@smithy/types': 2.12.0 + tslib: 2.6.2 + dev: false + + /@smithy/querystring-builder@2.2.0: + resolution: {integrity: sha512-L1kSeviUWL+emq3CUVSgdogoM/D9QMFaqxL/dd0X7PCNWmPXqt+ExtrBjqT0V7HLN03Vs9SuiLrG3zy3JGnE5A==} + engines: {node: '>=14.0.0'} + dependencies: + '@smithy/types': 2.12.0 + '@smithy/util-uri-escape': 2.2.0 + tslib: 2.6.2 + dev: false + + /@smithy/querystring-parser@2.2.0: + resolution: {integrity: sha512-BvHCDrKfbG5Yhbpj4vsbuPV2GgcpHiAkLeIlcA1LtfpMz3jrqizP1+OguSNSj1MwBHEiN+jwNisXLGdajGDQJA==} + engines: {node: '>=14.0.0'} + dependencies: + '@smithy/types': 2.12.0 + tslib: 2.6.2 + dev: false + + /@smithy/service-error-classification@2.1.5: + resolution: {integrity: sha512-uBDTIBBEdAQryvHdc5W8sS5YX7RQzF683XrHePVdFmAgKiMofU15FLSM0/HU03hKTnazdNRFa0YHS7+ArwoUSQ==} + engines: {node: '>=14.0.0'} + dependencies: + '@smithy/types': 2.12.0 + dev: false + + /@smithy/shared-ini-file-loader@2.4.0: + resolution: {integrity: sha512-WyujUJL8e1B6Z4PBfAqC/aGY1+C7T0w20Gih3yrvJSk97gpiVfB+y7c46T4Nunk+ZngLq0rOIdeVeIklk0R3OA==} + engines: {node: '>=14.0.0'} + dependencies: + '@smithy/types': 2.12.0 + tslib: 2.6.2 + dev: false + + /@smithy/signature-v4@2.3.0: + resolution: {integrity: sha512-ui/NlpILU+6HAQBfJX8BBsDXuKSNrjTSuOYArRblcrErwKFutjrCNb/OExfVRyj9+26F9J+ZmfWT+fKWuDrH3Q==} + engines: {node: '>=14.0.0'} + dependencies: + '@smithy/is-array-buffer': 2.2.0 + '@smithy/types': 2.12.0 + '@smithy/util-hex-encoding': 2.2.0 + '@smithy/util-middleware': 2.2.0 + '@smithy/util-uri-escape': 2.2.0 + '@smithy/util-utf8': 2.3.0 + tslib: 2.6.2 + dev: false + + /@smithy/smithy-client@2.5.1: + resolution: {integrity: sha512-jrbSQrYCho0yDaaf92qWgd+7nAeap5LtHTI51KXqmpIFCceKU3K9+vIVTUH72bOJngBMqa4kyu1VJhRcSrk/CQ==} + engines: {node: '>=14.0.0'} + dependencies: + '@smithy/middleware-endpoint': 2.5.1 + '@smithy/middleware-stack': 2.2.0 + '@smithy/protocol-http': 3.3.0 + '@smithy/types': 2.12.0 + '@smithy/util-stream': 2.2.0 + tslib: 2.6.2 + dev: false + + /@smithy/types@2.12.0: + resolution: {integrity: sha512-QwYgloJ0sVNBeBuBs65cIkTbfzV/Q6ZNPCJ99EICFEdJYG50nGIY/uYXp+TbsdJReIuPr0a0kXmCvren3MbRRw==} + engines: {node: '>=14.0.0'} + dependencies: + tslib: 2.6.2 + dev: false + + /@smithy/url-parser@2.2.0: + resolution: {integrity: sha512-hoA4zm61q1mNTpksiSWp2nEl1dt3j726HdRhiNgVJQMj7mLp7dprtF57mOB6JvEk/x9d2bsuL5hlqZbBuHQylQ==} + dependencies: + '@smithy/querystring-parser': 2.2.0 + '@smithy/types': 2.12.0 + tslib: 2.6.2 + dev: false + + /@smithy/util-base64@2.3.0: + resolution: {integrity: sha512-s3+eVwNeJuXUwuMbusncZNViuhv2LjVJ1nMwTqSA0XAC7gjKhqqxRdJPhR8+YrkoZ9IiIbFk/yK6ACe/xlF+hw==} + engines: {node: '>=14.0.0'} + dependencies: + '@smithy/util-buffer-from': 2.2.0 + '@smithy/util-utf8': 2.3.0 + tslib: 2.6.2 + dev: false + + /@smithy/util-body-length-browser@2.2.0: + resolution: {integrity: sha512-dtpw9uQP7W+n3vOtx0CfBD5EWd7EPdIdsQnWTDoFf77e3VUf05uA7R7TGipIo8e4WL2kuPdnsr3hMQn9ziYj5w==} + dependencies: + tslib: 2.6.2 + dev: false + + /@smithy/util-body-length-node@2.3.0: + resolution: {integrity: sha512-ITWT1Wqjubf2CJthb0BuT9+bpzBfXeMokH/AAa5EJQgbv9aPMVfnM76iFIZVFf50hYXGbtiV71BHAthNWd6+dw==} + engines: {node: '>=14.0.0'} + dependencies: + tslib: 2.6.2 + dev: false + + /@smithy/util-buffer-from@2.2.0: + resolution: {integrity: sha512-IJdWBbTcMQ6DA0gdNhh/BwrLkDR+ADW5Kr1aZmd4k3DIF6ezMV4R2NIAmT08wQJ3yUK82thHWmC/TnK/wpMMIA==} + engines: {node: '>=14.0.0'} + dependencies: + '@smithy/is-array-buffer': 2.2.0 + tslib: 2.6.2 + dev: false + + /@smithy/util-config-provider@2.3.0: + resolution: {integrity: sha512-HZkzrRcuFN1k70RLqlNK4FnPXKOpkik1+4JaBoHNJn+RnJGYqaa3c5/+XtLOXhlKzlRgNvyaLieHTW2VwGN0VQ==} + engines: {node: '>=14.0.0'} + dependencies: + tslib: 2.6.2 + dev: false + + /@smithy/util-defaults-mode-browser@2.2.1: + resolution: {integrity: sha512-RtKW+8j8skk17SYowucwRUjeh4mCtnm5odCL0Lm2NtHQBsYKrNW0od9Rhopu9wF1gHMfHeWF7i90NwBz/U22Kw==} + engines: {node: '>= 10.0.0'} + dependencies: + '@smithy/property-provider': 2.2.0 + '@smithy/smithy-client': 2.5.1 + '@smithy/types': 2.12.0 + bowser: 2.11.0 + tslib: 2.6.2 + dev: false + + /@smithy/util-defaults-mode-node@2.3.1: + resolution: {integrity: sha512-vkMXHQ0BcLFysBMWgSBLSk3+leMpFSyyFj8zQtv5ZyUBx8/owVh1/pPEkzmW/DR/Gy/5c8vjLDD9gZjXNKbrpA==} + engines: {node: '>= 10.0.0'} + dependencies: + '@smithy/config-resolver': 2.2.0 + '@smithy/credential-provider-imds': 2.3.0 + '@smithy/node-config-provider': 2.3.0 + '@smithy/property-provider': 2.2.0 + '@smithy/smithy-client': 2.5.1 + '@smithy/types': 2.12.0 + tslib: 2.6.2 + dev: false + + /@smithy/util-endpoints@1.2.0: + resolution: {integrity: sha512-BuDHv8zRjsE5zXd3PxFXFknzBG3owCpjq8G3FcsXW3CykYXuEqM3nTSsmLzw5q+T12ZYuDlVUZKBdpNbhVtlrQ==} + engines: {node: '>= 14.0.0'} + dependencies: + '@smithy/node-config-provider': 2.3.0 + '@smithy/types': 2.12.0 + tslib: 2.6.2 + dev: false + + /@smithy/util-hex-encoding@2.2.0: + resolution: {integrity: sha512-7iKXR+/4TpLK194pVjKiasIyqMtTYJsgKgM242Y9uzt5dhHnUDvMNb+3xIhRJ9QhvqGii/5cRUt4fJn3dtXNHQ==} + engines: {node: '>=14.0.0'} + dependencies: + tslib: 2.6.2 + dev: false + + /@smithy/util-middleware@2.2.0: + resolution: {integrity: sha512-L1qpleXf9QD6LwLCJ5jddGkgWyuSvWBkJwWAZ6kFkdifdso+sk3L3O1HdmPvCdnCK3IS4qWyPxev01QMnfHSBw==} + engines: {node: '>=14.0.0'} + dependencies: + '@smithy/types': 2.12.0 + tslib: 2.6.2 + dev: false + + /@smithy/util-retry@2.2.0: + resolution: {integrity: sha512-q9+pAFPTfftHXRytmZ7GzLFFrEGavqapFc06XxzZFcSIGERXMerXxCitjOG1prVDR9QdjqotF40SWvbqcCpf8g==} + engines: {node: '>= 14.0.0'} + dependencies: + '@smithy/service-error-classification': 2.1.5 + '@smithy/types': 2.12.0 + tslib: 2.6.2 + dev: false + + /@smithy/util-stream@2.2.0: + resolution: {integrity: sha512-17faEXbYWIRst1aU9SvPZyMdWmqIrduZjVOqCPMIsWFNxs5yQQgFrJL6b2SdiCzyW9mJoDjFtgi53xx7EH+BXA==} + engines: {node: '>=14.0.0'} + dependencies: + '@smithy/fetch-http-handler': 2.5.0 + '@smithy/node-http-handler': 2.5.0 + '@smithy/types': 2.12.0 + '@smithy/util-base64': 2.3.0 + '@smithy/util-buffer-from': 2.2.0 + '@smithy/util-hex-encoding': 2.2.0 + '@smithy/util-utf8': 2.3.0 + tslib: 2.6.2 + dev: false + + /@smithy/util-uri-escape@2.2.0: + resolution: {integrity: sha512-jtmJMyt1xMD/d8OtbVJ2gFZOSKc+ueYJZPW20ULW1GOp/q/YIM0wNh+u8ZFao9UaIGz4WoPW8hC64qlWLIfoDA==} + engines: {node: '>=14.0.0'} + dependencies: + tslib: 2.6.2 + dev: false + + /@smithy/util-utf8@2.3.0: + resolution: {integrity: sha512-R8Rdn8Hy72KKcebgLiv8jQcQkXoLMOGGv5uI1/k0l+snqkOzQ1R0ChUBCxWMlBsFMekWjq0wRudIweFs7sKT5A==} + engines: {node: '>=14.0.0'} + dependencies: + '@smithy/util-buffer-from': 2.2.0 + tslib: 2.6.2 + dev: false + + /@smithy/util-waiter@2.2.0: + resolution: {integrity: sha512-IHk53BVw6MPMi2Gsn+hCng8rFA3ZmR3Rk7GllxDUW9qFJl/hiSvskn7XldkECapQVkIg/1dHpMAxI9xSTaLLSA==} + engines: {node: '>=14.0.0'} + dependencies: + '@smithy/abort-controller': 2.2.0 + '@smithy/types': 2.12.0 + tslib: 2.6.2 + dev: false + + /@svgr/babel-plugin-add-jsx-attribute@6.5.1(@babel/core@7.24.4): resolution: {integrity: sha512-9PYGcXrAxitycIjRmZB+Q0JaN07GZIWaTBIGQzfaZv+qr1n8X1XUEJ5rZ/vx6OVD9RRYlrNnXWExQXcmZeD/BQ==} engines: {node: '>=10'} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.20.2 + '@babel/core': 7.24.4 dev: true - /@svgr/babel-plugin-remove-jsx-attribute@6.5.0(@babel/core@7.20.2): + /@svgr/babel-plugin-remove-jsx-attribute@6.5.0(@babel/core@7.24.4): resolution: {integrity: sha512-8zYdkym7qNyfXpWvu4yq46k41pyNM9SOstoWhKlm+IfdCE1DdnRKeMUPsWIEO/DEkaWxJ8T9esNdG3QwQ93jBA==} engines: {node: '>=10'} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.20.2 + '@babel/core': 7.24.4 dev: true - /@svgr/babel-plugin-remove-jsx-empty-expression@6.5.0(@babel/core@7.20.2): + /@svgr/babel-plugin-remove-jsx-empty-expression@6.5.0(@babel/core@7.24.4): resolution: {integrity: sha512-NFdxMq3xA42Kb1UbzCVxplUc0iqSyM9X8kopImvFnB+uSDdzIHOdbs1op8ofAvVRtbg4oZiyRl3fTYeKcOe9Iw==} engines: {node: '>=10'} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.20.2 + '@babel/core': 7.24.4 dev: true - /@svgr/babel-plugin-replace-jsx-attribute-value@6.5.1(@babel/core@7.20.2): + /@svgr/babel-plugin-replace-jsx-attribute-value@6.5.1(@babel/core@7.24.4): resolution: {integrity: sha512-8DPaVVE3fd5JKuIC29dqyMB54sA6mfgki2H2+swh+zNJoynC8pMPzOkidqHOSc6Wj032fhl8Z0TVn1GiPpAiJg==} engines: {node: '>=10'} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.20.2 + '@babel/core': 7.24.4 dev: true - /@svgr/babel-plugin-svg-dynamic-title@6.5.1(@babel/core@7.20.2): + /@svgr/babel-plugin-svg-dynamic-title@6.5.1(@babel/core@7.24.4): resolution: {integrity: sha512-FwOEi0Il72iAzlkaHrlemVurgSQRDFbk0OC8dSvD5fSBPHltNh7JtLsxmZUhjYBZo2PpcU/RJvvi6Q0l7O7ogw==} engines: {node: '>=10'} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.20.2 + '@babel/core': 7.24.4 dev: true - /@svgr/babel-plugin-svg-em-dimensions@6.5.1(@babel/core@7.20.2): + /@svgr/babel-plugin-svg-em-dimensions@6.5.1(@babel/core@7.24.4): resolution: {integrity: sha512-gWGsiwjb4tw+ITOJ86ndY/DZZ6cuXMNE/SjcDRg+HLuCmwpcjOktwRF9WgAiycTqJD/QXqL2f8IzE2Rzh7aVXA==} engines: {node: '>=10'} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.20.2 + '@babel/core': 7.24.4 dev: true - /@svgr/babel-plugin-transform-react-native-svg@6.5.1(@babel/core@7.20.2): + /@svgr/babel-plugin-transform-react-native-svg@6.5.1(@babel/core@7.24.4): resolution: {integrity: sha512-2jT3nTayyYP7kI6aGutkyfJ7UMGtuguD72OjeGLwVNyfPRBD8zQthlvL+fAbAKk5n9ZNcvFkp/b1lZ7VsYqVJg==} engines: {node: '>=10'} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.20.2 + '@babel/core': 7.24.4 dev: true - /@svgr/babel-plugin-transform-svg-component@6.5.1(@babel/core@7.20.2): + /@svgr/babel-plugin-transform-svg-component@6.5.1(@babel/core@7.24.4): resolution: {integrity: sha512-a1p6LF5Jt33O3rZoVRBqdxL350oge54iZWHNI6LJB5tQ7EelvD/Mb1mfBiZNAan0dt4i3VArkFRjA4iObuNykQ==} engines: {node: '>=12'} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.20.2 + '@babel/core': 7.24.4 dev: true - /@svgr/babel-preset@6.5.1(@babel/core@7.20.2): + /@svgr/babel-preset@6.5.1(@babel/core@7.24.4): resolution: {integrity: sha512-6127fvO/FF2oi5EzSQOAjo1LE3OtNVh11R+/8FXa+mHx1ptAaS4cknIjnUA7e6j6fwGGJ17NzaTJFUwOV2zwCw==} engines: {node: '>=10'} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.20.2 - '@svgr/babel-plugin-add-jsx-attribute': 6.5.1(@babel/core@7.20.2) - '@svgr/babel-plugin-remove-jsx-attribute': 6.5.0(@babel/core@7.20.2) - '@svgr/babel-plugin-remove-jsx-empty-expression': 6.5.0(@babel/core@7.20.2) - '@svgr/babel-plugin-replace-jsx-attribute-value': 6.5.1(@babel/core@7.20.2) - '@svgr/babel-plugin-svg-dynamic-title': 6.5.1(@babel/core@7.20.2) - '@svgr/babel-plugin-svg-em-dimensions': 6.5.1(@babel/core@7.20.2) - '@svgr/babel-plugin-transform-react-native-svg': 6.5.1(@babel/core@7.20.2) - '@svgr/babel-plugin-transform-svg-component': 6.5.1(@babel/core@7.20.2) + '@babel/core': 7.24.4 + '@svgr/babel-plugin-add-jsx-attribute': 6.5.1(@babel/core@7.24.4) + '@svgr/babel-plugin-remove-jsx-attribute': 6.5.0(@babel/core@7.24.4) + '@svgr/babel-plugin-remove-jsx-empty-expression': 6.5.0(@babel/core@7.24.4) + '@svgr/babel-plugin-replace-jsx-attribute-value': 6.5.1(@babel/core@7.24.4) + '@svgr/babel-plugin-svg-dynamic-title': 6.5.1(@babel/core@7.24.4) + '@svgr/babel-plugin-svg-em-dimensions': 6.5.1(@babel/core@7.24.4) + '@svgr/babel-plugin-transform-react-native-svg': 6.5.1(@babel/core@7.24.4) + '@svgr/babel-plugin-transform-svg-component': 6.5.1(@babel/core@7.24.4) dev: true /@svgr/core@6.5.1: resolution: {integrity: sha512-/xdLSWxK5QkqG524ONSjvg3V/FkNyCv538OIBdQqPNaAta3AsXj/Bd2FbvR87yMbXO2hFSWiAe/Q6IkVPDw+mw==} engines: {node: '>=10'} dependencies: - '@babel/core': 7.20.2 - '@svgr/babel-preset': 6.5.1(@babel/core@7.20.2) + '@babel/core': 7.24.4 + '@svgr/babel-preset': 6.5.1(@babel/core@7.24.4) '@svgr/plugin-jsx': 6.5.1(@svgr/core@6.5.1) camelcase: 6.3.0 cosmiconfig: 7.1.0 @@ -9625,8 +9791,8 @@ packages: peerDependencies: '@svgr/core': ^6.0.0 dependencies: - '@babel/core': 7.20.2 - '@svgr/babel-preset': 6.5.1(@babel/core@7.20.2) + '@babel/core': 7.24.4 + '@svgr/babel-preset': 6.5.1(@babel/core@7.24.4) '@svgr/core': 6.5.1 '@svgr/hast-util-to-babel-ast': 6.5.1 svg-parser: 2.0.4 @@ -9866,7 +10032,6 @@ packages: resolution: {integrity: sha512-jOdnI/3qTpHABjM5cx1Hc0sKsPoYCp+DP/GJRGtDlPd7fiV9oXGGIcjW/ZOxLIvjGz8MA+uMZI9metHlgqbgwQ==} dependencies: '@types/node': 20.11.20 - dev: true /@types/aria-query@5.0.1: resolution: {integrity: sha512-XTIieEY+gvJ39ChLcB4If5zHtPxt3Syj5rgZR+e1ctpmK8NjPf0zFqsz4JpLJT0xla9GFDKjy8Cpu331nrmE1Q==} @@ -9906,7 +10071,17 @@ packages: dependencies: '@types/connect': 3.4.35 '@types/node': 20.11.20 - dev: true + + /@types/caseless@0.12.5: + resolution: {integrity: sha512-hWtVTC2q7hc7xZ/RLbxapMvDMgUnDvKvMOpKal4DrMyfGBUfB1oKaZlIRr6mJL+If3bAP6sV/QneGzF6tJjZDg==} + dev: false + + /@types/co-body@6.1.3: + resolution: {integrity: sha512-UhuhrQ5hclX6UJctv5m4Rfp52AfG9o9+d9/HwjxhVB5NjXxr5t9oKgJxN8xRHgr35oo8meUEHUPFWiKg6y71aA==} + dependencies: + '@types/node': 20.12.7 + '@types/qs': 6.9.7 + dev: false /@types/color-convert@2.0.0: resolution: {integrity: sha512-m7GG7IKKGuJUXvkZ1qqG3ChccdIM/qBBo913z+Xft0nKCX4hAU/IxKwZBU4cpRZ7GS5kV4vOblUkILtSShCPXQ==} @@ -9928,11 +10103,9 @@ packages: resolution: {integrity: sha512-cdeYyv4KWoEgpBISTxWvqYsVy444DOqehiF3fM3ne10AmJ62RSyNkUnxMJXHQWRQQX2eR94m5y1IZyDwBjV9FQ==} dependencies: '@types/node': 20.11.20 - dev: true /@types/content-disposition@0.5.4: resolution: {integrity: sha512-0mPF08jn9zYI0n0Q/Pnz7C4kThdSt+6LD4amsrYDDpgBfrVWa3TcCOxKX1zkGgYniGagRv8heN2cbh+CAn+uuQ==} - dev: true /@types/conventional-commits-parser@5.0.0: resolution: {integrity: sha512-loB369iXNmAZglwWATL+WRe+CRMmmBPtpolYzIebFaX4YA3x+BEfLqhUAV9WanycKI3TG1IMr5bMJDajDKLlUQ==} @@ -9951,7 +10124,6 @@ packages: '@types/express': 4.17.13 '@types/keygrip': 1.0.2 '@types/node': 20.11.20 - dev: true /@types/debug@4.1.7: resolution: {integrity: sha512-9AonUzyTjXXhEOa0DnqpzZi6VHlqKMswga9EXjpXnnqxwLtdvPPtlO8evrI5D9S6asFRCQ6v+wpiUKbw+vKqyg==} @@ -9975,7 +10147,6 @@ packages: '@types/node': 20.11.20 '@types/qs': 6.9.7 '@types/range-parser': 1.2.4 - dev: true /@types/express@4.17.13: resolution: {integrity: sha512-6bSZTPaTIACxn48l50SR+axgrqm6qXFIxrdAKaG6PaJk3+zuUr35hBlgT7vOmJcum+OEaIBLtHV/qloEAFITeA==} @@ -9984,18 +10155,17 @@ packages: '@types/express-serve-static-core': 4.17.26 '@types/qs': 6.9.7 '@types/serve-static': 1.13.10 - dev: true - /@types/formidable@2.0.4: - resolution: {integrity: sha512-6HYcnmBCeby/nNGgX9kq1DxUpK2UcB3yoHCr3GzFjjqkpivOdcBSbsXP9NbxLcPEi11Fl/L41rbFCIsteF9sbg==} + /@types/formidable@2.0.6: + resolution: {integrity: sha512-L4HcrA05IgQyNYJj6kItuIkXrInJvsXTPC5B1i64FggWKKqSL+4hgt7asiSNva75AoLQjq29oPxFfU4GAQ6Z2w==} dependencies: - '@types/node': 20.11.20 + '@types/node': 20.12.7 dev: false /@types/graceful-fs@4.1.5: resolution: {integrity: sha512-anKkLmZZ+xm4p8JWBf4hElkM4XR+EZeA2M9BAkkTldmcyDY4mbdIJnRghDJH3Ov5ooY7/UAoENtmdMSkaAd7Cw==} dependencies: - '@types/node': 20.11.20 + '@types/node': 20.12.7 dev: true /@types/hast@2.3.4: @@ -10016,7 +10186,6 @@ packages: /@types/http-assert@1.5.3: resolution: {integrity: sha512-FyAOrDuQmBi8/or3ns4rwPno7/9tJTijVW6aQQjK02+kOQ8zmoNg2XJtAuQhvQcy1ASJq38wirX5//9J1EqoUA==} - dev: true /@types/http-cache-semantics@4.0.4: resolution: {integrity: sha512-1m0bIFVc7eJWyve9S0RnuRgcQqF/Xd5QsUZAZeQFr1Q3/p9JWoQQEqmVy+DPTNpGXwhgIetAoYF8JSc33q29QA==} @@ -10024,7 +10193,6 @@ packages: /@types/http-errors@1.8.2: resolution: {integrity: sha512-EqX+YQxINb+MeXaIqYDASb6U6FCHbWjkj4a1CKDBks3d/QiB2+PqBLyO72vLDgAO1wUI4O+9gweRcQK11bTL/w==} - dev: true /@types/inquirer@9.0.3: resolution: {integrity: sha512-CzNkWqQftcmk2jaCWdBTf9Sm7xSw4rkI1zpU/Udw3HX5//adEZUIm9STtoRP1qgWj0CWQtJ9UTvqmO2NNjhMJw==} @@ -10080,13 +10248,11 @@ packages: /@types/keygrip@1.0.2: resolution: {integrity: sha512-GJhpTepz2udxGexqos8wgaBx4I/zWIDPh/KOGEwAqtuGDkOUJu5eFvwmdBX4AmB8Odsr+9pHCQqiAqDL/yKMKw==} - dev: true /@types/koa-compose@3.2.5: resolution: {integrity: sha512-B8nG/OoE1ORZqCkBVsup/AKcvjdgoHnfi4pZMn5UwAPCbhk/96xyv284eBYW8JlQbQ7zDmnpFr68I/40mFoIBQ==} dependencies: '@types/koa': 2.13.4 - dev: true /@types/koa-compress@4.0.3: resolution: {integrity: sha512-nJSII/tOSvYCwk3yDEBJLHd8ctkt5CQFZ0j8ZBnHZ2x0hg24z9H1i38lWXA/5z0Ix0uitMW1jov+kVbQI1aNPQ==} @@ -10124,7 +10290,19 @@ packages: '@types/keygrip': 1.0.2 '@types/koa-compose': 3.2.5 '@types/node': 20.11.20 - dev: true + + /@types/koa@2.15.0: + resolution: {integrity: sha512-7QFsywoE5URbuVnG3loe03QXuGajrnotr3gQkXcEBShORai23MePfFYdhz90FEtBBpkyIYQbVD+evKtloCgX3g==} + dependencies: + '@types/accepts': 1.3.5 + '@types/content-disposition': 0.5.4 + '@types/cookies': 0.7.7 + '@types/http-assert': 1.5.3 + '@types/http-errors': 1.8.2 + '@types/keygrip': 1.0.2 + '@types/koa-compose': 3.2.5 + '@types/node': 20.12.7 + dev: false /@types/koa__cors@5.0.0: resolution: {integrity: sha512-LCk/n25Obq5qlernGOK/2LUwa/2YJb2lxHUkkvYFDOpLXlVI6tKcdfCHRBQnOY4LwH6el5WOLs6PD/a8Uzau6g==} @@ -10160,7 +10338,6 @@ packages: /@types/mime@1.3.2: resolution: {integrity: sha512-YATxVxgRqNH6nHEIsvg6k2Boc1JHI9ZbH5iWFFv/MTkchz3b1ieGDa5T0a9RznNdI0KhVbdbWSN+KWWrQZRxTw==} - dev: true /@types/minimist@1.2.2: resolution: {integrity: sha512-jhuKLIRrhvCPLqwPcx6INqmKeiA5EWrsCOPhrlFSrbrmU4ZMPjj5Ul/oLCMDO98XRUIwVm78xICz4EPCektzeQ==} @@ -10177,7 +10354,7 @@ packages: /@types/node-fetch@2.6.2: resolution: {integrity: sha512-DHqhlq5jeESLy19TYhLakJ07kNumXWjcDdxXsLUMJZ6ue8VZJj4kLPQVE/2mdHh3xZziNF1xppu5lwmS53HR+A==} dependencies: - '@types/node': 20.11.20 + '@types/node': 20.12.7 form-data: 3.0.1 dev: false @@ -10196,6 +10373,11 @@ packages: dependencies: undici-types: 5.26.5 + /@types/node@20.12.7: + resolution: {integrity: sha512-wq0cICSkRLVaf3UGLMGItu/PtdY7oaXaI/RVU+xliKVOtRna3PRY57ZDfztpDL0n11vfymMUnXv8QwYCO7L1wg==} + dependencies: + undici-types: 5.26.5 + /@types/nodemailer@6.4.7: resolution: {integrity: sha512-f5qCBGAn/f0qtRcd4SEn88c8Fp3Swct1731X4ryPKqS61/A3LmmzN8zaEz7hneJvpjFbUUgY7lru/B/7ODTazg==} dependencies: @@ -10210,10 +10392,11 @@ packages: resolution: {integrity: sha512-37i+OaWTh9qeK4LSHPsyRC7NahnGotNuZvjLSgcPzblpHB3rrCJxAOgI5gCdKm7coonsaX1Of0ILiTcnZjbfxA==} dev: true - /@types/oidc-provider@8.0.0: - resolution: {integrity: sha512-75LafF0iKy4WLwnELxJ4q/2ix6M9Jp+qAcZDQVF5SuW+gCtB6d2Bb3WvAQuQmMKLeCinR1oDfs4FEqB4ZFgokA==} + /@types/oidc-provider@8.4.4: + resolution: {integrity: sha512-+SlmKc4qlCJLjpw6Du/8cXw18JsPEYyQwoy+xheLkiuNsCz1mPEYI/lRXLQHvfJD9TH6+2/WDTLZQ2UUJ5G4bw==} dependencies: '@types/koa': 2.13.4 + '@types/node': 20.12.7 dev: true /@types/parse-json@4.0.0: @@ -10255,11 +10438,9 @@ packages: /@types/qs@6.9.7: resolution: {integrity: sha512-FGa1F62FT09qcrueBA6qYTrJPVDzah9a+493+o2PCXsesWHIn27G98TsSMs3WPNbZIEj4+VJf6saSFpvD+3Zsw==} - dev: true /@types/range-parser@1.2.4: resolution: {integrity: sha512-EEhsLsD6UsDM1yFhAvy0Cjr6VwmpMWqFBCb9w07wVugF7w9nfajxLuVmngTIpgS6svCnm6Vaw+MZhoDCKnOfsw==} - dev: true /@types/react-color@3.0.6: resolution: {integrity: sha512-OzPIO5AyRmLA7PlOyISlgabpYUa3En74LP8mTMa0veCA719SvYQov4WLMsHvCgXP+L+KI9yGhYnqZafVGG0P4w==} @@ -10321,6 +10502,15 @@ packages: '@types/react': 18.0.31 dev: true + /@types/request@2.48.12: + resolution: {integrity: sha512-G3sY+NpsA9jnwm0ixhAFQSJ3Q9JkpLZpJbI3GMv0mIAT0y3mRabYeINzal5WOChIiaTEGQYlHOKgkaM9EisWHw==} + dependencies: + '@types/caseless': 0.12.5 + '@types/node': 20.12.7 + '@types/tough-cookie': 4.0.2 + form-data: 2.5.1 + dev: false + /@types/resolve@1.20.2: resolution: {integrity: sha512-60BCwRFOZCQhDncwQdxxeOEEkbc5dIMccYLwbxsS4TUNeVECQ/pBJ0j09mrHOl/JJvpRPGwO9SvE4nR2Nb/a4Q==} dev: true @@ -10346,7 +10536,6 @@ packages: dependencies: '@types/mime': 1.3.2 '@types/node': 20.11.20 - dev: true /@types/shimmer@1.0.2: resolution: {integrity: sha512-dKkr1bTxbEsFlh2ARpKzcaAmsYixqt9UyCdoEZk8rHyE4iQYcDCyvSjDSf7JUWJHlJiTtbIoQjxKh6ViywqDAg==} @@ -10371,11 +10560,11 @@ packages: dependencies: '@types/cookiejar': 2.1.5 '@types/methods': 1.1.4 - '@types/node': 20.11.20 + '@types/node': 20.12.7 dev: true - /@types/supertest@6.0.1: - resolution: {integrity: sha512-M1xs8grAWC4RisSEQjyQV0FZzXnL3y796540Q/HCdiPcErwKpcAfvsNQFb4xp+5btSWMOZG1YlDWs2z96pdbcw==} + /@types/supertest@6.0.2: + resolution: {integrity: sha512-137ypx2lk/wTQbW6An6safu9hXmajAifU/s7szAHLN/FeIm5w7yR0Wkl9fdJMRSHwOn4HLAI0DaB2TOORuhPDg==} dependencies: '@types/methods': 1.1.4 '@types/superagent': 8.1.1 @@ -10396,12 +10585,11 @@ packages: /@types/tough-cookie@4.0.2: resolution: {integrity: sha512-Q5vtl1W5ue16D+nIaW8JWebSSraJVlK+EthKn7e7UcD4KWsaSJ8BqGPXNaPghgtcn/fhvrN17Tv8ksUsQpiplw==} - dev: true /@types/tunnel@0.0.3: resolution: {integrity: sha512-sOUTGn6h1SfQ+gbgqC364jLFBw2lnFqkgF3q0WovEHRLMrVD1sd5aufqi/aJObLekJO+Aq5z646U4Oxy6shXMA==} dependencies: - '@types/node': 20.11.20 + '@types/node': 20.12.7 dev: false /@types/unist@2.0.6: @@ -10432,7 +10620,7 @@ packages: resolution: {integrity: sha512-oJoftv0LSuaDZE3Le4DbKX+KS9G36NzOeSap90UIK0yMA/NhKJhqlSGtNDORNRaIbQfzjXDrQa0ytJ6mNRGz/Q==} requiresBuild: true dependencies: - '@types/node': 20.11.20 + '@types/node': 20.12.7 dev: true optional: true @@ -10589,7 +10777,7 @@ packages: 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) + vitest: 1.4.0(@types/node@20.10.4) transitivePeerDependencies: - supports-color dev: true @@ -10706,6 +10894,14 @@ packages: acorn-walk: 8.3.2 dev: true + /acorn-import-assertions@1.9.0(acorn@8.11.3): + resolution: {integrity: sha512-cmMwop9x+8KFhxvKrKfPYmN6/pKTYYHBqLa0DfvVZcKMJWNyWLnaqND7dx/qn66R7ewM1UX5XMaDVP5wlVTaVA==} + peerDependencies: + acorn: ^8 + dependencies: + acorn: 8.11.3 + dev: false + /acorn-jsx@5.3.2(acorn@8.10.0): resolution: {integrity: sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==} peerDependencies: @@ -10734,7 +10930,6 @@ packages: resolution: {integrity: sha512-Y9rRfJG5jcKOE0CLisYbojUjIrIEE7AGMzA/Sm4BslANhbS+cDMpgBdcPT91oJ7OuJ9hYJBx59RjbhxVnrF8Xg==} engines: {node: '>=0.4.0'} hasBin: true - dev: true /agent-base@6.0.2: resolution: {integrity: sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==} @@ -10854,8 +11049,8 @@ packages: picomatch: 2.3.1 dev: true - /applicationinsights@2.7.0: - resolution: {integrity: sha512-/vV5X6M4TlRA5NxNZAdCE0gukzfK24mb3z18D5Kl/CyIfSVIkafsIji3mK+Zi5q+7dn6H1CkFazlcnLf40anHw==} + /applicationinsights@2.9.5: + resolution: {integrity: sha512-APQ8IWyYDHFvKbitFKpsmZXxkzQh0yYTFacQqoVW7HwlPo3eeLprwnq5RFNmmG6iqLmvQ+xRJSDLEQCgqPh+bw==} engines: {node: '>=8.0.0'} peerDependencies: applicationinsights-native-metrics: '*' @@ -10863,19 +11058,19 @@ packages: applicationinsights-native-metrics: optional: true dependencies: - '@azure/core-auth': 1.4.0 + '@azure/core-auth': 1.7.2 '@azure/core-rest-pipeline': 1.10.1 '@azure/core-util': 1.2.0 - '@azure/opentelemetry-instrumentation-azure-sdk': 1.0.0-beta.4 + '@azure/opentelemetry-instrumentation-azure-sdk': 1.0.0-beta.5 '@microsoft/applicationinsights-web-snippet': 1.0.1 - '@opentelemetry/api': 1.4.0 - '@opentelemetry/core': 1.15.0(@opentelemetry/api@1.4.0) - '@opentelemetry/sdk-trace-base': 1.15.0(@opentelemetry/api@1.4.0) - '@opentelemetry/semantic-conventions': 1.15.0 + '@opentelemetry/api': 1.8.0 + '@opentelemetry/core': 1.23.0(@opentelemetry/api@1.8.0) + '@opentelemetry/sdk-trace-base': 1.23.0(@opentelemetry/api@1.8.0) + '@opentelemetry/semantic-conventions': 1.23.0 cls-hooked: 4.2.2 continuation-local-storage: 3.2.1 - diagnostic-channel: 1.1.0 - diagnostic-channel-publishers: 1.0.6(diagnostic-channel@1.1.0) + diagnostic-channel: 1.1.1 + diagnostic-channel-publishers: 1.0.8(diagnostic-channel@1.1.1) transitivePeerDependencies: - supports-color dev: false @@ -11057,17 +11252,17 @@ packages: resolution: {integrity: sha512-fpWrvyVHEKyeEvbKZTVOeZF3VSKKWtJxFIxX/jaVPf+cLbGUSitjb49pHLqPV2BUNNZ0LcoeEGfE/YCpyDYHIw==} dev: true - /babel-jest@29.7.0(@babel/core@7.20.2): + /babel-jest@29.7.0(@babel/core@7.24.4): resolution: {integrity: sha512-BrvGY3xZSwEcCzKvKsCi2GgHqDqsYkOP4/by5xCgIwGXQxIEh+8ew3gmrE1y7XRR6LHZIj6yLYnUi/mm2KXKBg==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} peerDependencies: '@babel/core': ^7.8.0 dependencies: - '@babel/core': 7.20.2 + '@babel/core': 7.24.4 '@jest/transform': 29.7.0 '@types/babel__core': 7.1.19 babel-plugin-istanbul: 6.1.1 - babel-preset-jest: 29.6.3(@babel/core@7.20.2) + babel-preset-jest: 29.6.3(@babel/core@7.24.4) chalk: 4.1.2 graceful-fs: 4.2.11 slash: 3.0.0 @@ -11114,35 +11309,35 @@ packages: '@types/babel__traverse': 7.18.2 dev: true - /babel-preset-current-node-syntax@1.0.1(@babel/core@7.20.2): + /babel-preset-current-node-syntax@1.0.1(@babel/core@7.24.4): resolution: {integrity: sha512-M7LQ0bxarkxQoN+vz5aJPsLBn77n8QgTFmo8WK0/44auK2xlCXrYcUxHFxgU7qW5Yzw/CjmLRK2uJzaCd7LvqQ==} peerDependencies: '@babel/core': ^7.0.0 dependencies: - '@babel/core': 7.20.2 - '@babel/plugin-syntax-async-generators': 7.8.4(@babel/core@7.20.2) - '@babel/plugin-syntax-bigint': 7.8.3(@babel/core@7.20.2) - '@babel/plugin-syntax-class-properties': 7.12.13(@babel/core@7.20.2) - '@babel/plugin-syntax-import-meta': 7.10.4(@babel/core@7.20.2) - '@babel/plugin-syntax-json-strings': 7.8.3(@babel/core@7.20.2) - '@babel/plugin-syntax-logical-assignment-operators': 7.10.4(@babel/core@7.20.2) - '@babel/plugin-syntax-nullish-coalescing-operator': 7.8.3(@babel/core@7.20.2) - '@babel/plugin-syntax-numeric-separator': 7.10.4(@babel/core@7.20.2) - '@babel/plugin-syntax-object-rest-spread': 7.8.3(@babel/core@7.20.2) - '@babel/plugin-syntax-optional-catch-binding': 7.8.3(@babel/core@7.20.2) - '@babel/plugin-syntax-optional-chaining': 7.8.3(@babel/core@7.20.2) - '@babel/plugin-syntax-top-level-await': 7.14.5(@babel/core@7.20.2) - dev: true - - /babel-preset-jest@29.6.3(@babel/core@7.20.2): + '@babel/core': 7.24.4 + '@babel/plugin-syntax-async-generators': 7.8.4(@babel/core@7.24.4) + '@babel/plugin-syntax-bigint': 7.8.3(@babel/core@7.24.4) + '@babel/plugin-syntax-class-properties': 7.12.13(@babel/core@7.24.4) + '@babel/plugin-syntax-import-meta': 7.10.4(@babel/core@7.24.4) + '@babel/plugin-syntax-json-strings': 7.8.3(@babel/core@7.24.4) + '@babel/plugin-syntax-logical-assignment-operators': 7.10.4(@babel/core@7.24.4) + '@babel/plugin-syntax-nullish-coalescing-operator': 7.8.3(@babel/core@7.24.4) + '@babel/plugin-syntax-numeric-separator': 7.10.4(@babel/core@7.24.4) + '@babel/plugin-syntax-object-rest-spread': 7.8.3(@babel/core@7.24.4) + '@babel/plugin-syntax-optional-catch-binding': 7.8.3(@babel/core@7.24.4) + '@babel/plugin-syntax-optional-chaining': 7.8.3(@babel/core@7.24.4) + '@babel/plugin-syntax-top-level-await': 7.14.5(@babel/core@7.24.4) + dev: true + + /babel-preset-jest@29.6.3(@babel/core@7.24.4): resolution: {integrity: sha512-0B3bhxR6snWXJZtR/RliHTDPRgn1sNHOR0yVtq/IiQFyuOVjFS+wuio/R4gSNkyYmKmJB4wGZv2NZanmKmTnNA==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} peerDependencies: '@babel/core': ^7.0.0 dependencies: - '@babel/core': 7.20.2 + '@babel/core': 7.24.4 babel-plugin-jest-hoist: 29.6.3 - babel-preset-current-node-syntax: 1.0.1(@babel/core@7.20.2) + babel-preset-current-node-syntax: 1.0.1(@babel/core@7.24.4) dev: true /bail@1.0.5: @@ -11167,13 +11362,12 @@ packages: dev: true optional: true - /bare-fs@2.2.2: - resolution: {integrity: sha512-X9IqgvyB0/VA5OZJyb5ZstoN62AzD7YxVGog13kkfYWYqJYcK0kcqLZ6TrmH5qr4/8//ejVcX4x/a0UvaogXmA==} + /bare-fs@2.2.3: + resolution: {integrity: sha512-amG72llr9pstfXOBOHve1WjiuKKAMnebcmMbPWDZ7BCevAoJLpugjuAPRsDINEyjT0a6tbaVx3DctkXIRbLuJw==} requiresBuild: true dependencies: bare-events: 2.2.2 - bare-os: 2.2.1 - bare-path: 2.1.0 + bare-path: 2.1.1 streamx: 2.15.1 dev: true optional: true @@ -11184,8 +11378,8 @@ packages: dev: true optional: true - /bare-path@2.1.0: - resolution: {integrity: sha512-DIIg7ts8bdRKwJRJrUMy/PICEaQZaPGZ26lsSx9MJSwIhSrcdHn7/C8W+XmnG/rKi6BaRcz+JO00CjZteybDtw==} + /bare-path@2.1.1: + resolution: {integrity: sha512-OHM+iwRDRMDBsSW7kl3dO62JyHdBKO3B25FB9vNQBPcGHMo4+eA8Yj41Lfbk3pS/seDY+siNge0LdRTulAau/A==} requiresBuild: true dependencies: bare-os: 2.2.1 @@ -11281,6 +11475,17 @@ packages: update-browserslist-db: 1.0.10(browserslist@4.21.4) dev: true + /browserslist@4.23.0: + resolution: {integrity: sha512-QW8HiM1shhT2GuzkvklfjcKDiWFXHOeFCIA/huJPwHsslwcydgk7X+z2zXpEijP98UCY7HbubZt5J2Zgvf0CaQ==} + engines: {node: ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7} + hasBin: true + dependencies: + caniuse-lite: 1.0.30001610 + electron-to-chromium: 1.4.738 + node-releases: 2.0.14 + update-browserslist-db: 1.0.13(browserslist@4.23.0) + dev: true + /bser@2.1.1: resolution: {integrity: sha512-gQxTNE/GAfIIrmHLUE3oJyp5FO6HRBfhjnw4/wMmA63ZGDJnWBmgY/lyQBpnDUkGmAhbSe39tx2d/iTOAfglwQ==} dependencies: @@ -11367,6 +11572,17 @@ packages: dependencies: function-bind: 1.1.1 get-intrinsic: 1.1.3 + dev: true + + /call-bind@1.0.7: + resolution: {integrity: sha512-GHTSNSYICQ7scH7sZ+M2rFopRoLh8t2bLSW6BbgrtLsahOIB5iyAVJf9GjWK3cYTDaMj4XdBpM1cA6pIS0Kv2w==} + engines: {node: '>= 0.4'} + dependencies: + es-define-property: 1.0.0 + es-errors: 1.3.0 + function-bind: 1.1.2 + get-intrinsic: 1.2.4 + set-function-length: 1.2.2 /call-me-maybe@1.0.2: resolution: {integrity: sha512-HpX65o1Hnr9HH25ojC1YGs7HCQLq0GCOibSaWER0eNpgJ/Z1MZv2mTc7+xh6WOPxbRVcmgbv4hGU+uSQ/2xFZQ==} @@ -11426,6 +11642,10 @@ packages: resolution: {integrity: sha512-NTt0DNoKe958Q0BE0j0c1V9jbUzhBxHIEJy7asmGrpE0yG63KTV7PLHPnK2E1O9RsQrQ081I3NLuXGS6zht3cw==} dev: true + /caniuse-lite@1.0.30001610: + resolution: {integrity: sha512-QFutAY4NgaelojVMjY63o6XlZyORPaLfyMnsl3HgnWdJUcX6K0oaJymHjH8PT5Gk7sTm8rvC/c5COUQKXqmOMA==} + dev: true + /cbor-extract@2.2.0: resolution: {integrity: sha512-Ig1zM66BjLfTXpNgKpvBePq271BPOvu8MR0Jl080yG7Jsl+wAZunfrwiwA+9ruzm/WEdIV5QF/bjDZTqyAIVHA==} hasBin: true @@ -11566,7 +11786,6 @@ packages: /cjs-module-lexer@1.2.2: resolution: {integrity: sha512-cOU9usZw8/dXIXKtwa8pM0OTJQuJkxMN6w30csNRUerHfeQ5R6U3kkU/FtJeIf3M202OHfY2U8ccInBG7/xogA==} - dev: true /classnames@2.3.1: resolution: {integrity: sha512-OlQdbZ7gLfGarSqxesMesDa5uz7KFbID8Kpq/SxIoNGDqY8lSYs0D+hhtBXhcdB3rcbXArFr7vlHheLk1voeNA==} @@ -11654,12 +11873,12 @@ packages: engines: {node: '>=0.10.0'} dev: false - /co-body@5.2.0: - resolution: {integrity: sha512-sX/LQ7LqUhgyaxzbe7IqwPeTr2yfpfUIQ/dgpKo6ZI4y4lpQA0YxAomWIY+7I7rHWcG02PG+OuPREzMW/5tszQ==} + /co-body@6.1.0: + resolution: {integrity: sha512-m7pOT6CdLN7FuXUcpuz/8lfQ/L77x8SchHCF4G0RBTJO20Wzmhn5Sp4/5WsKy8OSpifBSUrmg83qEqaDHdyFuQ==} dependencies: inflation: 2.0.0 - qs: 6.10.3 - raw-body: 2.4.3 + qs: 6.12.1 + raw-body: 2.5.2 type-is: 1.6.18 dev: false @@ -11827,8 +12046,8 @@ packages: resolution: {integrity: sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==} dev: true - /cookiejar@2.1.3: - resolution: {integrity: sha512-JxbCBUdrfr6AQjOXrxoTvAMJO4HBTUIlBzslcJPAz+/KT8yk53fXun51u+RenNYvad/+Vc2DIz5o9UxlCDymFQ==} + /cookiejar@2.1.4: + resolution: {integrity: sha512-LDx6oHrK+PhzLKJU9j5S7/Y3jM/mUHvD/DeI1WQmJn652iPC5Y4TBzC9l+5OMOXlyTTA+SmVUPm0HQUwpD5Jqw==} dev: true /cookies@0.8.0: @@ -11843,7 +12062,7 @@ packages: requiresBuild: true dev: true - /cosmiconfig-typescript-loader@5.0.0(@types/node@20.11.20)(cosmiconfig@8.3.6)(typescript@5.0.2): + /cosmiconfig-typescript-loader@5.0.0(@types/node@20.12.7)(cosmiconfig@8.3.6)(typescript@5.0.2): resolution: {integrity: sha512-+8cK7jRAReYkMwMiG+bxhcNKiHJDM6bR9FD/nGBXOWdMLuYawjF5cGrtLilJ+LGd3ZjCXnJjR5DkfWPoIVlqJA==} engines: {node: '>=v16'} peerDependencies: @@ -11851,7 +12070,7 @@ packages: cosmiconfig: '>=8.2' typescript: '>=4' dependencies: - '@types/node': 20.11.20 + '@types/node': 20.12.7 cosmiconfig: 8.3.6(typescript@5.0.2) jiti: 1.21.0 typescript: 5.0.2 @@ -11952,7 +12171,7 @@ packages: - ts-node dev: true - /create-jest@29.7.0(@types/node@20.11.20)(ts-node@10.9.2): + /create-jest@29.7.0(@types/node@20.12.7)(ts-node@10.9.2): resolution: {integrity: sha512-Adz2bdH0Vq3F53KEMJOoftQFutWCukm6J24wbPWRO4k1kMY7gS7ds/uoJkNuV8wDCtWWnuwGcJwpWcih+zEW1Q==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} hasBin: true @@ -11961,7 +12180,7 @@ packages: chalk: 4.1.2 exit: 0.1.2 graceful-fs: 4.2.11 - jest-config: 29.7.0(@types/node@20.11.20)(ts-node@10.9.2) + jest-config: 29.7.0(@types/node@20.12.7)(ts-node@10.9.2) jest-util: 29.7.0 prompts: 2.4.2 transitivePeerDependencies: @@ -12316,6 +12535,14 @@ packages: engines: {node: '>=10'} dev: false + /define-data-property@1.1.4: + resolution: {integrity: sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==} + engines: {node: '>= 0.4'} + dependencies: + es-define-property: 1.0.0 + es-errors: 1.3.0 + gopd: 1.0.1 + /define-lazy-prop@2.0.0: resolution: {integrity: sha512-Ds09qNh8yw3khSjiJjiUInaGX9xlqZDY7JVryGxdxV7NPeuqQfplOpQ66yJFZut3jLa5zOwkXw1g9EI2uKh4Og==} engines: {node: '>=8'} @@ -12404,24 +12631,24 @@ packages: resolution: {integrity: sha512-YJe4CT5SA8on3Spa+UDtNhEqtuV6Epwz3OZ4HQVLhlRccpZ9/PAYk0/cy/oKxFKRrZPBUPyxympQci4yWNWZ9g==} dev: true - /dezalgo@1.0.3: - resolution: {integrity: sha512-K7i4zNfT2kgQz3GylDw40ot9GAE47sFZ9EXHFSPP6zONLgH6kWXE0KWJchkbQJLBkRazq4APwZ4OwiFFlT95OQ==} + /dezalgo@1.0.4: + resolution: {integrity: sha512-rXSP0bf+5n0Qonsb+SVVfNfIsimO4HEtmnIpPHY8Q1UCzKlQrDMfdobr8nJOOsRgWCyMRqeSBQzmWUMq7zvVig==} dependencies: asap: 2.0.6 wrappy: 1.0.2 - /diagnostic-channel-publishers@1.0.6(diagnostic-channel@1.1.0): - resolution: {integrity: sha512-RE5AP4JmEm/CV06gOyFdgWWm3gMNOoXulod2mq4ysiz9s77ZhHb1P1DGrfePHjNOmgvWglhegmj5q8DNtjRrEg==} + /diagnostic-channel-publishers@1.0.8(diagnostic-channel@1.1.1): + resolution: {integrity: sha512-HmSm9hXxSPxA9BaLGY98QU1zsdjeCk113KjAYGPCen1ZP6mhVaTPzHd6UYv5r21DnWANi+f+NyPOHruGT9jpqQ==} peerDependencies: diagnostic-channel: '*' dependencies: - diagnostic-channel: 1.1.0 + diagnostic-channel: 1.1.1 dev: false - /diagnostic-channel@1.1.0: - resolution: {integrity: sha512-fwujyMe1gj6rk6dYi9hMZm0c8Mz8NDMVl2LB4iaYh3+LIAThZC8RKFGXWG0IML2OxAit/ZFRgZhMkhQ3d/bobQ==} + /diagnostic-channel@1.1.1: + resolution: {integrity: sha512-r2HV5qFkUICyoaKlBEpLKHjxMXATUf/l+h8UZPGBHGLy4DDiY2sOLcIctax4eRnTw5wH2jTMExLntGPJ8eOJxw==} dependencies: - semver: 5.7.2 + semver: 7.6.0 dev: false /diff-sequences@29.6.3: @@ -12547,13 +12774,13 @@ packages: resolution: {integrity: sha512-jtD6YG370ZCIi/9GTaJKQxWTZD045+4R4hTk/x1UyoqadyJ9x9CgSi1RlVDQF8U2sxLLSnFkCaMihqljHIWgMg==} dev: true - /duplexify@4.1.2: - resolution: {integrity: sha512-fz3OjcNCHmRP12MJoZMPglx8m4rrFP8rovnk4vT8Fs+aonZoCwGg10dSsQsfP/E62eZcPTMSMP6686fu9Qlqtw==} + /duplexify@4.1.3: + resolution: {integrity: sha512-M3BmBhwJRZsSx38lZyhE53Csddgzl5R7xGJNk7CVddZD6CcmwMCH8J+7AprIrQKH7TonKxaCjcv27Qmf+sQ+oA==} dependencies: end-of-stream: 1.4.4 inherits: 2.0.4 readable-stream: 3.6.2 - stream-shift: 1.0.1 + stream-shift: 1.0.3 dev: false /eastasianwidth@0.2.0: @@ -12572,6 +12799,10 @@ packages: resolution: {integrity: sha512-yer0w5wCYdFoZytfmbNhwiGI/3cW06+RV7E23ln4490DVMxs7PvYpbsrSmAiBn/V6gode8wvJlST2YfWgvzWIg==} dev: true + /electron-to-chromium@1.4.738: + resolution: {integrity: sha512-lwKft2CLFztD+vEIpesrOtCrko/TFnEJlHFdRhazU7Y/jx5qc4cqsocfVrBg4So4gGe9lvxnbLIoev47WMpg+A==} + dev: true + /emitter-listener@1.1.2: resolution: {integrity: sha512-Bt1sBAGFHY9DKY+4/2cV6izcKJUf5T7/gkdmkxzX/qv9CcGH8xSwVRW5mtX03SWJtRTWSOpzCuWN9rBFYZepZQ==} dependencies: @@ -12680,6 +12911,16 @@ packages: unbox-primitive: 1.0.2 dev: true + /es-define-property@1.0.0: + resolution: {integrity: sha512-jxayLKShrEqqzJ0eumQbVhTYQM27CfT1T35+gCgDFoL82JLsXqTJ76zv6A0YLOgEnLUMvLzsDsGIrl8NFpT2gQ==} + engines: {node: '>= 0.4'} + dependencies: + get-intrinsic: 1.2.4 + + /es-errors@1.3.0: + resolution: {integrity: sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==} + engines: {node: '>= 0.4'} + /es-shim-unscopables@1.0.0: resolution: {integrity: sha512-Jm6GPcCdC30eMLbZ2x8z2WuRwAws3zTBBKuusffYVUrNj/GVSUAZ+xKMaUpfNDR5IbyNA5LJbaecoUVbmUcB1w==} dependencies: @@ -13267,8 +13508,8 @@ packages: engines: {node: '>=0.10.0'} dev: true - /eta@2.2.0: - resolution: {integrity: sha512-UVQ72Rqjy/ZKQalzV5dCCJP80GrmPrMxh6NlNf+erV6ObL0ZFkhCstWRawS85z3smdr3d2wXPsZEY7rDPfGd2g==} + /eta@3.4.0: + resolution: {integrity: sha512-tCsc7WXTjrTx4ZjYLplcqrI3o4mYJ+Z6YspeuGL8tbt/hHoMchwBwtKfwM09svEY86iRapY93vUqQttcNuIO5Q==} engines: {node: '>=6.0.0'} dev: false @@ -13464,13 +13705,6 @@ packages: strnum: 1.0.5 dev: false - /fast-xml-parser@4.1.2: - resolution: {integrity: sha512-CDYeykkle1LiA/uqQyNwYpFbyF6Axec6YapmpUP+/RHWIoR1zKjocdvNaTsxCxZzQ6v9MLXaSYm9Qq0thv0DHg==} - hasBin: true - dependencies: - strnum: 1.0.5 - dev: false - /fast-xml-parser@4.2.5: resolution: {integrity: sha512-B9/wizE4WngqQftFPmdaMYlXoJlJOYxGQOanC77fq9k8+Z0v5dDSVh+3glErdIROP//s/jgb7ZuxKfB8nVyo0g==} hasBin: true @@ -13478,8 +13712,8 @@ packages: strnum: 1.0.5 dev: false - /fast-xml-parser@4.3.2: - resolution: {integrity: sha512-rmrXUXwbJedoXkStenj1kkljNF7ugn5ZjR9FJcwmCfcCbtOMDghPajbc+Tck6vE6F5XsDmx+Pr2le9fw8+pXBg==} + /fast-xml-parser@4.3.6: + resolution: {integrity: sha512-M2SovcRxD4+vC493Uc2GZVcZaj66CCJhWurC4viynVSTvrpErCShNcDz1lAho6n9REQKvL/ll4A4/fw6Y9z8nw==} hasBin: true dependencies: strnum: 1.0.5 @@ -13636,16 +13870,6 @@ packages: resolution: {integrity: sha512-X8cqMLLie7KsNUDSdzeN8FYK9rEt4Dt67OsG/DNGnYTSDBG4uFAJFBnUeiV+zCVAvwFy56IjM9sH51jVaEhNxw==} dev: true - /follow-redirects@1.15.1: - resolution: {integrity: sha512-yLAMQs+k0b2m7cVxpS1VKJVvoz7SS9Td1zss3XRwXj+ZDH00RJgnuLx7E44wx02kQLrdM3aOOy+FpzS7+8OizA==} - engines: {node: '>=4.0'} - peerDependencies: - debug: '*' - peerDependenciesMeta: - debug: - optional: true - dev: false - /follow-redirects@1.15.5: resolution: {integrity: sha512-vSFWUON1B+yAw1VN4xMfxgn5fTUiaOzAJCKBwIIgT/+7CuGy9+r+5gITvP62j3RmaD5Ph65UaERdOSRGUzZtgw==} engines: {node: '>=4.0'} @@ -13654,7 +13878,6 @@ packages: peerDependenciesMeta: debug: optional: true - dev: true /form-data-encoder@2.1.4: resolution: {integrity: sha512-yDYSgNMraqvnxiEXO4hi88+YZxaHC6QKzb5N84iRCTDeRO7ZALpir/lVmf/uXUhnwUr2O4HU8s/n6x+yNjQkHw==} @@ -13666,6 +13889,15 @@ packages: engines: {node: '>= 18'} dev: false + /form-data@2.5.1: + resolution: {integrity: sha512-m21N3WOmEEURgk6B9GLOE4RuWOFf28Lhh9qGYeNlGq4VDXUlJy2th2slBNU8Gp8EzloYZOibZJ7t5ecIrFSjVA==} + engines: {node: '>= 0.12'} + dependencies: + asynckit: 0.4.0 + combined-stream: 1.0.8 + mime-types: 2.1.35 + dev: false + /form-data@3.0.1: resolution: {integrity: sha512-RHkBKtLWUVwd7SqRIvCZMEvAMoGUp0XU+seQiZejj0COz3RI3hWP4sCv3gZWWLjJTd7rGwcsF5eKZGii0r/hbg==} engines: {node: '>= 6'} @@ -13688,13 +13920,13 @@ packages: engines: {node: '>=0.4.x'} dev: true - /formidable@2.0.1: - resolution: {integrity: sha512-rjTMNbp2BpfQShhFbR3Ruk3qk2y9jKpvMW78nJgx8QKtxjDVrwbZG+wvDOmVbifHyOUOQJXxqEy6r0faRrPzTQ==} + /formidable@2.1.2: + resolution: {integrity: sha512-CM3GuJ57US06mlpQ47YcunuUZ9jpm8Vx+P2CGt2j7HpgkKZO/DJYQ0Bobim8G6PFQmK5lOqOOdUXboU+h73A4g==} dependencies: - dezalgo: 1.0.3 + dezalgo: 1.0.4 hexoid: 1.0.0 once: 1.4.0 - qs: 6.9.3 + qs: 6.12.1 /fresh@0.5.2: resolution: {integrity: sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac=} @@ -13745,6 +13977,9 @@ packages: /function-bind@1.1.1: resolution: {integrity: sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==} + /function-bind@1.1.2: + resolution: {integrity: sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==} + /function.prototype.name@1.1.5: resolution: {integrity: sha512-uN7m/BzVKQnCUF/iW8jYea67v++2u7m5UgENbHRtdDVclOUP+FMPlCNdmk0h/ysGyo2tavMJEDqJAkJdRa1vMA==} engines: {node: '>= 0.4'} @@ -13772,8 +14007,8 @@ packages: - supports-color dev: false - /gcp-metadata@6.0.0: - resolution: {integrity: sha512-Ozxyi23/1Ar51wjUT2RDklK+3HxqDr8TLBNK8rBBFQ7T85iIGnXnVusauj06QyqCXRFZig8LZC+TUddWbndlpQ==} + /gcp-metadata@6.1.0: + resolution: {integrity: sha512-Jh/AIwwgaxan+7ZUUmRLCjtchyDiqh4KjBJ5tW3plBZb5iL/BPcso8A5DlzeD9qlw0duCamnNdpFjxwaT0KyKg==} engines: {node: '>=14'} dependencies: gaxios: 6.1.1 @@ -13819,6 +14054,16 @@ packages: has: 1.0.3 has-symbols: 1.0.3 + /get-intrinsic@1.2.4: + resolution: {integrity: sha512-5uYhsJH8VJBTv7oslg4BznJYhDoRI6waYCxMmCdnTrcCrHA/fCFKoTFz2JKKE0HdDFUF7/oQuhzumXJK7paBRQ==} + engines: {node: '>= 0.4'} + dependencies: + es-errors: 1.3.0 + function-bind: 1.1.2 + has-proto: 1.0.3 + has-symbols: 1.0.3 + hasown: 2.0.2 + /get-package-type@0.1.0: resolution: {integrity: sha512-pjzuKtY64GYfWizNAJ0fr9VqttZkNiK2iS430LtIHzjBEr6bX8Am2zm4sW4Ro5wjWW5cAlRL1qAMTcXbjNAO2Q==} engines: {node: '>=8.0.0'} @@ -14028,22 +14273,26 @@ packages: csstype: 3.0.11 dev: true - /google-auth-library@9.1.0: - resolution: {integrity: sha512-1M9HdOcQNPV5BwSXqwwT238MTKodJFBxZ/V2JP397ieOLv4FjQdfYb9SooR7Mb+oUT2IJ92mLJQf804dyx0MJA==} + /google-auth-library@9.8.0: + resolution: {integrity: sha512-TJJXFzMlVGRlIH27gYZ6XXyPf5Y3OItsKFfefsDAafNNywYRTkei83nEO29IrYj8GtdHWU78YnW+YZdaZaXIJA==} engines: {node: '>=14'} dependencies: base64-js: 1.5.1 ecdsa-sig-formatter: 1.0.11 gaxios: 6.1.1 - gcp-metadata: 6.0.0 + gcp-metadata: 6.1.0 gtoken: 7.0.1 jws: 4.0.0 - lru-cache: 6.0.0 transitivePeerDependencies: - encoding - supports-color dev: false + /gopd@1.0.1: + resolution: {integrity: sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==} + dependencies: + get-intrinsic: 1.2.4 + /got@13.0.0: resolution: {integrity: sha512-XfBk1CxOOScDcMr9O1yKkNaQyy865NbYs+F7dr4H0LZMVgCj2Le59k6PqbNHoL5ToeaEQUYh6c6yMfVcc6SJxA==} engines: {node: '>=16'} @@ -14139,6 +14388,15 @@ packages: dependencies: get-intrinsic: 1.1.3 + /has-property-descriptors@1.0.2: + resolution: {integrity: sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==} + dependencies: + es-define-property: 1.0.0 + + /has-proto@1.0.3: + resolution: {integrity: sha512-SJ1amZAJUiZS+PhsVLf5tGydlaVB8EdFpaSO4gmiUKUOxk8qzn5AIy4ZeJUmh22znIdk/uMAUT2pl3FxzVUH+Q==} + engines: {node: '>= 0.4'} + /has-symbols@1.0.3: resolution: {integrity: sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==} engines: {node: '>= 0.4'} @@ -14159,6 +14417,12 @@ packages: resolution: {integrity: sha512-7SW7ejyfnRxuOc7ptQHSf4LDoZaWOivfzqw+5rpcQku0nHfmicPKE51ra9BiRLAmT8+gGLestr1XroUkqdjL6w==} dev: false + /hasown@2.0.2: + resolution: {integrity: sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==} + engines: {node: '>= 0.4'} + dependencies: + function-bind: 1.1.2 + /hast-to-hyperscript@9.0.1: resolution: {integrity: sha512-zQgLKqF+O2F72S1aa4y2ivxzSlko3MAvxkwG8ehGmNiqd98BIN3JM1rAJPmplEyLmGLO2QZYJtIneOSZ2YbJuA==} dependencies: @@ -14443,7 +14707,7 @@ packages: engines: {node: '>=8.0.0'} dependencies: eventemitter3: 4.0.7 - follow-redirects: 1.15.1 + follow-redirects: 1.15.5 requires-port: 1.0.0 transitivePeerDependencies: - debug @@ -14576,9 +14840,12 @@ packages: resolve-from: 4.0.0 dev: true - /import-in-the-middle@1.3.5: - resolution: {integrity: sha512-yzHlBqi1EBFrkieAnSt8eTgO5oLSl+YJ7qaOpUH/PMqQOMZoQ/RmDlwnTLQrwYto+gHYjRG+i/IbsB1eDx32NQ==} + /import-in-the-middle@1.4.2: + resolution: {integrity: sha512-9WOz1Yh/cvO/p69sxRmhyQwrIGGSp7EIdcb+fFNVi7CzQGQB8U1/1XrKVSbEd/GNOAeM0peJtmi7+qphe7NvAw==} dependencies: + acorn: 8.11.3 + acorn-import-assertions: 1.9.0(acorn@8.11.3) + cjs-module-lexer: 1.2.2 module-details-from-path: 1.0.3 dev: false @@ -14621,7 +14888,7 @@ packages: dev: true /inflation@2.0.0: - resolution: {integrity: sha1-i0F+R8KPklpFEz2RTKH9OJEH8w8=} + resolution: {integrity: sha512-m3xv4hJYR2oXw4o4Y5l6P5P16WYmazYof+el6Al3f+YlggGj6qT9kImBAnzDelRALnP5d3h4jGBPKzYCizjZZw==} engines: {node: '>= 0.8.0'} dev: false @@ -15032,7 +15299,7 @@ packages: resolution: {integrity: sha512-pzqtp31nLv/XFOzXGuvhCb8qhjmTVo5vjVk19XE4CRlSWz0KoeJ3bw9XsA7nOp9YBf4qHjwBxkDzKcME/J29Yg==} engines: {node: '>=8'} dependencies: - '@babel/core': 7.20.2 + '@babel/core': 7.24.4 '@babel/parser': 7.24.0 '@istanbuljs/schema': 0.1.3 istanbul-lib-coverage: 3.2.2 @@ -15045,7 +15312,7 @@ packages: resolution: {integrity: sha512-EAMEJBsYuyyztxMxW3g7ugGPkrZsV57v0Hmv3mm1uQsmB+QnZuepg731CRaIgeUVSdmsTngOkSnauNF8p7FIhA==} engines: {node: '>=10'} dependencies: - '@babel/core': 7.20.2 + '@babel/core': 7.24.4 '@babel/parser': 7.24.0 '@istanbuljs/schema': 0.1.3 istanbul-lib-coverage: 3.2.2 @@ -15159,7 +15426,7 @@ packages: - ts-node dev: true - /jest-cli@29.7.0(@types/node@20.11.20): + /jest-cli@29.7.0(@types/node@20.12.7): resolution: {integrity: sha512-OVVobw2IubN/GSYsxETi+gOe7Ka59EFMR/twOU3Jb2GnKKeMGJB5SGUUrEz3SFVmJASUdZUzy83sLNNQ2gZslg==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} hasBin: true @@ -15173,10 +15440,10 @@ packages: '@jest/test-result': 29.7.0 '@jest/types': 29.6.3 chalk: 4.1.2 - create-jest: 29.7.0(@types/node@20.11.20)(ts-node@10.9.2) + create-jest: 29.7.0(@types/node@20.12.7)(ts-node@10.9.2) exit: 0.1.2 import-local: 3.1.0 - jest-config: 29.7.0(@types/node@20.11.20)(ts-node@10.9.2) + jest-config: 29.7.0(@types/node@20.12.7)(ts-node@10.9.2) jest-util: 29.7.0 jest-validate: 29.7.0 yargs: 17.7.2 @@ -15187,7 +15454,7 @@ packages: - ts-node dev: true - /jest-cli@29.7.0(@types/node@20.11.20)(ts-node@10.9.2): + /jest-cli@29.7.0(@types/node@20.12.7)(ts-node@10.9.2): resolution: {integrity: sha512-OVVobw2IubN/GSYsxETi+gOe7Ka59EFMR/twOU3Jb2GnKKeMGJB5SGUUrEz3SFVmJASUdZUzy83sLNNQ2gZslg==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} hasBin: true @@ -15201,10 +15468,10 @@ packages: '@jest/test-result': 29.7.0 '@jest/types': 29.6.3 chalk: 4.1.2 - create-jest: 29.7.0(@types/node@20.11.20)(ts-node@10.9.2) + create-jest: 29.7.0(@types/node@20.12.7)(ts-node@10.9.2) exit: 0.1.2 import-local: 3.1.0 - jest-config: 29.7.0(@types/node@20.11.20)(ts-node@10.9.2) + jest-config: 29.7.0(@types/node@20.12.7)(ts-node@10.9.2) jest-util: 29.7.0 jest-validate: 29.7.0 yargs: 17.7.2 @@ -15227,11 +15494,11 @@ packages: ts-node: optional: true dependencies: - '@babel/core': 7.20.2 + '@babel/core': 7.24.4 '@jest/test-sequencer': 29.7.0 '@jest/types': 29.6.3 '@types/node': 20.10.4 - babel-jest: 29.7.0(@babel/core@7.20.2) + babel-jest: 29.7.0(@babel/core@7.24.4) chalk: 4.1.2 ci-info: 3.8.0 deepmerge: 4.3.1 @@ -15267,11 +15534,52 @@ packages: ts-node: optional: true dependencies: - '@babel/core': 7.20.2 + '@babel/core': 7.24.4 '@jest/test-sequencer': 29.7.0 '@jest/types': 29.6.3 '@types/node': 20.11.20 - babel-jest: 29.7.0(@babel/core@7.20.2) + babel-jest: 29.7.0(@babel/core@7.24.4) + chalk: 4.1.2 + ci-info: 3.8.0 + deepmerge: 4.3.1 + glob: 7.2.3 + graceful-fs: 4.2.11 + jest-circus: 29.7.0 + jest-environment-node: 29.7.0 + jest-get-type: 29.6.3 + jest-regex-util: 29.6.3 + jest-resolve: 29.7.0 + jest-runner: 29.7.0 + jest-util: 29.7.0 + jest-validate: 29.7.0 + micromatch: 4.0.5 + parse-json: 5.2.0 + pretty-format: 29.7.0 + slash: 3.0.0 + strip-json-comments: 3.1.1 + ts-node: 10.9.2(@swc/core@1.3.52)(@types/node@20.12.7)(typescript@5.3.3) + transitivePeerDependencies: + - babel-plugin-macros + - supports-color + dev: true + + /jest-config@29.7.0(@types/node@20.12.7)(ts-node@10.9.2): + resolution: {integrity: sha512-uXbpfeQ7R6TZBqI3/TxCU4q4ttk3u0PJeC+E0zbfSoSjq6bJ7buBPxzQPL0ifrkY4DNu4JUdk0ImlBUYi840eQ==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + peerDependencies: + '@types/node': '*' + ts-node: '>=9.0.0' + peerDependenciesMeta: + '@types/node': + optional: true + ts-node: + optional: true + dependencies: + '@babel/core': 7.24.4 + '@jest/test-sequencer': 29.7.0 + '@jest/types': 29.6.3 + '@types/node': 20.12.7 + babel-jest: 29.7.0(@babel/core@7.24.4) chalk: 4.1.2 ci-info: 3.8.0 deepmerge: 4.3.1 @@ -15290,7 +15598,7 @@ packages: pretty-format: 29.7.0 slash: 3.0.0 strip-json-comments: 3.1.1 - ts-node: 10.9.2(@swc/core@1.3.52)(@types/node@20.11.20)(typescript@5.3.3) + ts-node: 10.9.2(@swc/core@1.3.52)(@types/node@20.12.7)(typescript@5.3.3) transitivePeerDependencies: - babel-plugin-macros - supports-color @@ -15628,15 +15936,15 @@ packages: resolution: {integrity: sha512-Rm0BMWtxBcioHr1/OX5YCP8Uov4riHvKPknOGs804Zg9JGZgmIBkbtlxJC/7Z4msKYVbIJtfU+tKb8xlYNfdkw==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} dependencies: - '@babel/core': 7.20.2 + '@babel/core': 7.24.4 '@babel/generator': 7.20.4 - '@babel/plugin-syntax-jsx': 7.18.6(@babel/core@7.20.2) - '@babel/plugin-syntax-typescript': 7.18.6(@babel/core@7.20.2) + '@babel/plugin-syntax-jsx': 7.18.6(@babel/core@7.24.4) + '@babel/plugin-syntax-typescript': 7.18.6(@babel/core@7.24.4) '@babel/types': 7.24.0 '@jest/expect-utils': 29.7.0 '@jest/transform': 29.7.0 '@jest/types': 29.6.3 - babel-preset-current-node-syntax: 1.0.1(@babel/core@7.20.2) + babel-preset-current-node-syntax: 1.0.1(@babel/core@7.24.4) chalk: 4.1.2 expect: 29.7.0 graceful-fs: 4.2.11 @@ -15662,7 +15970,7 @@ packages: jest: ^28.1.0 || ^29.1.2 react: ^17.0.0 || ^18.0.0 dependencies: - jest: 29.7.0(@types/node@20.11.20)(ts-node@10.9.2) + jest: 29.7.0(@types/node@20.12.7)(ts-node@10.9.2) react: 18.2.0 dev: true @@ -15720,7 +16028,7 @@ packages: resolution: {integrity: sha512-NcrQnevGoSp4b5kg+akIpthoAFHxPBcb5P6mYPY0fUNT+sSvmtu6jlkEle3anczUKIKEbMxFimk9oTP/tpIPgA==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} dependencies: - '@types/node': 20.11.20 + '@types/node': 20.12.7 jest-util: 29.7.0 merge-stream: 2.0.0 supports-color: 8.1.1 @@ -15757,7 +16065,7 @@ packages: - ts-node dev: true - /jest@29.7.0(@types/node@20.11.20): + /jest@29.7.0(@types/node@20.12.7): resolution: {integrity: sha512-NIy3oAFp9shda19hy4HK0HRTWKtPJmGdnvywu01nOqNC2vZg+Z+fvJDxpMQA88eb2I9EcafcdjYgsDthnYTvGw==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} hasBin: true @@ -15770,7 +16078,7 @@ packages: '@jest/core': 29.7.0(ts-node@10.9.2) '@jest/types': 29.6.3 import-local: 3.1.0 - jest-cli: 29.7.0(@types/node@20.11.20) + jest-cli: 29.7.0(@types/node@20.12.7) transitivePeerDependencies: - '@types/node' - babel-plugin-macros @@ -15778,7 +16086,7 @@ packages: - ts-node dev: true - /jest@29.7.0(@types/node@20.11.20)(ts-node@10.9.2): + /jest@29.7.0(@types/node@20.12.7)(ts-node@10.9.2): resolution: {integrity: sha512-NIy3oAFp9shda19hy4HK0HRTWKtPJmGdnvywu01nOqNC2vZg+Z+fvJDxpMQA88eb2I9EcafcdjYgsDthnYTvGw==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} hasBin: true @@ -15791,7 +16099,7 @@ packages: '@jest/core': 29.7.0(ts-node@10.9.2) '@jest/types': 29.6.3 import-local: 3.1.0 - jest-cli: 29.7.0(@types/node@20.11.20)(ts-node@10.9.2) + jest-cli: 29.7.0(@types/node@20.12.7)(ts-node@10.9.2) transitivePeerDependencies: - '@types/node' - babel-plugin-macros @@ -15814,16 +16122,11 @@ packages: '@sideway/pinpoint': 2.0.0 dev: true - /jose@4.14.4: - resolution: {integrity: sha512-j8GhLiKmUAh+dsFXlX1aJCbt5KMibuKb+d7j1JaOJG6s2UjX1PQlW+OKB/sD4a/5ZYF4RcmYmLSndOoU3Lt/3g==} - dev: false - /jose@5.0.1: resolution: {integrity: sha512-gRVzy7s3RRdGbXmcTdlOswJOjhwPLx1ijIgAqLY6ktzFpOJxxYn4l0fC2vHaHHi4YBX/5FOL3aY+6W0cvQgpug==} /jose@5.2.2: resolution: {integrity: sha512-/WByRr4jDcsKlvMd1dRJnPfS1GVO3WuKyaurJ/vvXcOaUQO8rnNObCQMlv/5uCceVQIq5Q4WLF44ohsdiTohdg==} - dev: true /js-base64@3.7.5: resolution: {integrity: sha512-3MEt5DTINKqfScXKfJFrRbxkrnk2AxPWGBL/ycjz4dK8iqiSJ06UxD8jh8xuh6p10TX4t2+7FsBYVxxQbMg+qA==} @@ -15954,6 +16257,12 @@ packages: hasBin: true dev: true + /json5@2.2.3: + resolution: {integrity: sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==} + engines: {node: '>=6'} + hasBin: true + dev: true + /jsonc-eslint-parser@2.4.0: resolution: {integrity: sha512-WYDyuc/uFcGp6YtM2H0uKmUwieOuzeE/5YocFJLnLfclZ4inf3mRn8ZVy1s7Hxji7Jxm6Ss8gqpexD/GlKoGgg==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} @@ -16075,12 +16384,15 @@ packages: resolution: {integrity: sha512-Ne7wqW7/9Cz54PDt4I3tcV+hAyat8ypyOGzYRJQfdxnnjeWsTxt1cy8pjvvKeI5kfXuyvULyeeAvwvvtAX3ayQ==} dev: true - /koa-body@5.0.0: - resolution: {integrity: sha512-nHwEODrQGiyKBILCWO8QSS40C87cKr2cp3y/Cw8u9Z8w5t0CdSkGm3+y9WK5BIAlPpo9tTw5RtSbxpVyG79vmw==} + /koa-body@6.0.1: + resolution: {integrity: sha512-M8ZvMD8r+kPHy28aWP9VxL7kY8oPWA+C7ZgCljrCMeaU7uX6wsIQgDHskyrAr9sw+jqnIXyv4Mlxri5R4InIJg==} dependencies: - '@types/formidable': 2.0.4 - co-body: 5.2.0 - formidable: 2.0.1 + '@types/co-body': 6.1.3 + '@types/formidable': 2.0.6 + '@types/koa': 2.15.0 + co-body: 6.1.0 + formidable: 2.1.2 + zod: 3.22.4 dev: false /koa-compose@4.1.0: @@ -16128,14 +16440,15 @@ packages: - supports-color dev: false - /koa-proxies@0.12.1(koa@2.13.4): - resolution: {integrity: sha512-qCOGY7Qoe/Ewn2VskP9TdLMZffmsv8JUBWllNlmTJmgl1059nxt5jl7QBWNniqx2BthVSU5TIBuhUULA5d6t+A==} + /koa-proxies@0.12.4(koa@2.13.4): + resolution: {integrity: sha512-xxrEtN0e7s7/gNRoOMUltCbuIaCWqTQUTZNWQqet/8MoxSW0hG422lx2Al9FfYO3nCeA+b5c5/YmILRzavivDA==} peerDependencies: koa: '>=2' dependencies: http-proxy: 1.18.1 koa: 2.13.4 path-match: 1.2.4 + uuid: 8.3.2 transitivePeerDependencies: - debug dev: false @@ -16614,6 +16927,12 @@ packages: yallist: 2.1.2 dev: true + /lru-cache@5.1.1: + resolution: {integrity: sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==} + dependencies: + yallist: 3.1.1 + dev: true + /lru-cache@6.0.0: resolution: {integrity: sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==} engines: {node: '>=10'} @@ -17329,8 +17648,8 @@ packages: resolution: {integrity: sha512-ySViT69/76t8VhE1xXHK6Ch4NcDd26gx0MzKXLO+F7NOtnqH68d9zF94nT8ZWSxXh8ELOERsnJO/sWt1xZYw5A==} dev: false - /monaco-editor@0.46.0: - resolution: {integrity: sha512-ADwtLIIww+9FKybWscd7OCfm9odsFYHImBRI1v9AviGce55QY8raT+9ihH8jX/E/e6QVSGM+pKj4jSUSRmALNQ==} + /monaco-editor@0.47.0: + resolution: {integrity: sha512-VabVvHvQ9QmMwXu4du008ZDuyLnHs9j7ThVFsiJoXSOQk18+LF89N4ADzPbFenm0W4V2bGHnFBztIRQTgBfxzw==} dev: true /ms@2.1.2: @@ -17377,17 +17696,17 @@ packages: hasBin: true dev: true - /nanoid@4.0.2: - resolution: {integrity: sha512-7ZtY5KTCNheRGfEFxnedV5zFiORN1+Y1N6zvPTnHQd8ENUvfaDBeuJDZb2bN/oXwXxu3qkTXDzy57W5vAmDTBw==} - engines: {node: ^14 || ^16 || >=18} - hasBin: true - dev: false - /nanoid@5.0.1: resolution: {integrity: sha512-vWeVtV5Cw68aML/QaZvqN/3QQXc6fBfIieAlu05m7FZW2Dgb+3f0xc0TTxuJW+7u30t7iSDTV/j3kVI0oJqIfQ==} engines: {node: ^18 || >=20} hasBin: true + /nanoid@5.0.7: + resolution: {integrity: sha512-oLxFY2gd2IqnjcYyOXD8XGCftpGtZP2AbHbOkthDkvRywH5ayNtPVy9YlOPcHckXzbLTCHpkb7FB+yuxKV13pQ==} + engines: {node: ^18 || >=20} + hasBin: true + dev: false + /natural-compare-lite@1.4.0: resolution: {integrity: sha512-Tj+HTDSJJKaZnfiuw+iaF9skdPpTo2GtEly5JHnWV/hfv2Qj/9RKsGISQtLh2ox3l5EAGw487hnBee0sIJ6v2g==} dev: true @@ -17459,18 +17778,6 @@ packages: resolution: {integrity: sha512-73sE9+3UaLYYFmDsFZnqCInzPyh3MqIwZO9cw58yIqAZhONrrabrYyYe3TuIqtIiOuTXVhsGau8hcrhhwSsDIQ==} dev: true - /node-fetch@2.6.7: - resolution: {integrity: sha512-ZjMPFEfVx5j+y2yF35Kzx5sF7kDzxuDj6ziH4FFbOp87zKDZNx8yExJIb05OGF4Nlt9IHFIMBkRl41VdvcNdbQ==} - engines: {node: 4.x || >=6.0.0} - peerDependencies: - encoding: ^0.1.0 - peerDependenciesMeta: - encoding: - optional: true - dependencies: - whatwg-url: 5.0.0 - dev: false - /node-fetch@2.7.0: resolution: {integrity: sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==} engines: {node: 4.x || >=6.0.0} @@ -17534,6 +17841,10 @@ packages: type-is: 1.6.18 dev: true + /node-releases@2.0.14: + resolution: {integrity: sha512-y10wOWt8yZpqXmOgRo77WaHEmhYQYGNA6y421PKsKYWEK8aW+cqAphborZDhqfyKrbZEN92CN1X2KbafY2s7Yw==} + dev: true + /node-releases@2.0.6: resolution: {integrity: sha512-PiVXnNuFm5+iYkLBNeq5211hvO38y63T0i2KKh2KnUs3RpzJ+JtODFjkD8yjLwnDkTYF1eKXheUwdssR+NRZdg==} dev: true @@ -17651,6 +17962,10 @@ packages: /object-inspect@1.12.2: resolution: {integrity: sha512-z+cPxW0QGUp0mcqcsgQyLVRDoXFQbXOwBaqyF7VIgI4TWNQsDHrBpUQslRmIfAoYWdYzs6UlKJtB2XJpTaNSpQ==} + dev: true + + /object-inspect@1.13.1: + resolution: {integrity: sha512-5qoj1RUiKOMsCCNLV1CBiPYE10sziTsnmNxkAI/rZhiD63CF7IqdFGC/XzjWjpSgLf0LxXX3bDFIh0E18f6UhQ==} /object-keys@1.1.1: resolution: {integrity: sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==} @@ -17703,21 +18018,21 @@ packages: /obuf@1.1.2: resolution: {integrity: sha512-PX1wu0AmAdPqOL1mWhqmlOd8kOIZQwGZw6rh7uby9fTc5lhaOWFLX3I6R1hrF9k3zUY40e6igsLGkDXK92LJNg==} - /oidc-provider@8.2.2: - resolution: {integrity: sha512-zHXW8vzTuB0mJO3F/m+dz62/HII+qqMqgLGCQ5W/9Ojz6Jqe5voqA67ytvvHGkhoqgXCuYigLg9TBvbVnZQhGw==} + /oidc-provider@8.4.5: + resolution: {integrity: sha512-2NsPrvIAX1W4ZR41cGbz2Lt2Ci8iXvECh+x+LcKcM115s/h8iB1pwnNlCdIrvAA2iBGM4/TkO75Xg7xb2FCzWA==} dependencies: - '@koa/cors': 4.0.0 - '@koa/router': 12.0.0 + '@koa/cors': 5.0.0 + '@koa/router': 12.0.1 debug: 4.3.4 - eta: 2.2.0 + eta: 3.4.0 got: 13.0.0 - jose: 4.14.4 + jose: 5.2.2 jsesc: 3.0.2 koa: 2.14.2 - nanoid: 4.0.2 + nanoid: 5.0.7 object-hash: 3.0.0 oidc-token-hash: 5.0.3 - quick-lru: 6.1.1 + quick-lru: 7.0.0 raw-body: 2.5.2 transitivePeerDependencies: - supports-color @@ -18115,7 +18430,7 @@ packages: dev: true /path-match@1.2.4: - resolution: {integrity: sha1-pidH88fgwlFHYml/JEQ1hbCRAOo=} + resolution: {integrity: sha512-UWlehEdqu36jmh4h5CWJ7tARp1OEVKGHKm6+dg9qMq5RKUTV5WJrGgaZ3dN2m7WFAXDbjlHzvJvL/IUpy84Ktw==} dependencies: http-errors: 1.4.0 path-to-regexp: 1.8.0 @@ -18398,13 +18713,13 @@ packages: postcss: 8.4.31 dev: true - /postcss-safe-parser@6.0.0(postcss@8.4.35): + /postcss-safe-parser@6.0.0(postcss@8.4.38): resolution: {integrity: sha512-FARHN8pwH+WiS2OPCxJI8FuRJpTVnn6ZNFiqAM2aeW2LwTHWWmWgIyKC6cUo0L8aeKiF/14MNvnpls6R2PBeMQ==} engines: {node: '>=12.0'} peerDependencies: postcss: ^8.3.3 dependencies: - postcss: 8.4.35 + postcss: 8.4.38 dev: true /postcss-scss@4.0.5(postcss@8.4.31): @@ -18416,13 +18731,13 @@ packages: postcss: 8.4.31 dev: true - /postcss-scss@4.0.5(postcss@8.4.35): + /postcss-scss@4.0.5(postcss@8.4.38): resolution: {integrity: sha512-F7xpB6TrXyqUh3GKdyB4Gkp3QL3DDW1+uI+gxx/oJnUt/qXI4trj5OGlp9rOKdoABGULuqtqeG+3HEVQk4DjmA==} engines: {node: '>=12.0'} peerDependencies: postcss: ^8.3.3 dependencies: - postcss: 8.4.35 + postcss: 8.4.38 dev: true /postcss-selector-parser@6.0.11: @@ -18441,8 +18756,8 @@ packages: util-deprecate: 1.0.2 dev: true - /postcss-selector-parser@6.0.15: - resolution: {integrity: sha512-rEYkQOMUCEMhsKbK66tbEU9QVIxbhN18YiniAwA7XQYTVBqrBy+P2p5JcdqsHgKM2zWylp8d7J6eszocfds5Sw==} + /postcss-selector-parser@6.0.16: + resolution: {integrity: sha512-A0RVJrX+IUkVZbW3ClroRWurercFhieevHB38sr2+l9eUClMqome3LmEmnhlNy+5Mr2EYN6B2Kaw9wYdd+VHiw==} engines: {node: '>=4'} dependencies: cssesc: 3.0.0 @@ -18483,6 +18798,15 @@ packages: source-map-js: 1.0.2 dev: true + /postcss@8.4.38: + resolution: {integrity: sha512-Wglpdk03BSfXkHoQa3b/oulrotAkwrlLDRSOb9D0bN86FdRyE9lppSp33aHNPgBa0JKCoB+drFLZkQoRRYae5A==} + engines: {node: ^10 || ^12 || >=14} + dependencies: + nanoid: 3.3.7 + picocolors: 1.0.0 + source-map-js: 1.2.0 + dev: true + /postgres-array@2.0.0: resolution: {integrity: sha512-VpZrUqU5A69eQyW2c5CA1jtLecCsN2U/bD6VilrFDWq5+5UIEVO7nazS3TEcHf1zuPYO/sqGvUvW62g86RXZuA==} engines: {node: '>=4'} @@ -18768,15 +19092,11 @@ packages: yargs: 15.4.1 dev: false - /qs@6.10.3: - resolution: {integrity: sha512-wr7M2E0OFRfIfJZjKGieI8lBKb7fRCH4Fv5KNPEs7gJ8jadvotdsS08PzOKR7opXhZ/Xkjtt3WF9g38drmyRqQ==} + /qs@6.12.1: + resolution: {integrity: sha512-zWmv4RSuB9r2mYQw3zxQuHWeU+42aKi1wWig/j4ele4ygELZ7PEO6MM7rim9oAQH2A5MWfsAVf/jPvTPgCbvUQ==} engines: {node: '>=0.6'} dependencies: - side-channel: 1.0.4 - - /qs@6.9.3: - resolution: {integrity: sha512-EbZYNarm6138UKKq46tdx08Yo/q9ZhFoAXAI1meAFd2GtbRDhbZY2WQSICskT0c5q99aFzLG1D4nvTk9tqfXIw==} - engines: {node: '>=0.6'} + side-channel: 1.0.6 /query-string@9.0.0: resolution: {integrity: sha512-4EWwcRGsO2H+yzq6ddHcVqkCQ2EFUSfDMEjF8ryp8ReymyZhIuaFRGLomeOQLkrzacMHoyky2HW0Qe30UbzkKw==} @@ -18813,21 +19133,16 @@ packages: resolution: {integrity: sha512-S27GBT+F0NTRiehtbrgaSE1idUAJ5bX8dPAQTdylEyNlrdcH5X4Lz7Edz3DYzecbsCluD5zO8ZNEe04z3D3u6Q==} engines: {node: '>=12'} + /quick-lru@7.0.0: + resolution: {integrity: sha512-MX8gB7cVYTrYcFfAnfLlhRd0+Toyl8yX8uBx1MrX7K0jegiz9TumwOK27ldXrgDlHRdVi+MqU9Ssw6dr4BNreg==} + engines: {node: '>=18'} + dev: false + /range-parser@1.2.1: resolution: {integrity: sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==} engines: {node: '>= 0.6'} dev: true - /raw-body@2.4.3: - resolution: {integrity: sha512-UlTNLIcu0uzb4D2f4WltY6cVjLi+/jEN4lgEUj3E04tpMDpUlkBo/eSn6zou9hum2VMNpCCUone0O0WeJim07g==} - engines: {node: '>= 0.8'} - dependencies: - bytes: 3.1.2 - http-errors: 1.8.1 - iconv-lite: 0.4.24 - unpipe: 1.0.0 - dev: false - /raw-body@2.5.2: resolution: {integrity: sha512-8zGqypfENjCIqGhgXToC8aB2r7YrBX+AQAfIPs/Mlk+BtPTztOvTS01NRW/3Eh60J+a48lt8qsCzirQ6loCVfA==} engines: {node: '>= 0.8'} @@ -18892,7 +19207,7 @@ packages: dnd-core: 16.0.0 dev: true - /react-dnd@16.0.0(@types/node@20.11.20)(@types/react@18.0.31)(react@18.2.0): + /react-dnd@16.0.0(@types/node@20.12.7)(@types/react@18.0.31)(react@18.2.0): resolution: {integrity: sha512-RCoeWRWhuwSoqdLaJV8N/weARLyXqsf43OC3QiBWPORIIGGovF/EqI8ckf14ca3bl6oZNI/igtxX49+IDmNDeQ==} peerDependencies: '@types/hoist-non-react-statics': '>= 3.3.1' @@ -18909,7 +19224,7 @@ packages: dependencies: '@react-dnd/invariant': 4.0.0 '@react-dnd/shallowequal': 4.0.0 - '@types/node': 20.11.20 + '@types/node': 20.12.7 '@types/react': 18.0.31 dnd-core: 16.0.0 fast-deep-equal: 3.1.3 @@ -19573,13 +19888,15 @@ packages: onetime: 5.1.2 signal-exit: 3.0.7 - /retry-request@6.0.0: - resolution: {integrity: sha512-24kaFMd3wCnT3n4uPnsQh90ZSV8OISpfTFXJ00Wi+/oD2OPrp63EQ8hznk6rhxdlpwx2QBhQSDz2Fg46ki852g==} + /retry-request@7.0.2: + resolution: {integrity: sha512-dUOvLMJ0/JJYEn8NrpOaGNE7X3vpI5XlZS/u0ANjqtcZVKnIxP7IgCFwrKTxENw29emmwug53awKtaMm4i9g5w==} engines: {node: '>=14'} dependencies: - debug: 4.3.4 + '@types/request': 2.48.12 extend: 3.0.2 + teeny-request: 9.0.0 transitivePeerDependencies: + - encoding - supports-color dev: false @@ -19784,6 +20101,17 @@ packages: /set-blocking@2.0.0: resolution: {integrity: sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw==} + /set-function-length@1.2.2: + resolution: {integrity: sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==} + engines: {node: '>= 0.4'} + dependencies: + define-data-property: 1.1.4 + es-errors: 1.3.0 + function-bind: 1.1.2 + get-intrinsic: 1.2.4 + gopd: 1.0.1 + has-property-descriptors: 1.0.2 + /setprototypeof@1.1.0: resolution: {integrity: sha512-BvE/TwpZX4FXExxOxZyRGQQv651MSwmWKZGqvmPcRIjDqWub67kTKuIMx43cZZrS/cBBzwBcNDWoFxt2XEFIpQ==} dev: false @@ -19829,6 +20157,16 @@ packages: call-bind: 1.0.2 get-intrinsic: 1.1.3 object-inspect: 1.12.2 + dev: true + + /side-channel@1.0.6: + resolution: {integrity: sha512-fDW/EZ6Q9RiO8eFG8Hj+7u/oW+XrPTIChwCOM2+th2A6OblDtYYIpve9m+KvI9Z4C9qSEXlaGR6bTEYHReuglA==} + engines: {node: '>= 0.4'} + dependencies: + call-bind: 1.0.7 + es-errors: 1.3.0 + get-intrinsic: 1.2.4 + object-inspect: 1.13.1 /siginfo@2.0.0: resolution: {integrity: sha512-ybx0WO1/8bSBLEWXZvEd7gMW3Sn3JFlW3TvX1nREbDLRNQNaeNN8WK0meBwPdAaOI7TtRRRJn/Es1zhrrCHu7g==} @@ -19961,6 +20299,11 @@ packages: engines: {node: '>=0.10.0'} dev: true + /source-map-js@1.2.0: + resolution: {integrity: sha512-itJW8lvSA0TXEphiRoawsCksnlf8SyvmFzIhltqAHluXd88pkCd+cXJVHTDwdCr0IzwptSm035IHQktUu1QUMg==} + engines: {node: '>=0.10.0'} + dev: true + /source-map-support@0.5.13: resolution: {integrity: sha512-SHSKFHadjVA5oR4PPqhtAVdcBWwRYVd6g6cAXnIbRiIwc2EhPrTuKUBdSLvlEKyIP3GCf89fltvcZiP9MMFA1w==} dependencies: @@ -20110,8 +20453,8 @@ packages: stubs: 3.0.0 dev: false - /stream-shift@1.0.1: - resolution: {integrity: sha512-AiisoFqQ0vbGcZgQPY1cdP2I76glaVA/RauYR4G4thNFgkTqr90yXTo4LYX60Jl+sIlPNHHdGSwo01AvbKUSVQ==} + /stream-shift@1.0.3: + resolution: {integrity: sha512-76ORR0DO1o1hlKwTbi/DM3EXWGf3ZJYO8cXX5RJwnul2DEg2oyoZyjLNoQM8WsvZiFKCRfC1O0J7iCvie3RZmQ==} dev: false /stream-transform@2.1.3: @@ -20308,13 +20651,13 @@ packages: - postcss dev: true - /stylelint-config-xo-scss@0.15.0(postcss@8.4.35)(stylelint@15.11.0): + /stylelint-config-xo-scss@0.15.0(postcss@8.4.38)(stylelint@15.11.0): resolution: {integrity: sha512-X9WD8cDofWFWy3uaKdwwm+DjEvgI/+h7AtlaPagkhNAeOWH/GFQoeciBvNvyJ8tB1p00SoIzCn2IIOIKXCbxYA==} engines: {node: '>=12'} peerDependencies: stylelint: '>=14.5.1 || ^15.0.0' dependencies: - postcss-scss: 4.0.5(postcss@8.4.35) + postcss-scss: 4.0.5(postcss@8.4.38) stylelint: 15.11.0(typescript@5.3.3) stylelint-config-xo: 0.21.1(stylelint@15.11.0) stylelint-scss: 4.3.0(stylelint@15.11.0) @@ -20464,10 +20807,10 @@ packages: engines: {node: ^14.13.1 || >=16.0.0} hasBin: true dependencies: - '@csstools/css-parser-algorithms': 2.6.0(@csstools/css-tokenizer@2.2.3) - '@csstools/css-tokenizer': 2.2.3 - '@csstools/media-query-list-parser': 2.1.8(@csstools/css-parser-algorithms@2.6.0)(@csstools/css-tokenizer@2.2.3) - '@csstools/selector-specificity': 3.0.2(postcss-selector-parser@6.0.15) + '@csstools/css-parser-algorithms': 2.6.1(@csstools/css-tokenizer@2.2.4) + '@csstools/css-tokenizer': 2.2.4 + '@csstools/media-query-list-parser': 2.1.9(@csstools/css-parser-algorithms@2.6.1)(@csstools/css-tokenizer@2.2.4) + '@csstools/selector-specificity': 3.0.3(postcss-selector-parser@6.0.16) balanced-match: 2.0.0 colord: 2.9.3 cosmiconfig: 8.3.6(typescript@5.3.3) @@ -20491,10 +20834,10 @@ packages: micromatch: 4.0.5 normalize-path: 3.0.0 picocolors: 1.0.0 - postcss: 8.4.35 + postcss: 8.4.38 postcss-resolve-nested-selector: 0.1.1 - postcss-safe-parser: 6.0.0(postcss@8.4.35) - postcss-selector-parser: 6.0.15 + postcss-safe-parser: 6.0.0(postcss@8.4.38) + postcss-selector-parser: 6.0.16 postcss-value-parser: 4.2.0 resolve-from: 5.0.0 string-width: 4.2.3 @@ -20502,28 +20845,27 @@ packages: style-search: 0.1.0 supports-hyperlinks: 3.0.0 svg-tags: 1.0.0 - table: 6.8.1 + table: 6.8.2 write-file-atomic: 5.0.1 transitivePeerDependencies: - supports-color - typescript dev: true - /superagent@7.1.1: - resolution: {integrity: sha512-CQ2weSS6M+doIwwYFoMatklhRbx6sVNdB99OEJ5czcP3cng76Ljqus694knFWgOj3RkrtxZqIgpe6vhe0J7QWQ==} + /superagent@8.1.2: + resolution: {integrity: sha512-6WTxW1EB6yCxV5VFOIPQruWGHqc3yI7hEmZK6h+pyk69Lk/Ut7rLUY6W/ONF2MjBuGjvmMiIpsrVJ2vjrHlslA==} engines: {node: '>=6.4.0 <13 || >=14'} dependencies: component-emitter: 1.3.0 - cookiejar: 2.1.3 + cookiejar: 2.1.4 debug: 4.3.4 fast-safe-stringify: 2.1.1 form-data: 4.0.0 - formidable: 2.0.1 + formidable: 2.1.2 methods: 1.1.2 mime: 2.6.0 - qs: 6.10.3 - readable-stream: 3.6.2 - semver: 7.5.2 + qs: 6.12.1 + semver: 7.6.0 transitivePeerDependencies: - supports-color dev: true @@ -20533,12 +20875,12 @@ packages: engines: {node: '>=14.0.0'} dev: true - /supertest@6.2.2: - resolution: {integrity: sha512-wCw9WhAtKJsBvh07RaS+/By91NNE0Wh0DN19/hWPlBOU8tAfOtbZoVSV4xXeoKoxgPx0rx2y+y+8660XtE7jzg==} - engines: {node: '>=6.0.0'} + /supertest@6.3.4: + resolution: {integrity: sha512-erY3HFDG0dPnhw4U+udPfrzXa4xhSG+n4rxfRuZWCUvjFWwKl+OxWf/7zk50s84/fAAs7vf5QAb9uRa0cCykxw==} + engines: {node: '>=6.4.0'} dependencies: methods: 1.1.2 - superagent: 7.1.1 + superagent: 8.1.2 transitivePeerDependencies: - supports-color dev: true @@ -20637,6 +20979,17 @@ packages: strip-ansi: 6.0.1 dev: true + /table@6.8.2: + resolution: {integrity: sha512-w2sfv80nrAh2VCbqR5AK27wswXhqcck2AhfnNW76beQXskGZ1V12GwS//yYVa3d3fcvAip2OUnbDAjW2k3v9fA==} + engines: {node: '>=10.0.0'} + dependencies: + ajv: 8.12.0 + lodash.truncate: 4.4.2 + slice-ansi: 4.0.0 + string-width: 4.2.3 + strip-ansi: 6.0.1 + dev: true + /tapable@2.2.1: resolution: {integrity: sha512-GNzQvQTOIP6RyTfE2Qxb8ZVlNmw0n88vp1szwWRimP02mnTsx3Wtn5qRdqY9w2XduFNUgvOwhNnQsjwCp+kqaQ==} engines: {node: '>=6'} @@ -20648,8 +21001,8 @@ packages: pump: 3.0.0 tar-stream: 3.1.6 optionalDependencies: - bare-fs: 2.2.2 - bare-path: 2.1.0 + bare-fs: 2.2.3 + bare-path: 2.1.1 dev: true /tar-stream@3.1.6: @@ -20857,7 +21210,7 @@ packages: resolution: {integrity: sha512-AqTiAOLcj85xS7vQ8QkAV41hPDIJ71XJB4RCUrzo/1GM2CQwhkJGaf9Hgr7BOugMRpgGUrqRg/DrBDl4H40+8g==} dev: true - /ts-node@10.9.2(@swc/core@1.3.52)(@types/node@20.11.20)(typescript@5.3.3): + /ts-node@10.9.2(@swc/core@1.3.52)(@types/node@20.12.7)(typescript@5.3.3): resolution: {integrity: sha512-f0FFpIdcHgn8zcPSbf1dRevwt047YMnaiJM3u2w2RewrB+fob/zePZcrOyQoLMMO7aBIddLcQIEK5dYjkLnGrQ==} hasBin: true peerDependencies: @@ -20877,7 +21230,7 @@ packages: '@tsconfig/node12': 1.0.11 '@tsconfig/node14': 1.0.3 '@tsconfig/node16': 1.0.4 - '@types/node': 20.11.20 + '@types/node': 20.12.7 acorn: 8.10.0 acorn-walk: 8.2.0 arg: 4.1.3 @@ -21211,6 +21564,17 @@ packages: picocolors: 1.0.0 dev: true + /update-browserslist-db@1.0.13(browserslist@4.23.0): + resolution: {integrity: sha512-xebP81SNcPuNpPP3uzeW1NYXxI3rxyJzF3pD6sH4jE7o/IX+WtSpwnVU+qIsDPyk0d3hmFQ7mjqc6AtV604hbg==} + hasBin: true + peerDependencies: + browserslist: '>= 4.21.0' + dependencies: + browserslist: 4.23.0 + escalade: 3.1.1 + picocolors: 1.0.0 + dev: true + /uri-js@4.4.1: resolution: {integrity: sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==} dependencies: @@ -21789,8 +22153,8 @@ packages: engines: {node: '>=12'} dev: true - /xml2js@0.4.23: - resolution: {integrity: sha512-ySPiMjM0+pLDftHgXY4By0uswI3SPKLDw/i3UXbnO8M/p28zqexCUoPmQFrYD+/1BzhGJSs2i1ERWKJAtiLrug==} + /xml2js@0.5.0: + resolution: {integrity: sha512-drPFnkQJik/O+uPKpqSgr22mpuFHqKdbS835iAQrUC73L2F5WkboIRd63ai/2Yg6I1jzifPFKH2NTK+cfglkIA==} engines: {node: '>=4.0.0'} dependencies: sax: 1.2.4 @@ -21834,6 +22198,10 @@ packages: resolution: {integrity: sha512-ncTzHV7NvsQZkYe1DW7cbDLm0YpzHmZF5r/iyP3ZnQtMiJ+pjzisCiMNI+Sj+xQF5pXhSHxSB3uDbsBTzY/c2A==} dev: true + /yallist@3.1.1: + resolution: {integrity: sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==} + dev: true + /yallist@4.0.0: resolution: {integrity: sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==} From 45157873a2eb781aeb57670421ccaa76ed8f186d Mon Sep 17 00:00:00 2001 From: Xiao Yijun Date: Thu, 18 Apr 2024 14:33:10 +0800 Subject: [PATCH 288/687] test(console): assign permissions to organization role (#5729) --- .../console/rbac/organization-rbac.test.ts | 90 ++++++++++ .../src/ui-helpers/expect-api-resources.ts | 105 ++++++++++++ .../src/ui-helpers/expect-console.ts | 27 ++- .../src/ui-helpers/expect-organizations.ts | 155 +++++++++++++++++- 4 files changed, 374 insertions(+), 3 deletions(-) create mode 100644 packages/integration-tests/src/tests/console/rbac/organization-rbac.test.ts create mode 100644 packages/integration-tests/src/ui-helpers/expect-api-resources.ts diff --git a/packages/integration-tests/src/tests/console/rbac/organization-rbac.test.ts b/packages/integration-tests/src/tests/console/rbac/organization-rbac.test.ts new file mode 100644 index 00000000000..e9aedc38f50 --- /dev/null +++ b/packages/integration-tests/src/tests/console/rbac/organization-rbac.test.ts @@ -0,0 +1,90 @@ +import ExpectApiResources from '#src/ui-helpers/expect-api-resources.js'; +import ExpectConsole from '#src/ui-helpers/expect-console.js'; +import ExpectOrganizations from '#src/ui-helpers/expect-organizations.js'; +import { + generateResourceIndicator, + generateResourceName, + generateRoleName, + generateScopeName, +} from '#src/utils.js'; + +const expectConsole = new ExpectConsole(); +const expectApiResources = new ExpectApiResources(); +const expectOrganizations = new ExpectOrganizations(); + +const apiResourceName = generateResourceName(); +const apiResourceIndicator = generateResourceIndicator(); +const apiPermissionName = generateScopeName(); + +const organizationPermissionName = generateScopeName(); +const organizationRoleName = generateRoleName(); + +const dummyPermissionDescription = 'Dummy permission description'; + +describe('Organization RBAC', () => { + beforeAll(async () => { + await expectConsole.start(); + }); + + it('navigates to API resources page', async () => { + await expectApiResources.gotoPage('/api-resources', 'API resources'); + await expectApiResources.toExpectTableHeaders('API name', 'API Identifier'); + }); + + it('creates an API resource', async () => { + await expectApiResources.toCreateApiResource({ + name: apiResourceName, + indicator: apiResourceIndicator, + }); + }); + + it('creates an API permission for organization role', async () => { + await expectApiResources.toCreateApiResourcePermission( + { name: apiPermissionName, description: dummyPermissionDescription }, + apiResourceName + ); + }); + + it('navigates to the organization template', async () => { + await expectConsole.gotoPage('/organization-template', 'Organization template'); + await expectConsole.toExpectTabs('Organization roles', 'Organization permissions'); + await expectConsole.toExpectTableHeaders('Organization Role', 'Permissions'); + }); + + it('creates an organization permission', async () => { + await expectOrganizations.toCreateOrganizationPermission({ + name: organizationPermissionName, + description: dummyPermissionDescription, + }); + }); + + it('creates an organization role', async () => { + await expectOrganizations.toCreateOrganizationRole({ + name: organizationRoleName, + description: dummyPermissionDescription, + }); + }); + + it('assigns organization permissions and API permissions for organization role', async () => { + await expectOrganizations.toAssignPermissionsForOrganizationRole({ + organizationPermission: organizationPermissionName, + apiPermission: { + resource: apiResourceName, + permission: apiPermissionName, + }, + forOrganizationRole: organizationRoleName, + }); + }); + + // Clean up + it('deletes created resources', async () => { + // Delete created organization role + await expectOrganizations.toDeleteOrganizationRole(organizationRoleName); + + // Delete created organization permissions + await expectOrganizations.toDeleteOrganizationPermission(organizationPermissionName); + + // Delete created API resource + await expectApiResources.toDeleteApiResource(apiResourceName); + }); +}); diff --git a/packages/integration-tests/src/ui-helpers/expect-api-resources.ts b/packages/integration-tests/src/ui-helpers/expect-api-resources.ts new file mode 100644 index 00000000000..b8a877a2890 --- /dev/null +++ b/packages/integration-tests/src/ui-helpers/expect-api-resources.ts @@ -0,0 +1,105 @@ +import { cls } from '#src/utils.js'; + +import ExpectConsole from './expect-console.js'; +import { expectToClickDetailsPageOption, expectToClickModalAction } from './index.js'; + +export default class ExpectApiResources extends ExpectConsole { + /** + * Go to the api resources page and create a new API resource, then assert that the URL matches + * the API resource detail page. + * + * @param {Object} params The parameters for creating the API resource. + * @param {string} params.name The name of the API resource to create. + * @param {string} params.indicator The indicator of the API resource to create. + */ + async toCreateApiResource({ name, indicator }: { name: string; indicator: string }) { + await this.gotoPage('/api-resources', 'API resources'); + await this.toClickButton('Create API resource'); + + await this.toExpectModal('Start with tutorials'); + + // Click bottom button to skip tutorials + await this.toClickButton('Continue without tutorial', false); + + await this.toExpectModal('Create API resource'); + + await this.toFillForm({ + name, + indicator, + }); + + await this.toClick( + ['.ReactModalPortal', `button${cls('primary')}`].join(' '), + 'Create API resource', + false + ); + + this.toMatchUrl(/\/api-resources\/.+$/); + } + + /** + * Go to the api resource details page by given resource name and create a new API permission, then assert the permission is created. + * + * @param {Object} params The parameters for creating the API permission. + * @param {string} params.name The name of the API permission to create. + * @param {string} params.description The description of the API permission to create. + * @param {string} forResourceName The name of the API resource for which the permission is created. + */ + async toCreateApiResourcePermission( + { + name, + description, + }: { + name: string; + description: string; + }, + forResourceName: string + ) { + await this.gotoPage('/api-resources', 'API resources'); + await this.toExpectTableHeaders('API name', 'API Identifier'); + + await expect(this.page).toClick(['table', 'tbody', 'tr', 'td', `a${cls('title')}`].join(' '), { + text: forResourceName, + }); + + // Expect the API resource details page + await expect(this.page).toMatchElement([cls('header'), cls('metadata'), 'div'].join(' '), { + text: forResourceName, + }); + + await this.toClickButton('Create permission', false); + + await this.toExpectModal('Create permission'); + + await this.toFillForm({ name, description }); + + await this.toClick( + ['.ReactModalPortal', `button${cls('primary')}`].join(' '), + 'Create permission', + false + ); + + await this.waitForToast(`The permission ${name} has been successfully created`); + + await this.toExpectTableCell(name); + } + + /** + * Go to the api resource details page by given resource name and delete the API resource. + * + * @param {string} name The name of the API resource to delete. + */ + async toDeleteApiResource(name: string) { + await this.gotoPage('/api-resources', 'API resources'); + await this.toExpectTableCell(name); + await this.toClickTableCell(name); + + await expectToClickDetailsPageOption(this.page, 'Delete'); + + await this.toExpectModal('Reminder'); + await this.toFill('.ReactModalPortal input', name); + + await expectToClickModalAction(this.page, 'Delete'); + await this.waitForToast(`The API resource ${name} has been successfully deleted`); + } +} diff --git a/packages/integration-tests/src/ui-helpers/expect-console.ts b/packages/integration-tests/src/ui-helpers/expect-console.ts index b73e3b8b064..6494570c360 100644 --- a/packages/integration-tests/src/ui-helpers/expect-console.ts +++ b/packages/integration-tests/src/ui-helpers/expect-console.ts @@ -19,7 +19,11 @@ type ExpectConsoleOptions = { tenantId?: string; }; -export type ConsoleTitle = 'Sign-in experience' | 'Organizations'; +export type ConsoleTitle = + | 'Sign-in experience' + | 'Organizations' + | 'API resources' + | 'Organization template'; export default class ExpectConsole extends ExpectPage { readonly options: Required; @@ -59,9 +63,15 @@ export default class ExpectConsole extends ExpectPage { /** * Navigate to a specific page in the Console. + * If the current page is the target page, it will not navigate. */ async gotoPage(pathname: string, title: ConsoleTitle) { - await this.navigateTo(this.buildUrl(path.join(this.options.tenantId, pathname))); + const target = this.buildUrl(path.join(this.options.tenantId, pathname)); + if (this.page.url() === target.href) { + return; + } + + await this.navigateTo(target); await expect(this.page).toMatchElement( [dcls('main'), dcls('container'), dcls('title')].join(' '), { text: title } @@ -112,6 +122,19 @@ export default class ExpectConsole extends ExpectPage { }); } + /** + * To click a table cell with the given text. + * @param text The text to expect, case-insensitive. + * @param shouldNavigate Whether to navigate to the page after clicking the cell. + */ + async toClickTableCell(text: string, shouldNavigate = true) { + await this.toClick( + ['table', 'tbody', 'tr', 'td'].join(' '), + new RegExp(text, 'i'), + shouldNavigate + ); + } + /** * Expect a modal to appear with the given title. * diff --git a/packages/integration-tests/src/ui-helpers/expect-organizations.ts b/packages/integration-tests/src/ui-helpers/expect-organizations.ts index be27b4e67b8..07b30570440 100644 --- a/packages/integration-tests/src/ui-helpers/expect-organizations.ts +++ b/packages/integration-tests/src/ui-helpers/expect-organizations.ts @@ -1,6 +1,7 @@ -import { cls } from '#src/utils.js'; +import { cls, dcls } from '#src/utils.js'; import ExpectConsole from './expect-console.js'; +import { selectDropdownMenuItem } from './select-dropdown-menu-item.js'; export default class ExpectOrganizations extends ExpectConsole { /** @@ -20,4 +21,156 @@ export default class ExpectOrganizations extends ExpectConsole { await this.toClick(['.ReactModalPortal', `button${cls('primary')}`].join(' '), 'Create', false); this.toMatchUrl(/\/organizations\/.+$/); } + + /** + * Go to he organization template page and create a new organization permission, + * then assert then assert the permission is created. + * + * @param param The parameters for creating the organization permission. + * @param param.name The name of the organization permission. + * @param param.description The description of the organization permission. + */ + async toCreateOrganizationPermission({ + name, + description, + }: { + name: string; + description: string; + }) { + await this.gotoPage('/organization-template', 'Organization template'); + await this.toClickTab('Organization permissions'); + await this.toClickButton('Create organization permission', false); + + // Use fill input since no form tag is present in this modal + await this.toExpectModal('Create organization permission'); + await this.toFillInput('name', name); + await this.toFillInput('description', description); + await this.toClickButton('Create permission', false); + + await this.toExpectTableCell(name); + } + + /** + * Go to the organization template page and create a new organization role, + * then skip the permission assignment and assert that the URL matches + * the organization detail page. + * + * @param param The parameters for creating the organization role. + * @param param.name The name of the organization role. + * @param param.description The description of the organization role. + */ + async toCreateOrganizationRole({ name, description }: { name: string; description: string }) { + await this.gotoPage('/organization-template/organization-roles', 'Organization template'); + await this.toClickTab('Organization roles'); + await this.toClickButton('Create organization role', false); + + // Use fill input since no form tag is present in this modal + await this.toExpectModal('Create organization role'); + await this.toFillInput('name', name); + await this.toFillInput('description', description); + await this.toClickButton('Create role', false); + + // Skip permission assignment + await this.toExpectModal('Assign permissions'); + await this.toClickButton('Discard'); + + this.toMatchUrl(/\/organization-template\/organization-roles\/.+$/); + } + + /** + * Go to the organization role details page, assign organization permissions and API permissions for an organization role, + * then assert the permissions are assigned. + * + * @param param The parameters for assigning permissions for an organization role. + * @param param.organizationPermission The name of the organization permission to assign. + * @param param.apiPermission The API permission to assign. + * @param param.forOrganizationRole The organization role to assign the permissions. + */ + async toAssignPermissionsForOrganizationRole({ + organizationPermission, + apiPermission: { resource: apiResource, permission: apiPermission }, + forOrganizationRole, + }: { + organizationPermission: string; + apiPermission: { + resource: string; + permission: string; + }; + forOrganizationRole: string; + }) { + await this.navigateToOrganizationRoleDetailsPage(forOrganizationRole); + + await this.toClickButton('Assign permissions', false); + await this.toExpectModal('Assign permissions'); + // Select organization permission + await this.toClickTab('Organization permissions'); + await this.toClick(`div[role=button]`, organizationPermission, false); + + // Select API permission + await this.toClickTab('API permissions'); + await this.toClick(`div[role=button]`, apiResource, false); + await this.toClick(`div[role=button]`, apiPermission, false); + + await this.toClickButton('Save', false); + + await this.toExpectTableCell(organizationPermission); + await this.toExpectTableCell(apiPermission); + } + + /** + * Go to the organization role details page and delete an organization role, + * then assert that the URL matches the organization roles page. + * + * @param name The name of the organization role to delete. + */ + async toDeleteOrganizationRole(name: string) { + await this.navigateToOrganizationRoleDetailsPage(name); + + // Open the dropdown menu + await this.toClick([dcls('header'), `button${cls('withIcon')}`].join(' '), undefined, false); + await this.toClick(`${dcls('danger')}[role=menuitem]`, 'Delete', false); + await this.toExpectModal('Reminder'); + await this.toClick(['.ReactModalPortal', `button${cls('danger')}`].join(' '), 'Delete'); + await this.waitForToast(`Organization role ${name} was successfully deleted.`, 'success'); + this.toMatchUrl(/\/organization-template\/organization-roles$/); + } + + /** + * Go to the organization permissions page and delete an organization permission, + * + * @param name The name of the organization permission to delete. + */ + async toDeleteOrganizationPermission(name: string) { + await this.gotoPage('/organization-template', 'Organization template'); + await this.toClickTab('Organization permissions'); + await this.toExpectTableCell(name); + + // Open the dropdown menu from the table row + const permissionRow = await expect(this.page).toMatchElement('table tbody tr:has(td div)', { + text: name, + }); + + // Click the action button from the permission row + await expect(permissionRow).toClick('td:last-of-type button'); + + await selectDropdownMenuItem(this.page, 'div[role=menuitem]', 'Delete permission'); + + await this.toExpectModal('Reminder'); + await this.toClick(['.ReactModalPortal', `button${cls('danger')}`].join(' '), 'Delete', false); + } + + /** + * Navigate to the organization role details page by given role name. + * + * @param name The name of the organization role. + */ + private async navigateToOrganizationRoleDetailsPage(name: string) { + await this.gotoPage('/organization-template', 'Organization template'); + await this.toClickTab('Organization roles'); + await this.toExpectTableCell(name); + await this.toClickTableCell(name); + + // Assert in details page + this.toMatchUrl(/\/organization-template\/organization-roles\/.+$/); + } } From c1c746bca4be538e43d1138daa237013fdc96cbb Mon Sep 17 00:00:00 2001 From: Gao Sun Date: Thu, 18 Apr 2024 15:20:24 +0800 Subject: [PATCH 289/687] refactor: remove AppInsights for React (#5742) --- .changeset/ten-steaks-melt.md | 5 + packages/app-insights/package.json | 22 +- .../src/react/AppInsightsBoundary.tsx | 48 -- .../src/react/AppInsightsReact.ts | 137 ----- packages/app-insights/src/react/TrackOnce.tsx | 47 -- packages/app-insights/src/react/context.tsx | 61 -- packages/app-insights/src/react/index.ts | 5 - packages/app-insights/src/react/utils.ts | 5 - packages/app-insights/tsconfig.json | 2 +- packages/experience/jest.config.ts | 1 - packages/experience/package.json | 1 - packages/experience/src/App.tsx | 149 +++-- .../src/components/PageMeta/index.tsx | 20 +- pnpm-lock.yaml | 542 +----------------- 14 files changed, 89 insertions(+), 956 deletions(-) create mode 100644 .changeset/ten-steaks-melt.md delete mode 100644 packages/app-insights/src/react/AppInsightsBoundary.tsx delete mode 100644 packages/app-insights/src/react/AppInsightsReact.ts delete mode 100644 packages/app-insights/src/react/TrackOnce.tsx delete mode 100644 packages/app-insights/src/react/context.tsx delete mode 100644 packages/app-insights/src/react/index.ts delete mode 100644 packages/app-insights/src/react/utils.ts diff --git a/.changeset/ten-steaks-melt.md b/.changeset/ten-steaks-melt.md new file mode 100644 index 00000000000..b4d58e3db4d --- /dev/null +++ b/.changeset/ten-steaks-melt.md @@ -0,0 +1,5 @@ +--- +"@logto/app-insights": major +--- + +remove application insights for react diff --git a/packages/app-insights/package.json b/packages/app-insights/package.json index d862bf8da46..39af604081a 100644 --- a/packages/app-insights/package.json +++ b/packages/app-insights/package.json @@ -12,10 +12,6 @@ "./*": { "import": "./lib/*.js", "types": "./lib/*.d.ts" - }, - "./react": { - "import": "./lib/react/index.js", - "types": "./lib/react/index.d.ts" } }, "publishConfig": { @@ -34,17 +30,12 @@ }, "devDependencies": { "@silverhand/eslint-config": "5.0.0", - "@silverhand/eslint-config-react": "5.0.0", "@silverhand/ts-config": "5.0.0", - "@silverhand/ts-config-react": "5.0.0", "@types/node": "^20.9.5", - "@types/react": "^18.0.31", "@vitest/coverage-v8": "^1.4.0", "eslint": "^8.44.0", - "history": "^5.3.0", "lint-staged": "^15.0.0", "prettier": "^3.0.0", - "react": "^18.0.0", "typescript": "^5.3.3", "vitest": "^1.4.0" }, @@ -52,28 +43,17 @@ "node": "^20.9.0" }, "eslintConfig": { - "extends": "@silverhand/react" + "extends": "@silverhand" }, "prettier": "@silverhand/eslint-config/.prettierrc", "dependencies": { - "@microsoft/applicationinsights-clickanalytics-js": "^3.1.2", - "@microsoft/applicationinsights-react-js": "^17.1.2", - "@microsoft/applicationinsights-web": "^3.1.2", "@silverhand/essentials": "^2.9.0", "applicationinsights": "^2.9.5" }, "peerDependencies": { - "history": "^5.3.0", - "react": "^18.0.0", "tslib": "^2.4.1" }, "peerDependenciesMeta": { - "history": { - "optional": true - }, - "react": { - "optional": true - }, "tslib": { "optional": true } diff --git a/packages/app-insights/src/react/AppInsightsBoundary.tsx b/packages/app-insights/src/react/AppInsightsBoundary.tsx deleted file mode 100644 index 34444a79a38..00000000000 --- a/packages/app-insights/src/react/AppInsightsBoundary.tsx +++ /dev/null @@ -1,48 +0,0 @@ -import { type ReactNode, useContext, useEffect } from 'react'; - -import { AppInsightsContext, AppInsightsProvider } from './context.js'; -import { getPrimaryDomain } from './utils.js'; - -type AppInsightsProps = { - cloudRole: string; -}; - -const AppInsights = ({ cloudRole }: AppInsightsProps) => { - const { needsSetup, setup } = useContext(AppInsightsContext); - - useEffect(() => { - const run = async () => { - await setup(cloudRole, { cookieDomain: getPrimaryDomain() }); - }; - - if (needsSetup) { - void run(); - } - }, [cloudRole, needsSetup, setup]); - - return null; -}; - -type Props = AppInsightsProps & { - children: ReactNode; -}; - -/** - * **CAUTION:** Make sure to put this component inside `` or any other - * context providers that are render-sensitive, since we are lazy loading ApplicationInsights SDKs - * for better user experience. - * - * This component will trigger a render after the ApplicationInsights SDK is loaded which may - * cause issues for some context providers. For example, `useHandleSignInCallback` will be - * called twice if you use this component to wrap a ``. - */ -const AppInsightsBoundary = ({ children, ...rest }: Props) => { - return ( - - - {children} - - ); -}; - -export default AppInsightsBoundary; diff --git a/packages/app-insights/src/react/AppInsightsReact.ts b/packages/app-insights/src/react/AppInsightsReact.ts deleted file mode 100644 index a5b90ed685a..00000000000 --- a/packages/app-insights/src/react/AppInsightsReact.ts +++ /dev/null @@ -1,137 +0,0 @@ -import { type ClickAnalyticsPlugin } from '@microsoft/applicationinsights-clickanalytics-js'; -import type { ReactPlugin, withAITracking } from '@microsoft/applicationinsights-react-js'; -import type { ApplicationInsights, ITelemetryPlugin } from '@microsoft/applicationinsights-web'; -import { conditional, conditionalArray, type Optional } from '@silverhand/essentials'; -import { type ComponentType } from 'react'; - -export type SetupConfig = { - connectionString?: string; - /** - * The config object for the ClickAnalytics plugin. If this is provided, the plugin will be - * automatically loaded when calling `.setup()`. - * - * Wait for {@link https://github.com/microsoft/ApplicationInsights-JS/issues/2106 | microsoft/ApplicationInsights-JS#2106} - * to be resolved to use a stronger type. - * - * @see {@link https://github.com/microsoft/ApplicationInsights-JS/tree/master/extensions/applicationinsights-clickanalytics-js#configuration | ClickAnalytics configuration} - */ - clickPlugin?: Record; - cookieDomain?: string; -}; - -export class AppInsightsReact { - /** - * URL search parameters that start with `utm_`. It is an empty object until you call `.setup()`, - * which will read the URL search string and store parameters in this property. - */ - utmParameters: Record = {}; - - protected reactPlugin?: ReactPlugin; - protected clickAnalyticsPlugin?: ClickAnalyticsPlugin; - protected withAITracking?: typeof withAITracking; - protected appInsights?: ApplicationInsights; - - get instance(): Optional { - return this.appInsights; - } - - get trackPageView(): Optional { - return this.appInsights?.trackPageView.bind(this.appInsights); - } - - async setup(cloudRole: string, config?: string | SetupConfig): Promise { - const connectionStringFromConfig = - typeof config === 'string' ? config : config?.connectionString; - // The string needs to be normalized since it may contain '"' - const connectionString = ( - connectionStringFromConfig ?? process.env.APPLICATIONINSIGHTS_CONNECTION_STRING - )?.replace(/^"?(.*)"?$/g, '$1'); - - if (!connectionString) { - return false; - } - - if (this.appInsights?.config.connectionString === connectionString) { - return true; - } - - try { - // Lazy load ApplicationInsights modules - const { ReactPlugin, withAITracking } = await import( - '@microsoft/applicationinsights-react-js' - ); - const { ApplicationInsights } = await import('@microsoft/applicationinsights-web'); - - // Conditionally load ClickAnalytics plugin - const configObject = conditional(typeof config === 'object' && config) ?? {}; - const { cookieDomain, clickPlugin } = configObject; - const initClickAnalyticsPlugin = async () => { - const { ClickAnalyticsPlugin } = await import( - '@microsoft/applicationinsights-clickanalytics-js' - ); - return new ClickAnalyticsPlugin(); - }; - - // Assign React props - // https://github.com/microsoft/applicationinsights-react-js#readme - this.withAITracking = withAITracking; - this.reactPlugin = new ReactPlugin(); - - // Assign ClickAnalytics prop - this.clickAnalyticsPlugin = conditional(clickPlugin && (await initClickAnalyticsPlugin())); - - // Init ApplicationInsights instance - this.appInsights = new ApplicationInsights({ - config: { - cookieDomain, - connectionString, - enableAutoRouteTracking: false, - extensions: conditionalArray( - this.reactPlugin, - this.clickAnalyticsPlugin - ), - extensionConfig: conditional( - this.clickAnalyticsPlugin && { - [this.clickAnalyticsPlugin.identifier]: clickPlugin, - } - ), - }, - }); - - // Extract UTM parameters - const searchParams = [...new URLSearchParams(window.location.search).entries()]; - this.utmParameters = Object.fromEntries( - searchParams.filter(([key]) => key.startsWith('utm_')) - ); - - this.appInsights.addTelemetryInitializer((item) => { - // @see https://github.com/microsoft/ApplicationInsights-JS#example-setting-cloud-role-name - // @see https://github.com/microsoft/ApplicationInsights-node.js/blob/a573e40fc66981c6a3106bdc5b783d1d94f64231/Schema/PublicSchema/ContextTagKeys.bond#L83 - /* eslint-disable @silverhand/fp/no-mutation */ - item.tags = { ...item.tags, 'ai.cloud.role': cloudRole }; - /* eslint-enable @silverhand/fp/no-mutation */ - }); - - this.appInsights.loadAppInsights(); - } catch (error: unknown) { - console.error('Unable to init ApplicationInsights:'); - console.error(error); - - return false; - } - - return true; - } - - withAppInsights

(Component: ComponentType

): ComponentType

{ - if (!this.reactPlugin || !this.withAITracking) { - return Component; - } - - return this.withAITracking(this.reactPlugin, Component, undefined, 'appInsightsWrapper'); - } -} - -export const appInsightsReact = new AppInsightsReact(); - -export const withAppInsights = appInsightsReact.withAppInsights.bind(appInsightsReact); diff --git a/packages/app-insights/src/react/TrackOnce.tsx b/packages/app-insights/src/react/TrackOnce.tsx deleted file mode 100644 index d2975dd2cd6..00000000000 --- a/packages/app-insights/src/react/TrackOnce.tsx +++ /dev/null @@ -1,47 +0,0 @@ -import { type ICustomProperties } from '@microsoft/applicationinsights-web'; -import { yes } from '@silverhand/essentials'; -import { useContext, useEffect } from 'react'; - -import { getEventName, type Component, type EventType } from '../custom-event.js'; - -import { AppInsightsContext } from './context.js'; - -type Props = { - component: C; - event: EventType; - customProperties?: ICustomProperties; -}; - -const storageKeyPrefix = 'logto:insights:'; - -/** Track an event after AppInsights SDK is setup, but only once during the current session. */ -const TrackOnce = ({ component, event, customProperties }: Props) => { - const { isSetupFinished, appInsights } = useContext(AppInsightsContext); - - useEffect(() => { - const eventName = getEventName(component, event); - const storageKey = `${storageKeyPrefix}${eventName}`; - const tracked = yes(sessionStorage.getItem(storageKey)); - - if (isSetupFinished && !tracked) { - appInsights.instance?.trackEvent( - { - name: getEventName(component, event), - }, - { ...appInsights.utmParameters, ...customProperties } - ); - sessionStorage.setItem(storageKey, '1'); - } - }, [ - appInsights.instance, - appInsights.utmParameters, - component, - customProperties, - event, - isSetupFinished, - ]); - - return null; -}; - -export default TrackOnce; diff --git a/packages/app-insights/src/react/context.tsx b/packages/app-insights/src/react/context.tsx deleted file mode 100644 index 26489bd8f7a..00000000000 --- a/packages/app-insights/src/react/context.tsx +++ /dev/null @@ -1,61 +0,0 @@ -import { type ReactNode, createContext, useMemo, useState, useCallback } from 'react'; - -import { type AppInsightsReact, appInsightsReact as appInsights } from './AppInsightsReact'; - -const notImplemented = () => { - throw new Error('Not implemented'); -}; - -type Context = { - needsSetup: boolean; - isSetupFinished: boolean; - setup: (...args: Parameters) => Promise; - appInsights: AppInsightsReact; -}; - -export const AppInsightsContext = createContext({ - needsSetup: true, - isSetupFinished: false, - setup: notImplemented, - appInsights, -}); - -type Properties = { - children: ReactNode; -}; - -export type SetupStatus = 'none' | 'loading' | 'initialized' | 'failed'; - -export const AppInsightsProvider = ({ children }: Properties) => { - const [setupStatus, setSetupStatus] = useState('none'); - const setup = useCallback( - async (...args: Parameters) => { - if (setupStatus !== 'none') { - return; - } - - setSetupStatus('loading'); - const result = await appInsights.setup(...args); - - if (result) { - console.debug('Initialized ApplicationInsights'); - setSetupStatus('initialized'); - } else { - setSetupStatus('failed'); - } - }, - [setupStatus] - ); - - const context = useMemo( - () => ({ - needsSetup: setupStatus === 'none', - isSetupFinished: setupStatus === 'initialized' || setupStatus === 'failed', - setup, - appInsights, - }), - [setup, setupStatus] - ); - - return {children}; -}; diff --git a/packages/app-insights/src/react/index.ts b/packages/app-insights/src/react/index.ts deleted file mode 100644 index 638c4f0dfa9..00000000000 --- a/packages/app-insights/src/react/index.ts +++ /dev/null @@ -1,5 +0,0 @@ -export { AppInsightsReact, type SetupConfig, withAppInsights } from './AppInsightsReact.js'; -export * from './context.js'; -export * from './utils.js'; -export { default as AppInsightsBoundary } from './AppInsightsBoundary.js'; -export { default as TrackOnce } from './TrackOnce.js'; diff --git a/packages/app-insights/src/react/utils.ts b/packages/app-insights/src/react/utils.ts deleted file mode 100644 index 636664f4bf7..00000000000 --- a/packages/app-insights/src/react/utils.ts +++ /dev/null @@ -1,5 +0,0 @@ -/** - * **CAUTION:** This function takes the last two parts of the hostname which may cause issues for - * some second-level domains, e.g. `.co.uk`. - */ -export const getPrimaryDomain = () => window.location.hostname.split('.').slice(-2).join('.'); diff --git a/packages/app-insights/tsconfig.json b/packages/app-insights/tsconfig.json index 2e988e53b2f..72888320fc5 100644 --- a/packages/app-insights/tsconfig.json +++ b/packages/app-insights/tsconfig.json @@ -1,5 +1,5 @@ { - "extends": "@silverhand/ts-config-react/tsconfig.base", + "extends": "@silverhand/ts-config/tsconfig.base", "compilerOptions": { "outDir": "lib", "types": ["node"], diff --git a/packages/experience/jest.config.ts b/packages/experience/jest.config.ts index 8ab5d388c05..588c079456c 100644 --- a/packages/experience/jest.config.ts +++ b/packages/experience/jest.config.ts @@ -26,7 +26,6 @@ const config: Config.InitialOptions = { }, moduleNameMapper: { '^@/(.*)$': '/src/$1', - '^@logto/app-insights/(.*)$': '/../app-insights/lib/$1', '^@logto/shared/(.*)$': '/../shared/lib/$1', '\\.module\\.(css|sass|scss)$': 'identity-obj-proxy', }, diff --git a/packages/experience/package.json b/packages/experience/package.json index 746cc684e62..149beca5733 100644 --- a/packages/experience/package.json +++ b/packages/experience/package.json @@ -21,7 +21,6 @@ }, "devDependencies": { "@jest/types": "^29.5.0", - "@logto/app-insights": "workspace:^1.4.0", "@logto/connector-kit": "workspace:^3.0.0", "@logto/core-kit": "workspace:^2.4.0", "@logto/language-kit": "workspace:^1.1.0", diff --git a/packages/experience/src/App.tsx b/packages/experience/src/App.tsx index db44a29aab6..e58276176d3 100644 --- a/packages/experience/src/App.tsx +++ b/packages/experience/src/App.tsx @@ -1,4 +1,3 @@ -import { AppInsightsBoundary } from '@logto/app-insights/react'; import { MfaFactor, experience } from '@logto/schemas'; import { Route, Routes, BrowserRouter } from 'react-router-dom'; @@ -48,85 +47,83 @@ const App = () => { - - - }> - } /> - } /> + + }> + } /> + } /> + } + /> + } /> + + }> } + path="unknown-session" + element={} /> - } /> - - }> - } - /> - - {/* Sign-in */} - - } /> - } /> - - - {/* Register */} - - } /> - } /> - - - {/* Forgot password */} - - } /> - } /> - - - {/* Passwordless verification code */} - } /> - - {/* Mfa binding */} - - } /> - } /> - } /> - } /> - - - {/* Mfa verification */} - - } /> - } /> - } /> - } /> - - - {/* Continue set up missing profile */} - - } /> - - - {/* Social sign-in pages */} - - } /> - } /> - - - {/* Single sign-on */} - }> - } /> - } /> - - - {/* Consent */} - } /> - - } /> + + {/* Sign-in */} + + } /> + } /> + + + {/* Register */} + + } /> + } /> + + + {/* Forgot password */} + + } /> + } /> + + + {/* Passwordless verification code */} + } /> + + {/* Mfa binding */} + + } /> + } /> + } /> + } /> + + + {/* Mfa verification */} + + } /> + } /> + } /> + } /> + + + {/* Continue set up missing profile */} + + } /> + + + {/* Social sign-in pages */} + + } /> + } /> + + {/* Single sign-on */} + }> + } /> + } /> + + + {/* Consent */} + } /> + + } /> - - + + diff --git a/packages/experience/src/components/PageMeta/index.tsx b/packages/experience/src/components/PageMeta/index.tsx index eb3ad32cd60..db55e237cab 100644 --- a/packages/experience/src/components/PageMeta/index.tsx +++ b/packages/experience/src/components/PageMeta/index.tsx @@ -1,34 +1,16 @@ -import { AppInsightsContext } from '@logto/app-insights/react'; import { type TFuncKey } from 'i18next'; -import { useContext, useEffect, useState } from 'react'; import { Helmet } from 'react-helmet'; import { useTranslation } from 'react-i18next'; -import { shouldTrack } from '@/utils/cookies'; - type Props = { titleKey: TFuncKey; titleKeyInterpolation?: Record; - // eslint-disable-next-line react/boolean-prop-naming - trackPageView?: boolean; }; -const PageMeta = ({ titleKey, titleKeyInterpolation = {}, trackPageView = true }: Props) => { +const PageMeta = ({ titleKey, titleKeyInterpolation = {} }: Props) => { const { t } = useTranslation(); - const { isSetupFinished, appInsights } = useContext(AppInsightsContext); - const [pageViewTracked, setPageViewTracked] = useState(false); - - const rawTitle = t(titleKey, { lng: 'en', ...titleKeyInterpolation }); const title = t(titleKey, titleKeyInterpolation); - useEffect(() => { - // Only track once for the same page - if (shouldTrack && isSetupFinished && trackPageView && !pageViewTracked) { - appInsights.trackPageView?.({ name: `Main flow: ${String(rawTitle)}` }); - setPageViewTracked(true); - } - }, [appInsights, isSetupFinished, pageViewTracked, rawTitle, trackPageView]); - return ; }; diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index a11532c3cae..b2cf8c9b498 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -39,15 +39,6 @@ importers: packages/app-insights: dependencies: - '@microsoft/applicationinsights-clickanalytics-js': - specifier: ^3.1.2 - version: 3.1.2(tslib@2.4.1) - '@microsoft/applicationinsights-react-js': - specifier: ^17.1.2 - version: 17.1.2(history@5.3.0)(react@18.2.0)(tslib@2.4.1) - '@microsoft/applicationinsights-web': - specifier: ^3.1.2 - version: 3.1.2(tslib@2.4.1) '@silverhand/essentials': specifier: ^2.9.0 version: 2.9.0 @@ -61,39 +52,24 @@ importers: '@silverhand/eslint-config': specifier: 5.0.0 version: 5.0.0(eslint@8.44.0)(prettier@3.0.0)(typescript@5.3.3) - '@silverhand/eslint-config-react': - specifier: 5.0.0 - version: 5.0.0(eslint@8.44.0)(postcss@8.4.38)(prettier@3.0.0)(stylelint@15.11.0)(typescript@5.3.3) '@silverhand/ts-config': specifier: 5.0.0 version: 5.0.0(typescript@5.3.3) - '@silverhand/ts-config-react': - specifier: 5.0.0 - version: 5.0.0(typescript@5.3.3) '@types/node': specifier: ^20.9.5 version: 20.10.4 - '@types/react': - specifier: ^18.0.31 - version: 18.0.31 '@vitest/coverage-v8': specifier: ^1.4.0 version: 1.4.0(vitest@1.4.0) eslint: specifier: ^8.44.0 version: 8.44.0 - history: - specifier: ^5.3.0 - version: 5.3.0 lint-staged: specifier: ^15.0.0 version: 15.0.2 prettier: specifier: ^3.0.0 version: 3.0.0 - react: - specifier: ^18.0.0 - version: 18.2.0 typescript: specifier: ^5.3.3 version: 5.3.3 @@ -3402,9 +3378,6 @@ importers: '@jest/types': specifier: ^29.5.0 version: 29.6.3 - '@logto/app-insights': - specifier: workspace:^1.4.0 - version: link:../app-insights '@logto/connector-kit': specifier: workspace:^3.0.0 version: link:../toolkit/connector-kit @@ -5544,7 +5517,7 @@ packages: engines: {node: '>=14.0.0'} dependencies: '@azure/abort-controller': 1.1.0 - tslib: 2.5.0 + tslib: 2.6.2 dev: false /@azure/logger@1.0.4: @@ -6032,6 +6005,7 @@ packages: engines: {node: '>=6.9.0'} dependencies: regenerator-runtime: 0.13.11 + dev: true /@babel/runtime@7.21.0: resolution: {integrity: sha512-xwII0//EObnq89Ji5AKYQaRYiW/nZ3llSv29d49IuxPhKbtJoLP+9QUUZ4nVragQVtaVGeZrpB+ZtG/Pdy/POw==} @@ -6507,25 +6481,11 @@ packages: '@csstools/css-tokenizer': 2.0.1 dev: true - /@csstools/css-parser-algorithms@2.6.1(@csstools/css-tokenizer@2.2.4): - resolution: {integrity: sha512-ubEkAaTfVZa+WwGhs5jbo5Xfqpeaybr/RvWzvFxRs4jfq16wH8l8Ty/QEEpINxll4xhuGfdMbipRyz5QZh9+FA==} - engines: {node: ^14 || ^16 || >=18} - peerDependencies: - '@csstools/css-tokenizer': ^2.2.4 - dependencies: - '@csstools/css-tokenizer': 2.2.4 - dev: true - /@csstools/css-tokenizer@2.0.1: resolution: {integrity: sha512-sYD3H7ReR88S/4+V5VbKiBEUJF4FqvG+8aNJkxqoPAnbhFziDG22IDZc4+h+xA63SfgM+h15lq5OnLeCxQ9nPA==} engines: {node: ^14 || ^16 || >=18} dev: true - /@csstools/css-tokenizer@2.2.4: - resolution: {integrity: sha512-PuWRAewQLbDhGeTvFuq2oClaSCKPIBmHyIobCV39JHRYN0byDcUWJl5baPeNUcqrjtdMNqFooE0FGl31I3JOqw==} - engines: {node: ^14 || ^16 || >=18} - dev: true - /@csstools/media-query-list-parser@2.0.1(@csstools/css-parser-algorithms@2.0.1)(@csstools/css-tokenizer@2.0.1): resolution: {integrity: sha512-X2/OuzEbjaxhzm97UJ+95GrMeT29d1Ib+Pu+paGLuRWZnWRK9sI9r3ikmKXPWGA1C4y4JEdBEFpp9jEqCvLeRA==} engines: {node: ^14 || ^16 || >=18} @@ -6537,17 +6497,6 @@ packages: '@csstools/css-tokenizer': 2.0.1 dev: true - /@csstools/media-query-list-parser@2.1.9(@csstools/css-parser-algorithms@2.6.1)(@csstools/css-tokenizer@2.2.4): - resolution: {integrity: sha512-qqGuFfbn4rUmyOB0u8CVISIp5FfJ5GAR3mBrZ9/TKndHakdnm6pY0L/fbLcpPnrzwCyyTEZl1nUcXAYHEWneTA==} - engines: {node: ^14 || ^16 || >=18} - peerDependencies: - '@csstools/css-parser-algorithms': ^2.6.1 - '@csstools/css-tokenizer': ^2.2.4 - dependencies: - '@csstools/css-parser-algorithms': 2.6.1(@csstools/css-tokenizer@2.2.4) - '@csstools/css-tokenizer': 2.2.4 - dev: true - /@csstools/selector-specificity@2.1.1(postcss-selector-parser@6.0.11)(postcss@8.4.31): resolution: {integrity: sha512-jwx+WCqszn53YHOfvFMJJRd/B2GqkCBt+1MJSG6o5/s8+ytHMvDZXsJgUEWLk12UnLd7HYKac4BYU5i/Ron1Cw==} engines: {node: ^14 || ^16 || >=18} @@ -6559,15 +6508,6 @@ packages: postcss-selector-parser: 6.0.11 dev: true - /@csstools/selector-specificity@3.0.3(postcss-selector-parser@6.0.16): - resolution: {integrity: sha512-KEPNw4+WW5AVEIyzC80rTbWEUatTW2lXpN8+8ILC8PiPeWPjwUzrPZDIOZ2wwqDmeqOYTdSGyL3+vE5GC3FB3Q==} - engines: {node: ^14 || ^16 || >=18} - peerDependencies: - postcss-selector-parser: ^6.0.13 - dependencies: - postcss-selector-parser: 6.0.16 - dev: true - /@esbuild/aix-ppc64@0.19.12: resolution: {integrity: sha512-bmoCYyWdEL3wDQIVbcyzRyeKLgk2WtWLTWz1ZIAZF/EGbNOwSA6ew3PftJ1PqMiOOGu0OyFMzG53L0zqIpPeNA==} engines: {node: '>=12'} @@ -7488,164 +7428,10 @@ packages: resolution: {integrity: sha512-H1rQc1ZOHANWBvPcW+JpGwr+juXSxM8Q8YCkm3GhZd8REu1fHR3z99CErO1p9pkcfcxZnMdIZdIsXkOHY0NilA==} dev: true - /@microsoft/applicationinsights-analytics-js@3.1.2(tslib@2.4.1): - resolution: {integrity: sha512-HIlptHMIX3cGqTOUrdVjWb5FpYvs1xmosrIf7pnU0Y0/BER382fHCb/4BAB5mU32h/UlPX8to/d6Q20fSCtYAw==} - peerDependencies: - tslib: '*' - dependencies: - '@microsoft/applicationinsights-common': 3.1.2(tslib@2.4.1) - '@microsoft/applicationinsights-core-js': 3.1.2(tslib@2.4.1) - '@microsoft/applicationinsights-shims': 3.0.1 - '@microsoft/dynamicproto-js': 2.0.3 - '@nevware21/ts-utils': 0.11.2 - tslib: 2.4.1 - dev: false - - /@microsoft/applicationinsights-cfgsync-js@3.1.2(tslib@2.4.1): - resolution: {integrity: sha512-tVrIYxu3SCB/vYGdwPg5Inc8Kr1I9PCbqb/mIp+qOJyIRiB90VIHde6qHsttb7/ZHJJbNlztUtY4UcD5jaCBoA==} - peerDependencies: - tslib: '*' - dependencies: - '@microsoft/applicationinsights-common': 3.1.2(tslib@2.4.1) - '@microsoft/applicationinsights-core-js': 3.1.2(tslib@2.4.1) - '@microsoft/applicationinsights-shims': 3.0.1 - '@microsoft/dynamicproto-js': 2.0.3 - '@nevware21/ts-async': 0.5.1 - '@nevware21/ts-utils': 0.11.2 - tslib: 2.4.1 - dev: false - - /@microsoft/applicationinsights-channel-js@3.1.2(tslib@2.4.1): - resolution: {integrity: sha512-QyPxpOOhtohFzcl4tzfWp4seN6JaToF66DZ1qjsYkUmEyHAackWSsv9m7qvuaAcCB9WrUzW9y0mRXgGKsEJcAg==} - peerDependencies: - tslib: '*' - dependencies: - '@microsoft/applicationinsights-common': 3.1.2(tslib@2.4.1) - '@microsoft/applicationinsights-core-js': 3.1.2(tslib@2.4.1) - '@microsoft/applicationinsights-shims': 3.0.1 - '@microsoft/dynamicproto-js': 2.0.3 - '@nevware21/ts-async': 0.5.1 - '@nevware21/ts-utils': 0.11.2 - tslib: 2.4.1 - dev: false - - /@microsoft/applicationinsights-clickanalytics-js@3.1.2(tslib@2.4.1): - resolution: {integrity: sha512-zlOip0roNUGyrNb0vnsNSYYs5kETbf6Tlgijueyy9nrY14RbWCcIv0AhIxfM4juLIxlnl6Lo0YYdRe41P9yjng==} - peerDependencies: - tslib: '*' - dependencies: - '@microsoft/applicationinsights-common': 3.1.2(tslib@2.4.1) - '@microsoft/applicationinsights-core-js': 3.1.2(tslib@2.4.1) - '@microsoft/applicationinsights-properties-js': 3.1.2(tslib@2.4.1) - '@microsoft/applicationinsights-shims': 3.0.1 - '@microsoft/dynamicproto-js': 2.0.3 - '@nevware21/ts-utils': 0.11.2 - tslib: 2.4.1 - dev: false - - /@microsoft/applicationinsights-common@3.1.2(tslib@2.4.1): - resolution: {integrity: sha512-ivu3s73xt6Owakepnx2mbrMCry1mVHrA/2TL4nKCRLad6O3IBK3MkruMoeb3hoWpECBhErFRVj+/b0Kh7dl/Lw==} - peerDependencies: - tslib: '*' - dependencies: - '@microsoft/applicationinsights-core-js': 3.1.2(tslib@2.4.1) - '@microsoft/applicationinsights-shims': 3.0.1 - '@microsoft/dynamicproto-js': 2.0.3 - '@nevware21/ts-utils': 0.11.2 - tslib: 2.4.1 - dev: false - - /@microsoft/applicationinsights-core-js@3.1.2(tslib@2.4.1): - resolution: {integrity: sha512-xsJAm52tV355S/MogTunV/m1wg6P6tFg9Yhi4AC2OE9p2aa0k/FYHzWmrCrsEAVimCd8n/iTXmMRSrQk5QpxiA==} - peerDependencies: - tslib: '*' - dependencies: - '@microsoft/applicationinsights-shims': 3.0.1 - '@microsoft/dynamicproto-js': 2.0.3 - '@nevware21/ts-async': 0.5.1 - '@nevware21/ts-utils': 0.11.2 - tslib: 2.4.1 - dev: false - - /@microsoft/applicationinsights-dependencies-js@3.1.2(tslib@2.4.1): - resolution: {integrity: sha512-vFf/6s1ACvcmeDpAAMin2JefPQ+7lthfcNThLFOMPxRxsIKIsQMZ1rHhqd55xcZTNITCywhuK4dD+/YkwC9HPw==} - peerDependencies: - tslib: '*' - dependencies: - '@microsoft/applicationinsights-common': 3.1.2(tslib@2.4.1) - '@microsoft/applicationinsights-core-js': 3.1.2(tslib@2.4.1) - '@microsoft/applicationinsights-shims': 3.0.1 - '@microsoft/dynamicproto-js': 2.0.3 - '@nevware21/ts-async': 0.5.1 - '@nevware21/ts-utils': 0.11.2 - tslib: 2.4.1 - dev: false - - /@microsoft/applicationinsights-properties-js@3.1.2(tslib@2.4.1): - resolution: {integrity: sha512-GK+o/7RyIfySxAIHvw2oba5ca4WyvjE40+1gnRL15Pd/qnRn8+6OIOTpJ4kT1wg2l8CTVtPrUmIK4zeN6MqocA==} - peerDependencies: - tslib: '*' - dependencies: - '@microsoft/applicationinsights-common': 3.1.2(tslib@2.4.1) - '@microsoft/applicationinsights-core-js': 3.1.2(tslib@2.4.1) - '@microsoft/applicationinsights-shims': 3.0.1 - '@microsoft/dynamicproto-js': 2.0.3 - '@nevware21/ts-utils': 0.11.2 - tslib: 2.4.1 - dev: false - - /@microsoft/applicationinsights-react-js@17.1.2(history@5.3.0)(react@18.2.0)(tslib@2.4.1): - resolution: {integrity: sha512-i98Ep/UQvuLeDWWCWOLuvpF1cACOR98gafpTcOVeZSPKYlUtvFAqx6Xkn7HjjqZklxP9h0Hqjs5dreu4D5nM2A==} - peerDependencies: - history: '>= 4.10.1' - react: '>= 17.0.1 || ^18.0.0' - tslib: '*' - dependencies: - '@microsoft/applicationinsights-common': 3.1.2(tslib@2.4.1) - '@microsoft/applicationinsights-core-js': 3.1.2(tslib@2.4.1) - '@microsoft/applicationinsights-shims': 3.0.1 - '@microsoft/dynamicproto-js': 2.0.3 - '@nevware21/ts-utils': 0.11.2 - history: 5.3.0 - react: 18.2.0 - tslib: 2.4.1 - dev: false - - /@microsoft/applicationinsights-shims@3.0.1: - resolution: {integrity: sha512-DKwboF47H1nb33rSUfjqI6ryX29v+2QWcTrRvcQDA32AZr5Ilkr7whOOSsD1aBzwqX0RJEIP1Z81jfE3NBm/Lg==} - dependencies: - '@nevware21/ts-utils': 0.11.2 - dev: false - /@microsoft/applicationinsights-web-snippet@1.0.1: resolution: {integrity: sha512-2IHAOaLauc8qaAitvWS+U931T+ze+7MNWrDHY47IENP5y2UA0vqJDu67kWZDdpCN1fFC77sfgfB+HV7SrKshnQ==} dev: false - /@microsoft/applicationinsights-web@3.1.2(tslib@2.4.1): - resolution: {integrity: sha512-q+6RUtKChXrMf2+TN/dohK2p+LUTw8EIYKFtrujYG8/jh88fCdVqmgTCPk9bLb4wsH/dd5wLS+Aw7qVQtlYa9Q==} - peerDependencies: - tslib: '*' - dependencies: - '@microsoft/applicationinsights-analytics-js': 3.1.2(tslib@2.4.1) - '@microsoft/applicationinsights-cfgsync-js': 3.1.2(tslib@2.4.1) - '@microsoft/applicationinsights-channel-js': 3.1.2(tslib@2.4.1) - '@microsoft/applicationinsights-common': 3.1.2(tslib@2.4.1) - '@microsoft/applicationinsights-core-js': 3.1.2(tslib@2.4.1) - '@microsoft/applicationinsights-dependencies-js': 3.1.2(tslib@2.4.1) - '@microsoft/applicationinsights-properties-js': 3.1.2(tslib@2.4.1) - '@microsoft/applicationinsights-shims': 3.0.1 - '@microsoft/dynamicproto-js': 2.0.3 - '@nevware21/ts-async': 0.5.1 - '@nevware21/ts-utils': 0.11.2 - tslib: 2.4.1 - dev: false - - /@microsoft/dynamicproto-js@2.0.3: - resolution: {integrity: sha512-JTWTU80rMy3mdxOjjpaiDQsTLZ6YSGGqsjURsY6AUQtIj0udlF/jYmhdLZu8693ZIC0T1IwYnFa0+QeiMnziBA==} - dependencies: - '@nevware21/ts-utils': 0.11.2 - dev: false - /@mischnic/json-sourcemap@0.1.0: resolution: {integrity: sha512-dQb3QnfNqmQNYA4nFSN/uLaByIic58gOXq4Y4XqLOWmOrw73KmJPt/HLyG0wvn1bnR6mBKs/Uwvkh+Hns1T0XA==} engines: {node: '>=12.0.0'} @@ -7725,16 +7511,6 @@ packages: dev: true optional: true - /@nevware21/ts-async@0.5.1: - resolution: {integrity: sha512-O2kN8n2HpDWJ7Oji+oTMnhITrCndmrNvrHbGDwAIBydx+FWvLE/vrw4QwnRRMvSCa2AJrcP59Ryklxv30KfkWQ==} - dependencies: - '@nevware21/ts-utils': 0.11.2 - dev: false - - /@nevware21/ts-utils@0.11.2: - resolution: {integrity: sha512-80W8BkS09kkGuUHJX50Fqq+QqAslxUaOQytH+3JhRacXs1EpEt2JOOkYKytqFZAYir3SeH9fahniEaDzIBxlUw==} - dev: false - /@nodelib/fs.scandir@2.1.5: resolution: {integrity: sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==} engines: {node: '>= 8'} @@ -9017,30 +8793,6 @@ packages: - typescript dev: true - /@silverhand/eslint-config-react@5.0.0(eslint@8.44.0)(postcss@8.4.38)(prettier@3.0.0)(stylelint@15.11.0)(typescript@5.3.3): - resolution: {integrity: sha512-ZHLke0twGmW73b23mPh1r38fw+4L+XL+9dedml21+OnXpftT3XM00igRocUgdfGTGxbGbQy1n5fLN5gizv5InQ==} - engines: {node: ^20.9.0} - peerDependencies: - stylelint: ^15.0.0 - dependencies: - '@silverhand/eslint-config': 5.0.0(eslint@8.44.0)(prettier@3.0.0)(typescript@5.3.3) - eslint-config-xo-react: 0.27.0(eslint-plugin-react-hooks@4.6.0)(eslint-plugin-react@7.32.2)(eslint@8.44.0) - eslint-plugin-jsx-a11y: 6.7.1(eslint@8.44.0) - eslint-plugin-react: 7.32.2(eslint@8.44.0) - eslint-plugin-react-hooks: 4.6.0(eslint@8.44.0) - stylelint: 15.11.0(typescript@5.3.3) - stylelint-config-xo-scss: 0.15.0(postcss@8.4.38)(stylelint@15.11.0) - transitivePeerDependencies: - - '@types/eslint' - - eslint - - eslint-import-resolver-node - - eslint-import-resolver-webpack - - postcss - - prettier - - supports-color - - typescript - dev: true - /@silverhand/eslint-config@5.0.0(eslint@8.44.0)(prettier@3.0.0)(typescript@5.3.3): resolution: {integrity: sha512-cVoe58TAtt2u5gvk9WpTGg2NlA3DVw6DeBOV1qxj3gnFGOtvUf6IMeX5gwcox3+zMNBOmVmOGljeVS7bSuJ80w==} engines: {node: ^20.9.0} @@ -10299,7 +10051,6 @@ packages: '@types/keygrip': 1.0.2 '@types/koa-compose': 3.2.5 '@types/node': 20.12.7 - dev: false /@types/koa__cors@5.0.0: resolution: {integrity: sha512-LCk/n25Obq5qlernGOK/2LUwa/2YJb2lxHUkkvYFDOpLXlVI6tKcdfCHRBQnOY4LwH6el5WOLs6PD/a8Uzau6g==} @@ -10340,10 +10091,6 @@ packages: resolution: {integrity: sha512-jhuKLIRrhvCPLqwPcx6INqmKeiA5EWrsCOPhrlFSrbrmU4ZMPjj5Ul/oLCMDO98XRUIwVm78xICz4EPCektzeQ==} dev: true - /@types/minimist@1.2.5: - resolution: {integrity: sha512-hov8bUuiLiyFPGyFPE1lwWhmzYbirOXQNNo40+y3zow8aFVTeyn3VWL0VFFfdNddA8S4Vf0Tc062rzyNr7Paag==} - dev: true - /@types/ms@0.7.31: resolution: {integrity: sha512-iiUgKzV9AuaEkZqkOLDIvlQiL6ltuZd9tGcW3gwpnX8JbuiuhFlEGmmFXEXkN50Cvq7Os88IY2v0dkDqXYWVgA==} dev: true @@ -10385,10 +10132,6 @@ packages: resolution: {integrity: sha512-Gj7cI7z+98M282Tqmp2K5EIsoouUEzbBJhQQzDE3jSIRk6r9gsz0oUokqIUR4u1R3dMHo0pDHM7sNOHyhulypw==} dev: true - /@types/normalize-package-data@2.4.4: - resolution: {integrity: sha512-37i+OaWTh9qeK4LSHPsyRC7NahnGotNuZvjLSgcPzblpHB3rrCJxAOgI5gCdKm7coonsaX1Of0ILiTcnZjbfxA==} - dev: true - /@types/oidc-provider@8.4.4: resolution: {integrity: sha512-+SlmKc4qlCJLjpw6Du/8cXw18JsPEYyQwoy+xheLkiuNsCz1mPEYI/lRXLQHvfJD9TH6+2/WDTLZQ2UUJ5G4bw==} dependencies: @@ -12229,11 +11972,6 @@ packages: engines: {node: '>=12.22'} dev: true - /css-functions-list@3.2.1: - resolution: {integrity: sha512-Nj5YcaGgBtuUmn1D7oHqPW0c9iui7xsTsj5lIX8ZgevdfhmjFfKB3r8moHJtNJnctnYXJyYX5I1pp90HM4TPgQ==} - engines: {node: '>=12 || >=16'} - dev: true - /css-select@4.3.0: resolution: {integrity: sha512-wPpOYtnsVontu2mODhA19JrqWxNsfdatRKd64kmpRbQgh1KtItko5sTnEpPdpSaJszTOhEMlF/RPz28qj4HqhQ==} dependencies: @@ -12451,11 +12189,6 @@ packages: resolution: {integrity: sha512-z2S+W9X73hAUUki+N+9Za2lBlun89zigOyGrsax+KUQ6wKW4ZoWpEYBkGhQjwAjjDCkWxhY0VKEhk8wzY7F5cA==} engines: {node: '>=0.10.0'} - /decamelize@5.0.1: - resolution: {integrity: sha512-VfxadyCECXgQlkoEAjeghAr5gY3Hf+IKjKb+X8tGVDtveCjN+USwprd2q3QXBR9T1+x2DG0XZF5/w+7HAtSaXA==} - engines: {node: '>=10'} - dev: true - /decamelize@6.0.0: resolution: {integrity: sha512-Fv96DCsdOgB6mdGl67MT5JaTNKRzrzill5OH5s8bjYJXVlcXyPYGyPsUkWyGV5p1TXI5esYIYMMeDJL0hEIwaA==} engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} @@ -13760,13 +13493,6 @@ packages: flat-cache: 3.0.4 dev: true - /file-entry-cache@7.0.2: - resolution: {integrity: sha512-TfW7/1iI4Cy7Y8L6iqNdZQVvdXn0f8B4QcIXmkIbtTIe/Okm/nSlHb4IwGzRVOd3WfSieCgvf5cMzEfySAIl0g==} - engines: {node: '>=12.0.0'} - dependencies: - flat-cache: 3.2.0 - dev: true - /file-selector@0.6.0: resolution: {integrity: sha512-QlZ5yJC0VxHxQQsQhXvBaC7VRJ2uaxTf+Tfpu4Z/OcVQJVpZO+DGU0rkoVW5ce2SccxugvpBJoMvUs59iILYdw==} engines: {node: '>= 12'} @@ -13850,23 +13576,10 @@ packages: rimraf: 3.0.2 dev: true - /flat-cache@3.2.0: - resolution: {integrity: sha512-CYcENa+FtcUKLmhhqyctpclsq7QF38pKjZHsGNiSQF5r4FtoKDWabFDl3hzaEQMvT1LHEysw5twgLvpYYb4vbw==} - engines: {node: ^10.12.0 || >=12.0.0} - dependencies: - flatted: 3.3.1 - keyv: 4.5.4 - rimraf: 3.0.2 - dev: true - /flatted@3.2.7: resolution: {integrity: sha512-5nqDSxl8nn5BSNxyR3n4I6eDmbolI6WT+QqR547RwxQapgjQBmtktdP+HTBb/a/zLsbzERTONyUB5pefh5TtjQ==} dev: true - /flatted@3.3.1: - resolution: {integrity: sha512-X8cqMLLie7KsNUDSdzeN8FYK9rEt4Dt67OsG/DNGnYTSDBG4uFAJFBnUeiV+zCVAvwFy56IjM9sH51jVaEhNxw==} - dev: true - /follow-redirects@1.15.5: resolution: {integrity: sha512-vSFWUON1B+yAw1VN4xMfxgn5fTUiaOzAJCKBwIIgT/+7CuGy9+r+5gITvP62j3RmaD5Ph65UaERdOSRGUzZtgw==} engines: {node: '>=4.0'} @@ -14519,6 +14232,7 @@ packages: resolution: {integrity: sha512-ZqaKwjjrAYUYfLG+htGaIIZ4nioX2L70ZUMIFysS3xvBsSG4x/n1V6TXV3N8ZYNuFGlDirFg32T7B6WOUPDYcQ==} dependencies: '@babel/runtime': 7.19.4 + dev: true /hoist-non-react-statics@3.3.2: resolution: {integrity: sha512-/gGivxi8JPKWNm/W0jSmzcMPpfpPLc3dY/6GxhX2hQ9iGj3aDfklV4ET7NjKpSinLpJ5vafa9iiGIEZg10SfBw==} @@ -14571,11 +14285,6 @@ packages: engines: {node: '>=8'} dev: true - /html-tags@3.3.1: - resolution: {integrity: sha512-ztqyC3kLto0e9WbNp0aeP+M3kTt+nbaIveGmUxAtZa+8iFgKLUOD4YKM5j+f3QD89bra7UeumolZHKuOXnTmeQ==} - engines: {node: '>=8'} - dev: true - /html-url-attributes@3.0.0: resolution: {integrity: sha512-/sXbVCWayk6GDVg3ctOX6nxaVj7So40FcFAnWlWGNAB1LpYKcV5Cd10APjPjW80O7zYW2MsjBV4zZ7IZO5fVow==} dev: true @@ -14879,11 +14588,6 @@ packages: engines: {node: '>=8'} dev: true - /indent-string@5.0.0: - resolution: {integrity: sha512-m6FAo/spmsW2Ab2fU35JTYwtOKa2yAwXSwgjSv1TJzh4Mh7mC3lzAOVLBprb72XsTrgkEIsl7YrFNAiDiRhIGg==} - engines: {node: '>=12'} - dev: true - /inflation@2.0.0: resolution: {integrity: sha512-m3xv4hJYR2oXw4o4Y5l6P5P16WYmazYof+el6Al3f+YlggGj6qT9kImBAnzDelRALnP5d3h4jGBPKzYCizjZZw==} engines: {node: '>= 0.8.0'} @@ -16131,6 +15835,7 @@ packages: /js-tokens@4.0.0: resolution: {integrity: sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==} + dev: true /js-tokens@8.0.3: resolution: {integrity: sha512-UfJMcSJc+SEXEl9lH/VLHSZbThQyLpw1vLO1Lb+j4RWDvG3N2f7yj3PVQA3cmkTBNldJ9eFnM+xEXxHIXrYiJw==} @@ -16221,6 +15926,7 @@ packages: /json-buffer@3.0.1: resolution: {integrity: sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==} + dev: false /json-parse-even-better-errors@2.3.1: resolution: {integrity: sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==} @@ -16357,6 +16063,7 @@ packages: resolution: {integrity: sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==} dependencies: json-buffer: 3.0.1 + dev: false /kind-of@6.0.3: resolution: {integrity: sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==} @@ -16377,10 +16084,6 @@ packages: resolution: {integrity: sha512-5FZRzrZzNTBruuurWpvZnvP9pum+fe0HcK8z/ooo+U+Hmp4vtbyp1/QDsqmufirXy4egGzbaH/y2uCZf+6W5Kg==} dev: true - /known-css-properties@0.29.0: - resolution: {integrity: sha512-Ne7wqW7/9Cz54PDt4I3tcV+hAyat8ypyOGzYRJQfdxnnjeWsTxt1cy8pjvvKeI5kfXuyvULyeeAvwvvtAX3ayQ==} - dev: true - /koa-body@6.0.1: resolution: {integrity: sha512-M8ZvMD8r+kPHy28aWP9VxL7kY8oPWA+C7ZgCljrCMeaU7uX6wsIQgDHskyrAr9sw+jqnIXyv4Mlxri5R4InIJg==} dependencies: @@ -16882,6 +16585,7 @@ packages: hasBin: true dependencies: js-tokens: 4.0.0 + dev: true /loupe@2.3.7: resolution: {integrity: sha512-zSMINGVYkdpYSOBmLi0D1Uo7JU9nVdQKrHxC8eYlV+9YKK9WePqAlL7lSlorG/U2Fw1w0hTBmaa/jrQ3UbPHtA==} @@ -17184,24 +16888,6 @@ packages: resolution: {integrity: sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g=} engines: {node: '>= 0.6'} - /meow@10.1.5: - resolution: {integrity: sha512-/d+PQ4GKmGvM9Bee/DPa8z3mXs/pkvJE2KEThngVNOqtmljC6K7NMPxtc2JeZYTmpWb9k/TmxjeL18ez3h7vCw==} - engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} - dependencies: - '@types/minimist': 1.2.5 - camelcase-keys: 7.0.2 - decamelize: 5.0.1 - decamelize-keys: 1.1.1 - hard-rejection: 2.1.0 - minimist-options: 4.1.0 - normalize-package-data: 3.0.3 - read-pkg-up: 8.0.0 - redent: 4.0.0 - trim-newlines: 4.1.1 - type-fest: 1.4.0 - yargs-parser: 20.2.9 - dev: true - /meow@12.1.1: resolution: {integrity: sha512-BhXM0Au22RwUneMPwSCnyhTOizdWoIEPU9sp0Aqa1PnDMR5Wv2FGXYDjuzJEIX+Eo2Rb8xuYe5jrnm5QowQFkw==} engines: {node: '>=16.10'} @@ -18710,15 +18396,6 @@ packages: postcss: 8.4.31 dev: true - /postcss-safe-parser@6.0.0(postcss@8.4.38): - resolution: {integrity: sha512-FARHN8pwH+WiS2OPCxJI8FuRJpTVnn6ZNFiqAM2aeW2LwTHWWmWgIyKC6cUo0L8aeKiF/14MNvnpls6R2PBeMQ==} - engines: {node: '>=12.0'} - peerDependencies: - postcss: ^8.3.3 - dependencies: - postcss: 8.4.38 - dev: true - /postcss-scss@4.0.5(postcss@8.4.31): resolution: {integrity: sha512-F7xpB6TrXyqUh3GKdyB4Gkp3QL3DDW1+uI+gxx/oJnUt/qXI4trj5OGlp9rOKdoABGULuqtqeG+3HEVQk4DjmA==} engines: {node: '>=12.0'} @@ -18728,15 +18405,6 @@ packages: postcss: 8.4.31 dev: true - /postcss-scss@4.0.5(postcss@8.4.38): - resolution: {integrity: sha512-F7xpB6TrXyqUh3GKdyB4Gkp3QL3DDW1+uI+gxx/oJnUt/qXI4trj5OGlp9rOKdoABGULuqtqeG+3HEVQk4DjmA==} - engines: {node: '>=12.0'} - peerDependencies: - postcss: ^8.3.3 - dependencies: - postcss: 8.4.38 - dev: true - /postcss-selector-parser@6.0.11: resolution: {integrity: sha512-zbARubNdogI9j7WY4nQJBiNqQf3sLS3wCP4WfOidu+p28LofJqDH1tcXypGrcmMHhDk2t9wGhCsYe/+szLTy1g==} engines: {node: '>=4'} @@ -18753,14 +18421,6 @@ packages: util-deprecate: 1.0.2 dev: true - /postcss-selector-parser@6.0.16: - resolution: {integrity: sha512-A0RVJrX+IUkVZbW3ClroRWurercFhieevHB38sr2+l9eUClMqome3LmEmnhlNy+5Mr2EYN6B2Kaw9wYdd+VHiw==} - engines: {node: '>=4'} - dependencies: - cssesc: 3.0.0 - util-deprecate: 1.0.2 - dev: true - /postcss-sorting@7.0.1(postcss@8.4.31): resolution: {integrity: sha512-iLBFYz6VRYyLJEJsBJ8M3TCqNcckVzz4wFounSc5Oez35ogE/X+aoC5fFu103Ot7NyvjU3/xqIXn93Gp3kJk4g==} peerDependencies: @@ -18795,15 +18455,6 @@ packages: source-map-js: 1.0.2 dev: true - /postcss@8.4.38: - resolution: {integrity: sha512-Wglpdk03BSfXkHoQa3b/oulrotAkwrlLDRSOb9D0bN86FdRyE9lppSp33aHNPgBa0JKCoB+drFLZkQoRRYae5A==} - engines: {node: ^10 || ^12 || >=14} - dependencies: - nanoid: 3.3.7 - picocolors: 1.0.0 - source-map-js: 1.2.0 - dev: true - /postgres-array@2.0.0: resolution: {integrity: sha512-VpZrUqU5A69eQyW2c5CA1jtLecCsN2U/bD6VilrFDWq5+5UIEVO7nazS3TEcHf1zuPYO/sqGvUvW62g86RXZuA==} engines: {node: '>=4'} @@ -19513,6 +19164,7 @@ packages: engines: {node: '>=0.10.0'} dependencies: loose-envify: 1.4.0 + dev: true /reactcss@1.2.3(react@18.2.0): resolution: {integrity: sha512-KiwVUcFu1RErkI97ywr8nvx8dNOpT03rbnma0SSalTYjkrPYaEajR4a/MRt6DZ46K6arDRbWMNHF+xH7G7n/8A==} @@ -19532,15 +19184,6 @@ packages: type-fest: 0.8.1 dev: true - /read-pkg-up@8.0.0: - resolution: {integrity: sha512-snVCqPczksT0HS2EC+SxUndvSzn6LRCwpfSvLrIfR5BKDQQZMaI6jPRC9dYvYFDRAuFEAnkwww8kBBNE/3VvzQ==} - engines: {node: '>=12'} - dependencies: - find-up: 5.0.0 - read-pkg: 6.0.0 - type-fest: 1.4.0 - dev: true - /read-pkg@5.2.0: resolution: {integrity: sha512-Ug69mNOpfvKDAc2Q8DRpMjjzdtrnv9HcSMX+4VsZxD1aZ6ZzrIE7rlzXBtWTyhULSMKg076AW6WR5iZpD0JiOg==} engines: {node: '>=8'} @@ -19551,16 +19194,6 @@ packages: type-fest: 0.6.0 dev: true - /read-pkg@6.0.0: - resolution: {integrity: sha512-X1Fu3dPuk/8ZLsMhEj5f4wFAF0DWoK7qhGJvgaijocXxBmSToKfbFtqbxMO7bVjNA1dmE5huAzjXj/ey86iw9Q==} - engines: {node: '>=12'} - dependencies: - '@types/normalize-package-data': 2.4.4 - normalize-package-data: 3.0.3 - parse-json: 5.2.0 - type-fest: 1.4.0 - dev: true - /read-yaml-file@1.1.0: resolution: {integrity: sha512-VIMnQi/Z4HT2Fxuwg5KrY174U1VdUIASQVWXXyqtNRtxSr9IYkn1rsI6Tb6HsrHCmB7gVpNwX6JxPTHcH6IoTA==} engines: {node: '>=6'} @@ -19624,14 +19257,6 @@ packages: strip-indent: 3.0.0 dev: true - /redent@4.0.0: - resolution: {integrity: sha512-tYkDkVVtYkSVhuQ4zBgfvciymHaeuel+zFKXShfDnFP5SyVEP7qo70Rf1jTOTCx3vGNAbnEi/xFkcfQVMIBWag==} - engines: {node: '>=12'} - dependencies: - indent-string: 5.0.0 - strip-indent: 4.0.0 - dev: true - /redis@4.6.5: resolution: {integrity: sha512-O0OWA36gDQbswOdUuAhRL6mTZpHFN525HlgZgDaVNgCJIAZR3ya06NTESb0R+TUZ+BFaDpz6NnnVvoMx9meUFg==} dependencies: @@ -20296,11 +19921,6 @@ packages: engines: {node: '>=0.10.0'} dev: true - /source-map-js@1.2.0: - resolution: {integrity: sha512-itJW8lvSA0TXEphiRoawsCksnlf8SyvmFzIhltqAHluXd88pkCd+cXJVHTDwdCr0IzwptSm035IHQktUu1QUMg==} - engines: {node: '>=0.10.0'} - dev: true - /source-map-support@0.5.13: resolution: {integrity: sha512-SHSKFHadjVA5oR4PPqhtAVdcBWwRYVd6g6cAXnIbRiIwc2EhPrTuKUBdSLvlEKyIP3GCf89fltvcZiP9MMFA1w==} dependencies: @@ -20592,13 +20212,6 @@ packages: min-indent: 1.0.1 dev: true - /strip-indent@4.0.0: - resolution: {integrity: sha512-mnVSV2l+Zv6BLpSD/8V87CW/y9EmmbYzGCIavsnsI6/nwn26DwffM/yztm30Z/I2DY9wdS3vXVCMnHDgZaVNoA==} - engines: {node: '>=12'} - dependencies: - min-indent: 1.0.1 - dev: true - /strip-json-comments@3.1.1: resolution: {integrity: sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==} engines: {node: '>=8'} @@ -20648,20 +20261,6 @@ packages: - postcss dev: true - /stylelint-config-xo-scss@0.15.0(postcss@8.4.38)(stylelint@15.11.0): - resolution: {integrity: sha512-X9WD8cDofWFWy3uaKdwwm+DjEvgI/+h7AtlaPagkhNAeOWH/GFQoeciBvNvyJ8tB1p00SoIzCn2IIOIKXCbxYA==} - engines: {node: '>=12'} - peerDependencies: - stylelint: '>=14.5.1 || ^15.0.0' - dependencies: - postcss-scss: 4.0.5(postcss@8.4.38) - stylelint: 15.11.0(typescript@5.3.3) - stylelint-config-xo: 0.21.1(stylelint@15.11.0) - stylelint-scss: 4.3.0(stylelint@15.11.0) - transitivePeerDependencies: - - postcss - dev: true - /stylelint-config-xo@0.21.1(stylelint@15.0.0): resolution: {integrity: sha512-ORyxhq/Yutg27NgYlStkbXhK+Lz1SqZJDqV9Y2oWcfRFcDdgVAyM6ic7frOW00UH+OFyuGpTdIbTNTtVgsWpcw==} engines: {node: '>=12'} @@ -20673,17 +20272,6 @@ packages: stylelint-order: 5.0.0(stylelint@15.0.0) dev: true - /stylelint-config-xo@0.21.1(stylelint@15.11.0): - resolution: {integrity: sha512-ORyxhq/Yutg27NgYlStkbXhK+Lz1SqZJDqV9Y2oWcfRFcDdgVAyM6ic7frOW00UH+OFyuGpTdIbTNTtVgsWpcw==} - engines: {node: '>=12'} - peerDependencies: - stylelint: '>=14 || ^15.0.0' - dependencies: - stylelint: 15.11.0(typescript@5.3.3) - stylelint-declaration-block-no-ignored-properties: 2.5.0(stylelint@15.11.0) - stylelint-order: 5.0.0(stylelint@15.11.0) - dev: true - /stylelint-declaration-block-no-ignored-properties@2.5.0(stylelint@15.0.0): resolution: {integrity: sha512-UNz5nUC5GMgMb6GPc/pHUTC0+ydxTdj2mUn7XcKRdwQoiUzzUmWWdSf1aFv2UzrW4x8JYNReE1u5JOj7g0ThJw==} engines: {node: '>=6'} @@ -20693,15 +20281,6 @@ packages: stylelint: 15.0.0 dev: true - /stylelint-declaration-block-no-ignored-properties@2.5.0(stylelint@15.11.0): - resolution: {integrity: sha512-UNz5nUC5GMgMb6GPc/pHUTC0+ydxTdj2mUn7XcKRdwQoiUzzUmWWdSf1aFv2UzrW4x8JYNReE1u5JOj7g0ThJw==} - engines: {node: '>=6'} - peerDependencies: - stylelint: ^7.0.0 || ^8.0.0 || ^9.0.0 || ^10.0.0 || ^11.0.0 || ^12.0.0 || ^13.0.0 || ^14.0.0 || ^15.0.0 - dependencies: - stylelint: 15.11.0(typescript@5.3.3) - dev: true - /stylelint-order@5.0.0(stylelint@15.0.0): resolution: {integrity: sha512-OWQ7pmicXufDw5BlRqzdz3fkGKJPgLyDwD1rFY3AIEfIH/LQY38Vu/85v8/up0I+VPiuGRwbc2Hg3zLAsJaiyw==} peerDependencies: @@ -20712,16 +20291,6 @@ packages: stylelint: 15.0.0 dev: true - /stylelint-order@5.0.0(stylelint@15.11.0): - resolution: {integrity: sha512-OWQ7pmicXufDw5BlRqzdz3fkGKJPgLyDwD1rFY3AIEfIH/LQY38Vu/85v8/up0I+VPiuGRwbc2Hg3zLAsJaiyw==} - peerDependencies: - stylelint: ^14.0.0 || ^15.0.0 - dependencies: - postcss: 8.4.31 - postcss-sorting: 7.0.1(postcss@8.4.31) - stylelint: 15.11.0(typescript@5.3.3) - dev: true - /stylelint-scss@4.3.0(stylelint@15.0.0): resolution: {integrity: sha512-GvSaKCA3tipzZHoz+nNO7S02ZqOsdBzMiCx9poSmLlb3tdJlGddEX/8QzCOD8O7GQan9bjsvLMsO5xiw6IhhIQ==} peerDependencies: @@ -20735,19 +20304,6 @@ packages: stylelint: 15.0.0 dev: true - /stylelint-scss@4.3.0(stylelint@15.11.0): - resolution: {integrity: sha512-GvSaKCA3tipzZHoz+nNO7S02ZqOsdBzMiCx9poSmLlb3tdJlGddEX/8QzCOD8O7GQan9bjsvLMsO5xiw6IhhIQ==} - peerDependencies: - stylelint: ^14.5.1 || ^15.0.0 - dependencies: - lodash: 4.17.21 - postcss-media-query-parser: 0.2.3 - postcss-resolve-nested-selector: 0.1.1 - postcss-selector-parser: 6.0.13 - postcss-value-parser: 4.2.0 - stylelint: 15.11.0(typescript@5.3.3) - dev: true - /stylelint@15.0.0: resolution: {integrity: sha512-K97Jgy0ZYMSs6gXoboXbWvc0KvvGnUftiI1Tiv70mQ/DpeDTHOlqQSk3o65Ien+ddYAJeLjzkYM0O6TWiHdoSg==} engines: {node: ^14.13.1 || >=16.0.0} @@ -20799,56 +20355,6 @@ packages: - supports-color dev: true - /stylelint@15.11.0(typescript@5.3.3): - resolution: {integrity: sha512-78O4c6IswZ9TzpcIiQJIN49K3qNoXTM8zEJzhaTE/xRTCZswaovSEVIa/uwbOltZrk16X4jAxjaOhzz/hTm1Kw==} - engines: {node: ^14.13.1 || >=16.0.0} - hasBin: true - dependencies: - '@csstools/css-parser-algorithms': 2.6.1(@csstools/css-tokenizer@2.2.4) - '@csstools/css-tokenizer': 2.2.4 - '@csstools/media-query-list-parser': 2.1.9(@csstools/css-parser-algorithms@2.6.1)(@csstools/css-tokenizer@2.2.4) - '@csstools/selector-specificity': 3.0.3(postcss-selector-parser@6.0.16) - balanced-match: 2.0.0 - colord: 2.9.3 - cosmiconfig: 8.3.6(typescript@5.3.3) - css-functions-list: 3.2.1 - css-tree: 2.3.1 - debug: 4.3.4 - fast-glob: 3.3.2 - fastest-levenshtein: 1.0.16 - file-entry-cache: 7.0.2 - global-modules: 2.0.0 - globby: 11.1.0 - globjoin: 0.1.4 - html-tags: 3.3.1 - ignore: 5.3.1 - import-lazy: 4.0.0 - imurmurhash: 0.1.4 - is-plain-object: 5.0.0 - known-css-properties: 0.29.0 - mathml-tag-names: 2.1.3 - meow: 10.1.5 - micromatch: 4.0.5 - normalize-path: 3.0.0 - picocolors: 1.0.0 - postcss: 8.4.38 - postcss-resolve-nested-selector: 0.1.1 - postcss-safe-parser: 6.0.0(postcss@8.4.38) - postcss-selector-parser: 6.0.16 - postcss-value-parser: 4.2.0 - resolve-from: 5.0.0 - string-width: 4.2.3 - strip-ansi: 6.0.1 - style-search: 0.1.0 - supports-hyperlinks: 3.0.0 - svg-tags: 1.0.0 - table: 6.8.2 - write-file-atomic: 5.0.1 - transitivePeerDependencies: - - supports-color - - typescript - dev: true - /superagent@8.1.2: resolution: {integrity: sha512-6WTxW1EB6yCxV5VFOIPQruWGHqc3yI7hEmZK6h+pyk69Lk/Ut7rLUY6W/ONF2MjBuGjvmMiIpsrVJ2vjrHlslA==} engines: {node: '>=6.4.0 <13 || >=14'} @@ -20910,14 +20416,6 @@ packages: supports-color: 7.2.0 dev: true - /supports-hyperlinks@3.0.0: - resolution: {integrity: sha512-QBDPHyPQDRTy9ku4URNGY5Lah8PAaXs6tAAwp55sL5WCsSW7GIfdf6W5ixfziW+t7wh3GVvHyHHyQ1ESsoRvaA==} - engines: {node: '>=14.18'} - dependencies: - has-flag: 4.0.0 - supports-color: 7.2.0 - dev: true - /supports-preserve-symlinks-flag@1.0.0: resolution: {integrity: sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==} engines: {node: '>= 0.4'} @@ -20976,17 +20474,6 @@ packages: strip-ansi: 6.0.1 dev: true - /table@6.8.2: - resolution: {integrity: sha512-w2sfv80nrAh2VCbqR5AK27wswXhqcck2AhfnNW76beQXskGZ1V12GwS//yYVa3d3fcvAip2OUnbDAjW2k3v9fA==} - engines: {node: '>=10.0.0'} - dependencies: - ajv: 8.12.0 - lodash.truncate: 4.4.2 - slice-ansi: 4.0.0 - string-width: 4.2.3 - strip-ansi: 6.0.1 - dev: true - /tapable@2.2.1: resolution: {integrity: sha512-GNzQvQTOIP6RyTfE2Qxb8ZVlNmw0n88vp1szwWRimP02mnTsx3Wtn5qRdqY9w2XduFNUgvOwhNnQsjwCp+kqaQ==} engines: {node: '>=6'} @@ -21186,11 +20673,6 @@ packages: engines: {node: '>=8'} dev: true - /trim-newlines@4.1.1: - resolution: {integrity: sha512-jRKj0n0jXWo6kh62nA5TEh3+4igKDXLvzBJcPpiizP7oOolUrYIxmVBG9TOtHYFHoddUk6YvAkGeGoSVTXfQXQ==} - engines: {node: '>=12'} - dev: true - /trim-trailing-lines@1.1.4: resolution: {integrity: sha512-rjUWSqnfTNrjbB9NQWfPMH/xRK1deHeGsHoVfpxJ++XeYXE0d6B1En37AHfw3jtfTU7dzMzZL2jjpe8Qb5gLIQ==} dev: true @@ -22112,14 +21594,6 @@ packages: signal-exit: 3.0.7 dev: true - /write-file-atomic@5.0.1: - resolution: {integrity: sha512-+QU2zd6OTD8XWIJCbffaiQeH9U73qIqafo1x6V1snCWYGJf6cVE0cDR4D8xRzcEnfI21IFrUPzPGtcPf8AC+Rw==} - engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} - dependencies: - imurmurhash: 0.1.4 - signal-exit: 4.1.0 - dev: true - /ws@8.16.0: resolution: {integrity: sha512-HS0c//TP7Ina87TfiPUz1rQzMhHrl/SG2guqRcTOIUYD2q8uhUdNHZYJUaQ8aTGPzCh+c6oawMKW35nFl1dxyQ==} engines: {node: '>=10.0.0'} From c6adedefb5eb4c9e432a7196e75c97c9505690cc Mon Sep 17 00:00:00 2001 From: Xiao Yijun Date: Thu, 18 Apr 2024 16:15:05 +0800 Subject: [PATCH 290/687] fix(console): always display create org button (#5746) --- packages/console/src/pages/Organizations/index.tsx | 2 +- .../src/tests/console/organizations.test.ts | 13 ++++++------- .../src/ui-helpers/expect-organizations.ts | 4 ++-- 3 files changed, 9 insertions(+), 10 deletions(-) diff --git a/packages/console/src/pages/Organizations/index.tsx b/packages/console/src/pages/Organizations/index.tsx index fe18342b0f9..8b9a002af0d 100644 --- a/packages/console/src/pages/Organizations/index.tsx +++ b/packages/console/src/pages/Organizations/index.tsx @@ -81,7 +81,7 @@ function Organizations({ tab }: Props) { targetBlank: 'noopener', }} /> - {!isInitialSetup && ( + {(!isInitialSetup || isDevFeaturesEnabled) && (

)} - + {[ ApplicationType.Traditional, @@ -145,7 +145,12 @@ function EndpointsAndCredentials({ app: { type, secret, id, isThirdParty }, oidc ApplicationType.Protected, ].includes(type) && ( - + )} diff --git a/packages/console/src/pages/EnterpriseSsoDetails/Connection/OidcMetadataForm/index.module.scss b/packages/console/src/pages/EnterpriseSsoDetails/Connection/OidcMetadataForm/index.module.scss index a87c37cafdc..36ac802355a 100644 --- a/packages/console/src/pages/EnterpriseSsoDetails/Connection/OidcMetadataForm/index.module.scss +++ b/packages/console/src/pages/EnterpriseSsoDetails/Connection/OidcMetadataForm/index.module.scss @@ -1,9 +1,5 @@ @use '@/scss/underscore' as _; -.copyToClipboard { - display: block; -} - .oidcConfigPreview { margin-top: _.unit(3); } diff --git a/packages/console/src/pages/EnterpriseSsoDetails/Connection/OidcMetadataForm/index.tsx b/packages/console/src/pages/EnterpriseSsoDetails/Connection/OidcMetadataForm/index.tsx index b679078a627..b8c52e4000d 100644 --- a/packages/console/src/pages/EnterpriseSsoDetails/Connection/OidcMetadataForm/index.tsx +++ b/packages/console/src/pages/EnterpriseSsoDetails/Connection/OidcMetadataForm/index.tsx @@ -57,7 +57,7 @@ function OidcMetadataForm({ providerConfig, config, providerName }: Props) { > {providerName === SsoProviderName.GOOGLE_WORKSPACE ? ( - + {/* Show default value of `id` field to show that Logto has handled the default value. */} {/* Per SAML protocol, this field is not eligible to change in most cases. */} {key === 'id' ? ( diff --git a/packages/console/src/pages/EnterpriseSsoDetails/Connection/SamlMetadataForm/ParsedConfigPreview/index.module.scss b/packages/console/src/pages/EnterpriseSsoDetails/Connection/SamlMetadataForm/ParsedConfigPreview/index.module.scss index 8ef084c538d..42ca608ca42 100644 --- a/packages/console/src/pages/EnterpriseSsoDetails/Connection/SamlMetadataForm/ParsedConfigPreview/index.module.scss +++ b/packages/console/src/pages/EnterpriseSsoDetails/Connection/SamlMetadataForm/ParsedConfigPreview/index.module.scss @@ -44,8 +44,4 @@ .errorStatus { background: var(--color-on-error-container); } - - .copyToClipboard { - margin-left: _.unit(1); - } } diff --git a/packages/console/src/pages/EnterpriseSsoDetails/Connection/SamlMetadataForm/ParsedConfigPreview/index.tsx b/packages/console/src/pages/EnterpriseSsoDetails/Connection/SamlMetadataForm/ParsedConfigPreview/index.tsx index e3be72a7559..9b0866c8bdf 100644 --- a/packages/console/src/pages/EnterpriseSsoDetails/Connection/SamlMetadataForm/ParsedConfigPreview/index.tsx +++ b/packages/console/src/pages/EnterpriseSsoDetails/Connection/SamlMetadataForm/ParsedConfigPreview/index.tsx @@ -46,7 +46,7 @@ export function CertificatePreview({ ), }} /> - +
); } diff --git a/packages/console/src/pages/EnterpriseSsoDetails/Connection/ServiceProviderInfo/OidcConnectorSpInfo.tsx b/packages/console/src/pages/EnterpriseSsoDetails/Connection/ServiceProviderInfo/OidcConnectorSpInfo.tsx index 03e3d0c8dde..198c9020557 100644 --- a/packages/console/src/pages/EnterpriseSsoDetails/Connection/ServiceProviderInfo/OidcConnectorSpInfo.tsx +++ b/packages/console/src/pages/EnterpriseSsoDetails/Connection/ServiceProviderInfo/OidcConnectorSpInfo.tsx @@ -5,8 +5,6 @@ import CopyToClipboard from '@/ds-components/CopyToClipboard'; import FormField from '@/ds-components/FormField'; import useCustomDomain from '@/hooks/use-custom-domain'; -import * as styles from './index.module.scss'; - type Props = { readonly ssoConnectorId: string; }; @@ -19,7 +17,7 @@ function OidcConnectorSpInfo({ ssoConnectorId }: Props) { {/* Generated and passed in by Admin console. */} diff --git a/packages/console/src/pages/EnterpriseSsoDetails/Connection/ServiceProviderInfo/SamlConnectorSpInfo.tsx b/packages/console/src/pages/EnterpriseSsoDetails/Connection/ServiceProviderInfo/SamlConnectorSpInfo.tsx index 3f61865a72a..51cb6e2bed0 100644 --- a/packages/console/src/pages/EnterpriseSsoDetails/Connection/ServiceProviderInfo/SamlConnectorSpInfo.tsx +++ b/packages/console/src/pages/EnterpriseSsoDetails/Connection/ServiceProviderInfo/SamlConnectorSpInfo.tsx @@ -6,8 +6,6 @@ import useCustomDomain from '@/hooks/use-custom-domain'; import { type SamlProviderConfig } from '../../types/saml'; -import * as styles from './index.module.scss'; - type Props = { readonly samlProviderConfig?: SamlProviderConfig; }; @@ -23,7 +21,7 @@ function SamlConnectorSpInfo({ samlProviderConfig }: Props) { <> - + element.textContent ); From 585ce7413d159548685ca2059a5c1d85e2458642 Mon Sep 17 00:00:00 2001 From: simeng-li Date: Mon, 22 Apr 2024 10:15:58 +0800 Subject: [PATCH 305/687] fix(console): fix the jwt creation page idle bug after submit form (#5761) * fix(console): fix the jwt creation page idle bug after submit form fix the jwt creation page idle bug after submit the form * chore(console): add some comments add some comments --- .../CustomizeJwtDetails/MainContent/index.tsx | 19 ++++++++----------- .../CustomizeJwtDetails/use-data-fetch.ts | 2 +- .../pages/CustomizeJwtDetails/utils/path.ts | 4 ---- 3 files changed, 9 insertions(+), 16 deletions(-) delete mode 100644 packages/console/src/pages/CustomizeJwtDetails/utils/path.ts diff --git a/packages/console/src/pages/CustomizeJwtDetails/MainContent/index.tsx b/packages/console/src/pages/CustomizeJwtDetails/MainContent/index.tsx index 26f181e02c5..3dead2a6ea7 100644 --- a/packages/console/src/pages/CustomizeJwtDetails/MainContent/index.tsx +++ b/packages/console/src/pages/CustomizeJwtDetails/MainContent/index.tsx @@ -2,17 +2,16 @@ import { type LogtoJwtTokenKeyType } from '@logto/schemas'; import classNames from 'classnames'; import { FormProvider, useForm } from 'react-hook-form'; import { useNavigate } from 'react-router-dom'; -import { type KeyedMutator } from 'swr'; +import { useSWRConfig, type KeyedMutator } from 'swr'; import SubmitFormChangesActionBar from '@/components/SubmitFormChangesActionBar'; import UnsavedChangesAlertModal from '@/components/UnsavedChangesAlertModal'; import useApi from '@/hooks/use-api'; +import { getApiPath } from '@/pages/CustomizeJwt/utils/path'; import { trySubmitSafe } from '@/utils/form'; -import useJwtCustomizer from '../../CustomizeJwt/use-jwt-customizer'; import { type Action, type JwtCustomizer, type JwtCustomizerForm } from '../type'; import { formatFormDataToRequestData, formatResponseDataToFormData } from '../utils/format'; -import { getApiPath } from '../utils/path'; import ScriptSection from './ScriptSection'; import SettingsSection from './SettingsSection'; @@ -35,7 +34,7 @@ function MainContent({ }: Props) { const api = useApi(); const navigate = useNavigate(); - const { mutate: mutateJwtCustomizers } = useJwtCustomizer(); + const { mutate: globalMutate } = useSWRConfig(); const methods = useForm({ defaultValues: formatResponseDataToFormData(token, data), @@ -62,16 +61,14 @@ function MainContent({ await mutate(updatedJwtCustomizer); + // Need to reset the form data ahead to avoid the unsaved changes alert reset(formatResponseDataToFormData(tokenType, updatedJwtCustomizer)); - /** - * Should `reset` (to set `isDirty` to false) before navigating back to the custom JWT listing page. - * Otherwise, the unsaved changes alert modal will be triggered on clicking `create` button, which - * is not expected. - */ + // If the form is in create mode, navigate back to the previous page if (action === 'create') { - // Refresh the JWT customizers list to reflect the latest changes. - await mutateJwtCustomizers(); + // Need to trigger a global mutate to update the cache + // Keep asynchrony to avoid page idling + void globalMutate(getApiPath()); navigate(-1); } }) diff --git a/packages/console/src/pages/CustomizeJwtDetails/use-data-fetch.ts b/packages/console/src/pages/CustomizeJwtDetails/use-data-fetch.ts index 29812dcac42..ba9e7de1414 100644 --- a/packages/console/src/pages/CustomizeJwtDetails/use-data-fetch.ts +++ b/packages/console/src/pages/CustomizeJwtDetails/use-data-fetch.ts @@ -4,10 +4,10 @@ import useSWR from 'swr'; import useApi from '@/hooks/use-api'; import useSwrFetcher from '@/hooks/use-swr-fetcher'; +import { getApiPath } from '@/pages/CustomizeJwt/utils/path'; import { shouldRetryOnError } from '@/utils/request'; import { type Action, type JwtCustomizer } from './type'; -import { getApiPath } from './utils/path'; const useDataFetch = (tokenType: T, action: Action) => { const apiPath = getApiPath(tokenType); diff --git a/packages/console/src/pages/CustomizeJwtDetails/utils/path.ts b/packages/console/src/pages/CustomizeJwtDetails/utils/path.ts deleted file mode 100644 index 25c94ed2bc7..00000000000 --- a/packages/console/src/pages/CustomizeJwtDetails/utils/path.ts +++ /dev/null @@ -1,4 +0,0 @@ -import { type LogtoJwtTokenKeyType } from '@logto/schemas'; - -export const getApiPath = (tokenType: LogtoJwtTokenKeyType) => - `api/configs/jwt-customizer/${tokenType}`; From fcfa2c7d2627c38efd159fe67bb296979eb950fd Mon Sep 17 00:00:00 2001 From: simeng-li Date: Mon, 22 Apr 2024 10:16:40 +0800 Subject: [PATCH 306/687] refactor(console): implement new jwt customizer delete modal (#5765) * refactor(console): clean up the global useConfirmModal provider clean up the global useConfirmModal provider * refactor(console): implement new jwt customizer delete modal implement new jwt customizer delete modal --- .../AppConfirmModalProvider/index.tsx | 23 ++------ .../CustomizeJwt/CustomizerItem/index.tsx | 32 ++-------- .../pages/CustomizeJwt/DeleteConfirmModal.tsx | 58 +++++++++++++++++++ .../console/src/pages/CustomizeJwt/index.tsx | 25 +++++++- 4 files changed, 93 insertions(+), 45 deletions(-) create mode 100644 packages/console/src/pages/CustomizeJwt/DeleteConfirmModal.tsx diff --git a/packages/console/src/contexts/AppConfirmModalProvider/index.tsx b/packages/console/src/contexts/AppConfirmModalProvider/index.tsx index 94ea8c16794..3fc7f5c8271 100644 --- a/packages/console/src/contexts/AppConfirmModalProvider/index.tsx +++ b/packages/console/src/contexts/AppConfirmModalProvider/index.tsx @@ -5,27 +5,22 @@ import { createContext, useCallback, useEffect, useMemo, useRef, useState } from import type { ConfirmModalProps } from '@/ds-components/ConfirmModal'; import ConfirmModal from '@/ds-components/ConfirmModal'; -type ModalContentRenderProps = { - confirm: (data?: unknown) => void; - cancel: (data?: unknown) => void; -}; - type ConfirmModalType = 'alert' | 'confirm'; type ConfirmModalState = Omit< ConfirmModalProps, 'onCancel' | 'onConfirm' | 'children' | 'isLoading' > & { - ModalContent: string | ((props: ModalContentRenderProps) => Nullable); + ModalContent: string | (() => Nullable); type: ConfirmModalType; }; -type AppConfirmModalProps = Omit & { +type ShowConfirmModalProps = Omit & { type?: ConfirmModalType; }; type ConfirmModalContextType = { - show: (props: AppConfirmModalProps) => Promise<[boolean, unknown?]>; + show: (props: ShowConfirmModalProps) => Promise<[boolean, unknown?]>; confirm: (data?: unknown) => void; cancel: (data?: unknown) => void; }; @@ -51,7 +46,7 @@ function AppConfirmModalProvider({ children }: Props) { const resolver = useRef<(value: [result: boolean, data?: unknown]) => void>(); - const handleShow = useCallback(async ({ type = 'confirm', ...props }: AppConfirmModalProps) => { + const handleShow = useCallback(async ({ type = 'confirm', ...props }: ShowConfirmModalProps) => { resolver.current?.([false]); setModalState({ @@ -109,15 +104,9 @@ function AppConfirmModalProvider({ children }: Props) { { - handleCancel(); - }} + onCancel={handleCancel} > - {typeof ModalContent === 'string' ? ( - ModalContent - ) : ( - - )} + {typeof ModalContent === 'string' ? ModalContent : } ); diff --git a/packages/console/src/pages/CustomizeJwt/CustomizerItem/index.tsx b/packages/console/src/pages/CustomizeJwt/CustomizerItem/index.tsx index dfb7522e114..05c19a8436b 100644 --- a/packages/console/src/pages/CustomizeJwt/CustomizerItem/index.tsx +++ b/packages/console/src/pages/CustomizeJwt/CustomizerItem/index.tsx @@ -1,45 +1,23 @@ import { LogtoJwtTokenKeyType } from '@logto/schemas'; -import { useCallback } from 'react'; import { useTranslation } from 'react-i18next'; import DeleteIcon from '@/assets/icons/delete.svg'; import EditIcon from '@/assets/icons/edit.svg'; import Button from '@/ds-components/Button'; -import useApi from '@/hooks/use-api'; -import { useConfirmModal } from '@/hooks/use-confirm-modal'; import useTenantPathname from '@/hooks/use-tenant-pathname'; -import { getApiPath, getPagePath } from '@/pages/CustomizeJwt/utils/path'; - -import useJwtCustomizer from '../use-jwt-customizer'; +import { getPagePath } from '@/pages/CustomizeJwt/utils/path'; import * as styles from './index.module.scss'; type Props = { readonly tokenType: LogtoJwtTokenKeyType; + readonly onDelete: (token: LogtoJwtTokenKeyType) => void; }; -function CustomizerItem({ tokenType }: Props) { +function CustomizerItem({ tokenType, onDelete }: Props) { const { t } = useTranslation(undefined, { keyPrefix: 'admin_console' }); - const apiLink = getApiPath(tokenType); const editLink = getPagePath(tokenType, 'edit'); const { navigate } = useTenantPathname(); - const { show } = useConfirmModal(); - const { mutate } = useJwtCustomizer(); - - const api = useApi(); - - const onDelete = useCallback(async () => { - const [confirm] = await show({ - title: 'jwt_claims.delete_modal_title', - ModalContent: t('jwt_claims.delete_modal_content'), - confirmButtonText: 'general.delete', - }); - - if (confirm) { - await api.delete(apiLink); - await mutate(); - } - }, [api, apiLink, mutate, show, t]); return (
@@ -67,7 +45,9 @@ function CustomizerItem({ tokenType }: Props) { type="text" size="small" title="general.delete" - onClick={onDelete} + onClick={() => { + onDelete(tokenType); + }} />
diff --git a/packages/console/src/pages/CustomizeJwt/DeleteConfirmModal.tsx b/packages/console/src/pages/CustomizeJwt/DeleteConfirmModal.tsx new file mode 100644 index 00000000000..4910c8f54ec --- /dev/null +++ b/packages/console/src/pages/CustomizeJwt/DeleteConfirmModal.tsx @@ -0,0 +1,58 @@ +import { type LogtoJwtTokenKeyType } from '@logto/schemas'; +import { useCallback, useState } from 'react'; +import { useTranslation } from 'react-i18next'; +import { useSWRConfig } from 'swr'; + +import ConfirmModal from '@/ds-components/ConfirmModal'; +import useApi from '@/hooks/use-api'; +import { getApiPath } from '@/pages/CustomizeJwt/utils/path'; + +type Props = { + readonly isOpen: boolean; + readonly tokenType?: LogtoJwtTokenKeyType; + readonly onCancel: () => void; +}; + +function DeleteConfirmModal({ isOpen, tokenType, onCancel }: Props) { + const { t } = useTranslation(undefined, { keyPrefix: 'admin_console' }); + const [loading, setLoading] = useState(false); + const { mutate } = useSWRConfig(); + + const api = useApi(); + const apiLink = tokenType && getApiPath(tokenType); + + const onDelete = useCallback(async () => { + // If no token type is provided, dismiss the modal + if (!apiLink) { + onCancel(); + return; + } + + setLoading(true); + + try { + // Delete the JWT customizer + await api.delete(apiLink); + // Mutate the SWR cache + await mutate(getApiPath()); + } finally { + setLoading(false); + onCancel(); + } + }, [api, apiLink, mutate, onCancel]); + + return ( + + {t('jwt_claims.delete_modal_content')} + + ); +} + +export default DeleteConfirmModal; diff --git a/packages/console/src/pages/CustomizeJwt/index.tsx b/packages/console/src/pages/CustomizeJwt/index.tsx index 3377fc8427a..39152786824 100644 --- a/packages/console/src/pages/CustomizeJwt/index.tsx +++ b/packages/console/src/pages/CustomizeJwt/index.tsx @@ -1,4 +1,5 @@ import { LogtoJwtTokenKeyType } from '@logto/schemas'; +import { useCallback, useState } from 'react'; import { useTranslation } from 'react-i18next'; import FormCard, { FormCardSkeleton } from '@/components/FormCard'; @@ -7,12 +8,19 @@ import FormField from '@/ds-components/FormField'; import CreateButton from './CreateButton'; import CustomizerItem from './CustomizerItem'; +import DeleteConfirmModal from './DeleteConfirmModal'; import * as styles from './index.module.scss'; import useJwtCustomizer from './use-jwt-customizer'; function CustomizeJwt() { const { t } = useTranslation(undefined, { keyPrefix: 'admin_console' }); + const [deleteModalTokenType, setDeleteModalTokenType] = useState(); + + const onDeleteHandler = useCallback((tokenType: LogtoJwtTokenKeyType) => { + setDeleteModalTokenType(tokenType); + }, []); + const { isLoading, accessTokenJwtCustomizer, clientCredentialsJwtCustomizer } = useJwtCustomizer(); @@ -38,7 +46,10 @@ function CustomizeJwt() { {t('jwt_claims.user_jwt.card_description')} {accessTokenJwtCustomizer ? ( - + ) : ( )} @@ -50,7 +61,10 @@ function CustomizeJwt() { {t('jwt_claims.machine_to_machine_jwt.card_description')} {clientCredentialsJwtCustomizer ? ( - + ) : ( )} @@ -59,6 +73,13 @@ function CustomizeJwt() { )} + { + setDeleteModalTokenType(undefined); + }} + /> ); } From 711c51c0fd1c4b1a2d77b3fe03ea69a5efb23865 Mon Sep 17 00:00:00 2001 From: Charles Zhao Date: Mon, 22 Apr 2024 11:10:33 +0800 Subject: [PATCH 307/687] refactor(console): update organization guide and tenant member routers (#5766) --- .../src/hooks/use-console-routes/index.tsx | 19 +++++++++++++++++-- .../routes/tenant-settings.tsx | 17 ++++++++++++++--- .../src/pages/Organizations/Guide/index.tsx | 17 ++--------------- .../TenantSettings/TenantMembers/index.tsx | 19 +++---------------- 4 files changed, 36 insertions(+), 36 deletions(-) diff --git a/packages/console/src/hooks/use-console-routes/index.tsx b/packages/console/src/hooks/use-console-routes/index.tsx index 61d5db43eb1..47ee00f0440 100644 --- a/packages/console/src/hooks/use-console-routes/index.tsx +++ b/packages/console/src/hooks/use-console-routes/index.tsx @@ -1,6 +1,6 @@ import { condArray } from '@silverhand/essentials'; import { useMemo } from 'react'; -import { type RouteObject } from 'react-router-dom'; +import { Navigate, type RouteObject } from 'react-router-dom'; import { isCloud, isDevFeaturesEnabled } from '@/consts/env'; import Dashboard from '@/pages/Dashboard'; @@ -8,6 +8,11 @@ import GetStarted from '@/pages/GetStarted'; import Mfa from '@/pages/Mfa'; import NotFound from '@/pages/NotFound'; import OrganizationGuide from '@/pages/Organizations/Guide'; +import Introduction from '@/pages/Organizations/Guide/Introduction'; +import OrganizationInfo from '@/pages/Organizations/Guide/OrganizationInfo'; +import OrganizationPermissions from '@/pages/Organizations/Guide/OrganizationPermissions'; +import OrganizationRoles from '@/pages/Organizations/Guide/OrganizationRoles'; +import { steps } from '@/pages/Organizations/Guide/const'; import SigningKeys from '@/pages/SigningKeys'; import { apiResources } from './routes/api-resources'; @@ -46,7 +51,17 @@ export const useConsoleRoutes = () => { roles, isDevFeaturesEnabled && organizationTemplate, organizations, - !isDevFeaturesEnabled && { path: 'organization-guide/*', element: }, + !isDevFeaturesEnabled && { + path: 'organization-guide/*', + element: , + children: [ + { index: true, element: }, + { path: steps.introduction, element: }, + { path: steps.permissions, element: }, + { path: steps.roles, element: }, + { path: steps.organizationInfo, element: }, + ], + }, profile, { path: 'signing-keys', element: }, isCloud && tenantSettings, diff --git a/packages/console/src/hooks/use-console-routes/routes/tenant-settings.tsx b/packages/console/src/hooks/use-console-routes/routes/tenant-settings.tsx index eb08de78715..fd33b2384e8 100644 --- a/packages/console/src/hooks/use-console-routes/routes/tenant-settings.tsx +++ b/packages/console/src/hooks/use-console-routes/routes/tenant-settings.tsx @@ -5,17 +5,20 @@ import { Navigate, type RouteObject } from 'react-router-dom'; import { TenantSettingsTabs } from '@/consts'; import { TenantsContext } from '@/contexts/TenantsProvider'; import useCurrentTenantScopes from '@/hooks/use-current-tenant-scopes'; +import NotFound from '@/pages/NotFound'; import TenantSettings from '@/pages/TenantSettings'; import BillingHistory from '@/pages/TenantSettings/BillingHistory'; import Subscription from '@/pages/TenantSettings/Subscription'; import TenantBasicSettings from '@/pages/TenantSettings/TenantBasicSettings'; import TenantDomainSettings from '@/pages/TenantSettings/TenantDomainSettings'; import TenantMembers from '@/pages/TenantSettings/TenantMembers'; +import Invitations from '@/pages/TenantSettings/TenantMembers/Invitations'; +import Members from '@/pages/TenantSettings/TenantMembers/Members'; export const useTenantSettings = () => { const { isDevTenant } = useContext(TenantsContext); const { - access: { canManageTenant }, + access: { canInviteMember, canManageTenant }, } = useCurrentTenantScopes(); const tenantSettings: RouteObject = useMemo( @@ -33,7 +36,15 @@ export const useTenantSettings = () => { ), }, { path: TenantSettingsTabs.Settings, element: }, - { path: `${TenantSettingsTabs.Members}/*`, element: }, + { + path: `${TenantSettingsTabs.Members}/*`, + element: , + children: [ + { path: '*', element: }, + { index: true, element: }, + ...condArray(canInviteMember && [{ path: 'invitations', element: }]), + ], + }, { path: TenantSettingsTabs.Domains, element: }, !isDevTenant && canManageTenant && [ @@ -42,7 +53,7 @@ export const useTenantSettings = () => { ] ), }), - [canManageTenant, isDevTenant] + [canInviteMember, canManageTenant, isDevTenant] ); return tenantSettings; diff --git a/packages/console/src/pages/Organizations/Guide/index.tsx b/packages/console/src/pages/Organizations/Guide/index.tsx index e59e80ef171..618e9ec860d 100644 --- a/packages/console/src/pages/Organizations/Guide/index.tsx +++ b/packages/console/src/pages/Organizations/Guide/index.tsx @@ -1,18 +1,11 @@ import { useCallback } from 'react'; import Modal from 'react-modal'; -// FIXME: @charles -// eslint-disable-next-line no-restricted-imports -import { Navigate, Route, Routes } from 'react-router-dom'; +import { Outlet } from 'react-router-dom'; import DsModalHeader from '@/ds-components/ModalHeader'; import useTenantPathname from '@/hooks/use-tenant-pathname'; import * as modalStyles from '@/scss/modal.module.scss'; -import Introduction from './Introduction'; -import OrganizationInfo from './OrganizationInfo'; -import OrganizationPermissions from './OrganizationPermissions'; -import OrganizationRoles from './OrganizationRoles'; -import { steps } from './const'; import * as styles from './index.module.scss'; function Guide() { @@ -30,13 +23,7 @@ function Guide() { subtitle="organizations.guide.subtitle" onClose={onClose} /> - - } /> - } /> - } /> - } /> - } /> - + ); diff --git a/packages/console/src/pages/TenantSettings/TenantMembers/index.tsx b/packages/console/src/pages/TenantSettings/TenantMembers/index.tsx index 43dd2c4392e..fe6c694d063 100644 --- a/packages/console/src/pages/TenantSettings/TenantMembers/index.tsx +++ b/packages/console/src/pages/TenantSettings/TenantMembers/index.tsx @@ -1,8 +1,6 @@ import classNames from 'classnames'; import { useContext, useState } from 'react'; -// FIXME: @charles -// eslint-disable-next-line no-restricted-imports -import { Route, Routes } from 'react-router-dom'; +import { Outlet } from 'react-router-dom'; import useSWRMutation from 'swr/mutation'; import InvitationIcon from '@/assets/icons/invitation.svg'; @@ -16,16 +14,11 @@ import Button from '@/ds-components/Button'; import Spacer from '@/ds-components/Spacer'; import useCurrentTenantScopes from '@/hooks/use-current-tenant-scopes'; import useTenantPathname from '@/hooks/use-tenant-pathname'; -import NotFound from '@/pages/NotFound'; -import Invitations from './Invitations'; import InviteMemberModal from './InviteMemberModal'; -import Members from './Members'; import useTenantMembersUsage from './hooks'; import * as styles from './index.module.scss'; -const invitationsRoute = 'invitations'; - function TenantMembers() { const { hasTenantMembersSurpassedLimit } = useTenantMembersUsage(); const { navigate, match } = useTenantPathname(); @@ -34,9 +27,7 @@ function TenantMembers() { access: { canInviteMember }, } = useCurrentTenantScopes(); - const isInvitationTab = match( - `/tenant-settings/${TenantSettingsTabs.Members}/${invitationsRoute}` - ); + const isInvitationTab = match(`/tenant-settings/${TenantSettingsTabs.Members}/invitations`); const { currentTenantId } = useContext(TenantsContext); const cloudApi = useAuthedCloudApi(); @@ -84,11 +75,7 @@ function TenantMembers() { /> )} - - } /> - } /> - {canInviteMember && } />} - + {canInviteMember && ( Date: Mon, 22 Apr 2024 11:11:54 +0800 Subject: [PATCH 308/687] chore(phrases): improve phrases on accessing invitations not made for you (#5744) --- .../src/locales/de/translation/admin-console/invitation.ts | 2 +- .../src/locales/en/translation/admin-console/invitation.ts | 2 +- .../src/locales/es/translation/admin-console/invitation.ts | 2 +- .../src/locales/fr/translation/admin-console/invitation.ts | 2 +- .../src/locales/it/translation/admin-console/invitation.ts | 2 +- .../src/locales/ja/translation/admin-console/invitation.ts | 2 +- .../src/locales/ko/translation/admin-console/invitation.ts | 2 +- .../src/locales/pl-pl/translation/admin-console/invitation.ts | 2 +- .../src/locales/pt-br/translation/admin-console/invitation.ts | 2 +- .../src/locales/pt-pt/translation/admin-console/invitation.ts | 2 +- .../src/locales/ru/translation/admin-console/invitation.ts | 2 +- .../src/locales/tr-tr/translation/admin-console/invitation.ts | 2 +- .../src/locales/zh-cn/translation/admin-console/invitation.ts | 2 +- .../src/locales/zh-hk/translation/admin-console/invitation.ts | 2 +- .../src/locales/zh-tw/translation/admin-console/invitation.ts | 2 +- 15 files changed, 15 insertions(+), 15 deletions(-) diff --git a/packages/phrases/src/locales/de/translation/admin-console/invitation.ts b/packages/phrases/src/locales/de/translation/admin-console/invitation.ts index c158350e390..fd14201f2f4 100644 --- a/packages/phrases/src/locales/de/translation/admin-console/invitation.ts +++ b/packages/phrases/src/locales/de/translation/admin-console/invitation.ts @@ -10,7 +10,7 @@ const invitation = { email_not_match_title: 'You are currently signed in as\n{{email}}', /** UNTRANSLATED */ email_not_match_description: - 'You do not currently have access to this organization.\nPlease sign in with the correct account to accept the invitation and become a member of the organization.', + 'Please sign in with the correct account to accept the invitation and become a member of the organization.', /** UNTRANSLATED */ switch_account: 'Sign in to another account', /** UNTRANSLATED */ diff --git a/packages/phrases/src/locales/en/translation/admin-console/invitation.ts b/packages/phrases/src/locales/en/translation/admin-console/invitation.ts index 91eaa2d6e19..07814ba21e0 100644 --- a/packages/phrases/src/locales/en/translation/admin-console/invitation.ts +++ b/packages/phrases/src/locales/en/translation/admin-console/invitation.ts @@ -5,7 +5,7 @@ const invitation = { create_new_tenant: 'Create a new tenant', email_not_match_title: 'You are currently signed in as\n{{email}}', email_not_match_description: - 'You do not currently have access to this organization.\nPlease sign in with the correct account to accept the invitation and become a member of the organization.', + 'Please sign in with the correct account to accept the invitation and become a member of the organization.', switch_account: 'Sign in to another account', invalid_invitation_status: 'Invalid invitation. Please contact the administrator and try again.', invitation_not_found: 'Invitation not found. Please contact the administrator.', diff --git a/packages/phrases/src/locales/es/translation/admin-console/invitation.ts b/packages/phrases/src/locales/es/translation/admin-console/invitation.ts index c158350e390..fd14201f2f4 100644 --- a/packages/phrases/src/locales/es/translation/admin-console/invitation.ts +++ b/packages/phrases/src/locales/es/translation/admin-console/invitation.ts @@ -10,7 +10,7 @@ const invitation = { email_not_match_title: 'You are currently signed in as\n{{email}}', /** UNTRANSLATED */ email_not_match_description: - 'You do not currently have access to this organization.\nPlease sign in with the correct account to accept the invitation and become a member of the organization.', + 'Please sign in with the correct account to accept the invitation and become a member of the organization.', /** UNTRANSLATED */ switch_account: 'Sign in to another account', /** UNTRANSLATED */ diff --git a/packages/phrases/src/locales/fr/translation/admin-console/invitation.ts b/packages/phrases/src/locales/fr/translation/admin-console/invitation.ts index c158350e390..fd14201f2f4 100644 --- a/packages/phrases/src/locales/fr/translation/admin-console/invitation.ts +++ b/packages/phrases/src/locales/fr/translation/admin-console/invitation.ts @@ -10,7 +10,7 @@ const invitation = { email_not_match_title: 'You are currently signed in as\n{{email}}', /** UNTRANSLATED */ email_not_match_description: - 'You do not currently have access to this organization.\nPlease sign in with the correct account to accept the invitation and become a member of the organization.', + 'Please sign in with the correct account to accept the invitation and become a member of the organization.', /** UNTRANSLATED */ switch_account: 'Sign in to another account', /** UNTRANSLATED */ diff --git a/packages/phrases/src/locales/it/translation/admin-console/invitation.ts b/packages/phrases/src/locales/it/translation/admin-console/invitation.ts index c158350e390..fd14201f2f4 100644 --- a/packages/phrases/src/locales/it/translation/admin-console/invitation.ts +++ b/packages/phrases/src/locales/it/translation/admin-console/invitation.ts @@ -10,7 +10,7 @@ const invitation = { email_not_match_title: 'You are currently signed in as\n{{email}}', /** UNTRANSLATED */ email_not_match_description: - 'You do not currently have access to this organization.\nPlease sign in with the correct account to accept the invitation and become a member of the organization.', + 'Please sign in with the correct account to accept the invitation and become a member of the organization.', /** UNTRANSLATED */ switch_account: 'Sign in to another account', /** UNTRANSLATED */ diff --git a/packages/phrases/src/locales/ja/translation/admin-console/invitation.ts b/packages/phrases/src/locales/ja/translation/admin-console/invitation.ts index c158350e390..fd14201f2f4 100644 --- a/packages/phrases/src/locales/ja/translation/admin-console/invitation.ts +++ b/packages/phrases/src/locales/ja/translation/admin-console/invitation.ts @@ -10,7 +10,7 @@ const invitation = { email_not_match_title: 'You are currently signed in as\n{{email}}', /** UNTRANSLATED */ email_not_match_description: - 'You do not currently have access to this organization.\nPlease sign in with the correct account to accept the invitation and become a member of the organization.', + 'Please sign in with the correct account to accept the invitation and become a member of the organization.', /** UNTRANSLATED */ switch_account: 'Sign in to another account', /** UNTRANSLATED */ diff --git a/packages/phrases/src/locales/ko/translation/admin-console/invitation.ts b/packages/phrases/src/locales/ko/translation/admin-console/invitation.ts index c158350e390..fd14201f2f4 100644 --- a/packages/phrases/src/locales/ko/translation/admin-console/invitation.ts +++ b/packages/phrases/src/locales/ko/translation/admin-console/invitation.ts @@ -10,7 +10,7 @@ const invitation = { email_not_match_title: 'You are currently signed in as\n{{email}}', /** UNTRANSLATED */ email_not_match_description: - 'You do not currently have access to this organization.\nPlease sign in with the correct account to accept the invitation and become a member of the organization.', + 'Please sign in with the correct account to accept the invitation and become a member of the organization.', /** UNTRANSLATED */ switch_account: 'Sign in to another account', /** UNTRANSLATED */ diff --git a/packages/phrases/src/locales/pl-pl/translation/admin-console/invitation.ts b/packages/phrases/src/locales/pl-pl/translation/admin-console/invitation.ts index c158350e390..fd14201f2f4 100644 --- a/packages/phrases/src/locales/pl-pl/translation/admin-console/invitation.ts +++ b/packages/phrases/src/locales/pl-pl/translation/admin-console/invitation.ts @@ -10,7 +10,7 @@ const invitation = { email_not_match_title: 'You are currently signed in as\n{{email}}', /** UNTRANSLATED */ email_not_match_description: - 'You do not currently have access to this organization.\nPlease sign in with the correct account to accept the invitation and become a member of the organization.', + 'Please sign in with the correct account to accept the invitation and become a member of the organization.', /** UNTRANSLATED */ switch_account: 'Sign in to another account', /** UNTRANSLATED */ diff --git a/packages/phrases/src/locales/pt-br/translation/admin-console/invitation.ts b/packages/phrases/src/locales/pt-br/translation/admin-console/invitation.ts index c158350e390..fd14201f2f4 100644 --- a/packages/phrases/src/locales/pt-br/translation/admin-console/invitation.ts +++ b/packages/phrases/src/locales/pt-br/translation/admin-console/invitation.ts @@ -10,7 +10,7 @@ const invitation = { email_not_match_title: 'You are currently signed in as\n{{email}}', /** UNTRANSLATED */ email_not_match_description: - 'You do not currently have access to this organization.\nPlease sign in with the correct account to accept the invitation and become a member of the organization.', + 'Please sign in with the correct account to accept the invitation and become a member of the organization.', /** UNTRANSLATED */ switch_account: 'Sign in to another account', /** UNTRANSLATED */ diff --git a/packages/phrases/src/locales/pt-pt/translation/admin-console/invitation.ts b/packages/phrases/src/locales/pt-pt/translation/admin-console/invitation.ts index c158350e390..fd14201f2f4 100644 --- a/packages/phrases/src/locales/pt-pt/translation/admin-console/invitation.ts +++ b/packages/phrases/src/locales/pt-pt/translation/admin-console/invitation.ts @@ -10,7 +10,7 @@ const invitation = { email_not_match_title: 'You are currently signed in as\n{{email}}', /** UNTRANSLATED */ email_not_match_description: - 'You do not currently have access to this organization.\nPlease sign in with the correct account to accept the invitation and become a member of the organization.', + 'Please sign in with the correct account to accept the invitation and become a member of the organization.', /** UNTRANSLATED */ switch_account: 'Sign in to another account', /** UNTRANSLATED */ diff --git a/packages/phrases/src/locales/ru/translation/admin-console/invitation.ts b/packages/phrases/src/locales/ru/translation/admin-console/invitation.ts index c158350e390..fd14201f2f4 100644 --- a/packages/phrases/src/locales/ru/translation/admin-console/invitation.ts +++ b/packages/phrases/src/locales/ru/translation/admin-console/invitation.ts @@ -10,7 +10,7 @@ const invitation = { email_not_match_title: 'You are currently signed in as\n{{email}}', /** UNTRANSLATED */ email_not_match_description: - 'You do not currently have access to this organization.\nPlease sign in with the correct account to accept the invitation and become a member of the organization.', + 'Please sign in with the correct account to accept the invitation and become a member of the organization.', /** UNTRANSLATED */ switch_account: 'Sign in to another account', /** UNTRANSLATED */ diff --git a/packages/phrases/src/locales/tr-tr/translation/admin-console/invitation.ts b/packages/phrases/src/locales/tr-tr/translation/admin-console/invitation.ts index c158350e390..fd14201f2f4 100644 --- a/packages/phrases/src/locales/tr-tr/translation/admin-console/invitation.ts +++ b/packages/phrases/src/locales/tr-tr/translation/admin-console/invitation.ts @@ -10,7 +10,7 @@ const invitation = { email_not_match_title: 'You are currently signed in as\n{{email}}', /** UNTRANSLATED */ email_not_match_description: - 'You do not currently have access to this organization.\nPlease sign in with the correct account to accept the invitation and become a member of the organization.', + 'Please sign in with the correct account to accept the invitation and become a member of the organization.', /** UNTRANSLATED */ switch_account: 'Sign in to another account', /** UNTRANSLATED */ diff --git a/packages/phrases/src/locales/zh-cn/translation/admin-console/invitation.ts b/packages/phrases/src/locales/zh-cn/translation/admin-console/invitation.ts index c158350e390..fd14201f2f4 100644 --- a/packages/phrases/src/locales/zh-cn/translation/admin-console/invitation.ts +++ b/packages/phrases/src/locales/zh-cn/translation/admin-console/invitation.ts @@ -10,7 +10,7 @@ const invitation = { email_not_match_title: 'You are currently signed in as\n{{email}}', /** UNTRANSLATED */ email_not_match_description: - 'You do not currently have access to this organization.\nPlease sign in with the correct account to accept the invitation and become a member of the organization.', + 'Please sign in with the correct account to accept the invitation and become a member of the organization.', /** UNTRANSLATED */ switch_account: 'Sign in to another account', /** UNTRANSLATED */ diff --git a/packages/phrases/src/locales/zh-hk/translation/admin-console/invitation.ts b/packages/phrases/src/locales/zh-hk/translation/admin-console/invitation.ts index c158350e390..fd14201f2f4 100644 --- a/packages/phrases/src/locales/zh-hk/translation/admin-console/invitation.ts +++ b/packages/phrases/src/locales/zh-hk/translation/admin-console/invitation.ts @@ -10,7 +10,7 @@ const invitation = { email_not_match_title: 'You are currently signed in as\n{{email}}', /** UNTRANSLATED */ email_not_match_description: - 'You do not currently have access to this organization.\nPlease sign in with the correct account to accept the invitation and become a member of the organization.', + 'Please sign in with the correct account to accept the invitation and become a member of the organization.', /** UNTRANSLATED */ switch_account: 'Sign in to another account', /** UNTRANSLATED */ diff --git a/packages/phrases/src/locales/zh-tw/translation/admin-console/invitation.ts b/packages/phrases/src/locales/zh-tw/translation/admin-console/invitation.ts index c158350e390..fd14201f2f4 100644 --- a/packages/phrases/src/locales/zh-tw/translation/admin-console/invitation.ts +++ b/packages/phrases/src/locales/zh-tw/translation/admin-console/invitation.ts @@ -10,7 +10,7 @@ const invitation = { email_not_match_title: 'You are currently signed in as\n{{email}}', /** UNTRANSLATED */ email_not_match_description: - 'You do not currently have access to this organization.\nPlease sign in with the correct account to accept the invitation and become a member of the organization.', + 'Please sign in with the correct account to accept the invitation and become a member of the organization.', /** UNTRANSLATED */ switch_account: 'Sign in to another account', /** UNTRANSLATED */ From 9bece65d91cda153019816003635e7f7e8ef6cbd Mon Sep 17 00:00:00 2001 From: simeng-li Date: Mon, 22 Apr 2024 13:37:10 +0800 Subject: [PATCH 309/687] chore(experience): package update (#5769) react-device-deteck package update --- packages/experience/package.json | 2 +- pnpm-lock.yaml | 14 +++++++------- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/packages/experience/package.json b/packages/experience/package.json index b7cc156ef56..9aae62021e3 100644 --- a/packages/experience/package.json +++ b/packages/experience/package.json @@ -75,7 +75,7 @@ "postcss-modules": "^4.3.0", "prettier": "^3.0.0", "react": "^18.0.0", - "react-device-detect": "^2.2.2", + "react-device-detect": "^2.2.3", "react-dom": "^18.0.0", "react-helmet": "^6.1.0", "react-hook-form": "^7.34.0", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 005711b4de6..b8fd3bcfc17 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -3541,8 +3541,8 @@ importers: specifier: ^18.0.0 version: 18.2.0 react-device-detect: - specifier: ^2.2.2 - version: 2.2.2(react-dom@18.2.0)(react@18.2.0) + specifier: ^2.2.3 + version: 2.2.3(react-dom@18.2.0)(react@18.2.0) react-dom: specifier: ^18.0.0 version: 18.2.0(react@18.2.0) @@ -18657,15 +18657,15 @@ packages: tween-functions: 1.2.0 dev: true - /react-device-detect@2.2.2(react-dom@18.2.0)(react@18.2.0): - resolution: {integrity: sha512-zSN1gIAztUekp5qUT/ybHwQ9fmOqVT1psxpSlTn1pe0CO+fnJHKRLOWWac5nKxOxvOpD/w84hk1I+EydrJp7SA==} + /react-device-detect@2.2.3(react-dom@18.2.0)(react@18.2.0): + resolution: {integrity: sha512-buYY3qrCnQVlIFHrC5UcUoAj7iANs/+srdkwsnNjI7anr3Tt7UY6MqNxtMLlr0tMBied0O49UZVK8XKs3ZIiPw==} peerDependencies: react: '>= 0.14.0 || ^18.0.0' react-dom: '>= 0.14.0' dependencies: react: 18.2.0 react-dom: 18.2.0(react@18.2.0) - ua-parser-js: 1.0.2 + ua-parser-js: 1.0.37 dev: true /react-dnd-html5-backend@16.0.0: @@ -20861,8 +20861,8 @@ packages: engines: {node: '>=14.17'} hasBin: true - /ua-parser-js@1.0.2: - resolution: {integrity: sha512-00y/AXhx0/SsnI51fTc0rLRmafiGOM4/O+ny10Ps7f+j/b8p/ZY11ytMgznXkOVo4GQ+KwQG5UQLkLGirsACRg==} + /ua-parser-js@1.0.37: + resolution: {integrity: sha512-bhTyI94tZofjo+Dn8SN6Zv8nBDvyXTymAdM3LDI/0IboIUwTu1rEhW7v2TfiVsoYWgkQ4kOVqnI8APUFbIQIFQ==} dev: true /ufo@1.5.2: From 465c7a447a7bf14ae4cc2e73fc3d0dfbaa18be91 Mon Sep 17 00:00:00 2001 From: simeng-li Date: Tue, 23 Apr 2024 10:10:31 +0800 Subject: [PATCH 310/687] style(experience): fix the terms of use link style (#5771) fix the terms of use link style in confirm modal --- .../src/components/TermsLinks/index.module.scss | 1 - packages/experience/src/components/TermsLinks/index.tsx | 9 +++++---- .../index.module.scss | 0 .../index.tsx | 4 ++-- .../intext.test.tsx | 0 .../TermsAndPrivacyConfirmModalContent/index.tsx | 5 ++++- .../src/containers/TermsAndPrivacyLinks/index.tsx | 1 + packages/experience/src/hooks/use-terms.ts | 4 ++-- .../src/pages/Register/IdentifierRegisterForm/index.tsx | 6 +++--- packages/experience/src/pages/Register/index.tsx | 5 +++-- 10 files changed, 20 insertions(+), 15 deletions(-) rename packages/experience/src/containers/{TermsAndPrivacy => TermsAndPrivacyCheckbox}/index.module.scss (100%) rename packages/experience/src/containers/{TermsAndPrivacy => TermsAndPrivacyCheckbox}/index.tsx (93%) rename packages/experience/src/containers/{TermsAndPrivacy => TermsAndPrivacyCheckbox}/intext.test.tsx (100%) rename packages/experience/src/containers/{TermsAndPrivacy => }/TermsAndPrivacyConfirmModalContent/index.tsx (75%) diff --git a/packages/experience/src/components/TermsLinks/index.module.scss b/packages/experience/src/components/TermsLinks/index.module.scss index 08f065072b7..1d65dd23007 100644 --- a/packages/experience/src/components/TermsLinks/index.module.scss +++ b/packages/experience/src/components/TermsLinks/index.module.scss @@ -2,7 +2,6 @@ .link { - color: var(--color-type-primary); display: inline; } diff --git a/packages/experience/src/components/TermsLinks/index.tsx b/packages/experience/src/components/TermsLinks/index.tsx index 4e85decf72d..3922539dd70 100644 --- a/packages/experience/src/components/TermsLinks/index.tsx +++ b/packages/experience/src/components/TermsLinks/index.tsx @@ -1,17 +1,18 @@ import { useTranslation } from 'react-i18next'; -import TextLink from '@/components/TextLink'; +import TextLink, { type Props as TextLinkProps } from '@/components/TextLink'; import * as styles from './index.module.scss'; type Props = { + readonly linkType?: TextLinkProps['type']; // eslint-disable-next-line react/boolean-prop-naming readonly inline?: boolean; readonly termsOfUseUrl?: string; readonly privacyPolicyUrl?: string; }; -const TermsLinks = ({ inline, termsOfUseUrl, privacyPolicyUrl }: Props) => { +const TermsLinks = ({ inline, termsOfUseUrl, privacyPolicyUrl, linkType = 'secondary' }: Props) => { const { t } = useTranslation(); return ( @@ -21,7 +22,7 @@ const TermsLinks = ({ inline, termsOfUseUrl, privacyPolicyUrl }: Props) => { className={styles.link} text="description.terms_of_use" href={termsOfUseUrl} - type="secondary" + type={linkType} target="_blank" onClick={(event) => { event.stopPropagation(); @@ -35,7 +36,7 @@ const TermsLinks = ({ inline, termsOfUseUrl, privacyPolicyUrl }: Props) => { className={styles.link} text="description.privacy_policy" href={privacyPolicyUrl} - type="secondary" + type={linkType} target="_blank" onClick={(event) => { event.stopPropagation(); diff --git a/packages/experience/src/containers/TermsAndPrivacy/index.module.scss b/packages/experience/src/containers/TermsAndPrivacyCheckbox/index.module.scss similarity index 100% rename from packages/experience/src/containers/TermsAndPrivacy/index.module.scss rename to packages/experience/src/containers/TermsAndPrivacyCheckbox/index.module.scss diff --git a/packages/experience/src/containers/TermsAndPrivacy/index.tsx b/packages/experience/src/containers/TermsAndPrivacyCheckbox/index.tsx similarity index 93% rename from packages/experience/src/containers/TermsAndPrivacy/index.tsx rename to packages/experience/src/containers/TermsAndPrivacyCheckbox/index.tsx index 64b86fd0ff6..424f2078a89 100644 --- a/packages/experience/src/containers/TermsAndPrivacy/index.tsx +++ b/packages/experience/src/containers/TermsAndPrivacyCheckbox/index.tsx @@ -13,7 +13,7 @@ type Props = { readonly className?: string; }; -const TermsAndPrivacy = ({ className }: Props) => { +const TermsAndPrivacyCheckbox = ({ className }: Props) => { const { termsAgreement, setTermsAgreement, termsOfUseUrl, privacyPolicyUrl, isTermsDisabled } = useTerms(); const { t } = useTranslation(); @@ -57,4 +57,4 @@ const TermsAndPrivacy = ({ className }: Props) => { ); }; -export default TermsAndPrivacy; +export default TermsAndPrivacyCheckbox; diff --git a/packages/experience/src/containers/TermsAndPrivacy/intext.test.tsx b/packages/experience/src/containers/TermsAndPrivacyCheckbox/intext.test.tsx similarity index 100% rename from packages/experience/src/containers/TermsAndPrivacy/intext.test.tsx rename to packages/experience/src/containers/TermsAndPrivacyCheckbox/intext.test.tsx diff --git a/packages/experience/src/containers/TermsAndPrivacy/TermsAndPrivacyConfirmModalContent/index.tsx b/packages/experience/src/containers/TermsAndPrivacyConfirmModalContent/index.tsx similarity index 75% rename from packages/experience/src/containers/TermsAndPrivacy/TermsAndPrivacyConfirmModalContent/index.tsx rename to packages/experience/src/containers/TermsAndPrivacyConfirmModalContent/index.tsx index 387b8db3d31..fda8601e92b 100644 --- a/packages/experience/src/containers/TermsAndPrivacy/TermsAndPrivacyConfirmModalContent/index.tsx +++ b/packages/experience/src/containers/TermsAndPrivacyConfirmModalContent/index.tsx @@ -1,10 +1,12 @@ import { conditional } from '@silverhand/essentials'; import { useContext } from 'react'; -import { useTranslation, Trans } from 'react-i18next'; +import { Trans, useTranslation } from 'react-i18next'; import PageContext from '@/Providers/PageContextProvider/PageContext'; import TermsLinks from '@/components/TermsLinks'; +// Used by useTerms hook to display the terms and privacy policy confirmation modal +// This component should be used as the ModalContent prop in the useConfirmModal hook const TermsAndPrivacyConfirmModalContent = () => { const { experienceSettings } = useContext(PageContext); const { termsOfUseUrl, privacyPolicyUrl } = experienceSettings ?? {}; @@ -17,6 +19,7 @@ const TermsAndPrivacyConfirmModalContent = () => { link: ( diff --git a/packages/experience/src/containers/TermsAndPrivacyLinks/index.tsx b/packages/experience/src/containers/TermsAndPrivacyLinks/index.tsx index c2223da478b..dfe093e9e3e 100644 --- a/packages/experience/src/containers/TermsAndPrivacyLinks/index.tsx +++ b/packages/experience/src/containers/TermsAndPrivacyLinks/index.tsx @@ -5,6 +5,7 @@ type Props = { readonly className?: string; }; +// For sign-in page displaying terms and privacy links use only. No user interaction is needed. const TermsAndPrivacyLinks = ({ className }: Props) => { const { termsOfUseUrl, privacyPolicyUrl, isTermsDisabled } = useTerms(); diff --git a/packages/experience/src/hooks/use-terms.ts b/packages/experience/src/hooks/use-terms.ts index f250a945c99..ca873a6002e 100644 --- a/packages/experience/src/hooks/use-terms.ts +++ b/packages/experience/src/hooks/use-terms.ts @@ -1,8 +1,8 @@ import { conditional } from '@silverhand/essentials'; -import { useContext, useCallback, useMemo } from 'react'; +import { useCallback, useContext, useMemo } from 'react'; import PageContext from '@/Providers/PageContextProvider/PageContext'; -import TermsAndPrivacyConfirmModalContent from '@/containers/TermsAndPrivacy/TermsAndPrivacyConfirmModalContent'; +import TermsAndPrivacyConfirmModalContent from '@/containers/TermsAndPrivacyConfirmModalContent'; import { useConfirmModal } from './use-confirm-modal'; diff --git a/packages/experience/src/pages/Register/IdentifierRegisterForm/index.tsx b/packages/experience/src/pages/Register/IdentifierRegisterForm/index.tsx index dd7fe6ac8bc..96bfb20e468 100644 --- a/packages/experience/src/pages/Register/IdentifierRegisterForm/index.tsx +++ b/packages/experience/src/pages/Register/IdentifierRegisterForm/index.tsx @@ -1,7 +1,7 @@ import type { SignInIdentifier } from '@logto/schemas'; import classNames from 'classnames'; import { useCallback, useEffect } from 'react'; -import { useForm, Controller } from 'react-hook-form'; +import { Controller, useForm } from 'react-hook-form'; import { useTranslation } from 'react-i18next'; import LockIcon from '@/assets/icons/lock.svg'; @@ -9,7 +9,7 @@ import Button from '@/components/Button'; import ErrorMessage from '@/components/ErrorMessage'; import { SmartInputField } from '@/components/InputFields'; import type { IdentifierInputValue } from '@/components/InputFields/SmartInputField'; -import TermsAndPrivacy from '@/containers/TermsAndPrivacy'; +import TermsAndPrivacyCheckbox from '@/containers/TermsAndPrivacyCheckbox'; import useSingleSignOnWatch from '@/hooks/use-single-sign-on-watch'; import useTerms from '@/hooks/use-terms'; import { getGeneralIdentifierErrorMessage, validateIdentifierField } from '@/utils/form'; @@ -130,7 +130,7 @@ const IdentifierRegisterForm = ({ className, autoFocus, signUpMethods }: Props) * Form rerender will trigger autofill. * If the autofill value is SSO enabled, it will always show SSO form. */} - diff --git a/packages/experience/src/pages/Register/index.tsx b/packages/experience/src/pages/Register/index.tsx index 0a9302bc488..99f3ae8902a 100644 --- a/packages/experience/src/pages/Register/index.tsx +++ b/packages/experience/src/pages/Register/index.tsx @@ -9,7 +9,7 @@ import SingleSignOnFormModeContext from '@/Providers/SingleSignOnFormModeContext import Divider from '@/components/Divider'; import TextLink from '@/components/TextLink'; import SocialSignInList from '@/containers/SocialSignInList'; -import TermsAndPrivacy from '@/containers/TermsAndPrivacy'; +import TermsAndPrivacyCheckbox from '@/containers/TermsAndPrivacyCheckbox'; import { useSieMethods } from '@/hooks/use-sie'; import ErrorPage from '../ErrorPage'; @@ -79,9 +79,10 @@ const Register = () => { {signUpMethods.length > 0 && ( )} + {/* Social sign-in methods only */} {signUpMethods.length === 0 && socialConnectors.length > 0 && ( <> - + )} From 30aec5dd5f1385fea673152b3235cef6ae963020 Mon Sep 17 00:00:00 2001 From: Charles Zhao Date: Tue, 23 Apr 2024 10:14:37 +0800 Subject: [PATCH 311/687] chore(core): fix typo in code comments (#5772) --- packages/core/src/oidc/init.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/core/src/oidc/init.ts b/packages/core/src/oidc/init.ts index ea9b39822f5..4d9ff4d7c65 100644 --- a/packages/core/src/oidc/init.ts +++ b/packages/core/src/oidc/init.ts @@ -144,7 +144,7 @@ export default function initOidc( const { client, params } = ctx.oidc; /** - * In consent or code excange flow, the organization_id is undefined, + * In consent or code exchange flow, the organization_id is undefined, * and all the scopes inherited from the all organization roles will be granted. * In the flow of granting token for organization with api resource, * this value is set to the organization id, From 9cf03c8edb94b8116eac254019a543d3918ae426 Mon Sep 17 00:00:00 2001 From: simeng-li Date: Tue, 23 Apr 2024 10:37:54 +0800 Subject: [PATCH 312/687] feat(console): add spring boot integration guide (#5740) * feat(console): add spring boot integration guide add spring boot integration guide * chore: add changeset add changeset * chore: fix changeset typo * fix(console): update the spring boot guide description update the spring boot guide description * chore(console): remove extra empty space remove extra empty space --- .changeset/soft-stingrays-beam.md | 5 + .../console/src/assets/docs/guides/index.ts | 8 + .../guides/web-java-spring-boot/README.mdx | 330 ++++++++++++++++++ .../config.json | 0 .../docs/guides/web-java-spring-boot/index.ts | 16 + .../docs/guides/web-java-spring-boot/logo.svg | 1 + .../src/assets/docs/guides/web-java/index.ts | 12 - .../src/assets/docs/guides/web-java/logo.svg | 11 - 8 files changed, 360 insertions(+), 23 deletions(-) create mode 100644 .changeset/soft-stingrays-beam.md create mode 100644 packages/console/src/assets/docs/guides/web-java-spring-boot/README.mdx rename packages/console/src/assets/docs/guides/{web-java => web-java-spring-boot}/config.json (100%) create mode 100644 packages/console/src/assets/docs/guides/web-java-spring-boot/index.ts create mode 100644 packages/console/src/assets/docs/guides/web-java-spring-boot/logo.svg delete mode 100644 packages/console/src/assets/docs/guides/web-java/index.ts delete mode 100644 packages/console/src/assets/docs/guides/web-java/logo.svg diff --git a/.changeset/soft-stingrays-beam.md b/.changeset/soft-stingrays-beam.md new file mode 100644 index 00000000000..8afcdf71d42 --- /dev/null +++ b/.changeset/soft-stingrays-beam.md @@ -0,0 +1,5 @@ +--- +"@logto/console": patch +--- + +Add Java Spring Boot web integration guide to the application creation page diff --git a/packages/console/src/assets/docs/guides/index.ts b/packages/console/src/assets/docs/guides/index.ts index fd12ff800c5..39b9e0e765f 100644 --- a/packages/console/src/assets/docs/guides/index.ts +++ b/packages/console/src/assets/docs/guides/index.ts @@ -24,6 +24,7 @@ import webDotnetCoreMvc from './web-dotnet-core-mvc/index'; import webExpress from './web-express/index'; import webGo from './web-go/index'; import webGptPlugin from './web-gpt-plugin/index'; +import webJavaSpringBoot from './web-java-spring-boot/index'; import webNext from './web-next/index'; import webNextAppRouter from './web-next-app-router/index'; import webNextServerActions from './web-next-server-actions/index'; @@ -105,6 +106,13 @@ const guides: Readonly = Object.freeze([ Component: lazy(async () => import('./web-go/README.mdx')), metadata: webGo, }, + { + order: 1.4, + id: 'web-java-spring-boot', + Logo: lazy(async () => import('./web-java-spring-boot/logo.svg')), + Component: lazy(async () => import('./web-java-spring-boot/README.mdx')), + metadata: webJavaSpringBoot, + }, { order: 1.5, id: 'web-gpt-plugin', diff --git a/packages/console/src/assets/docs/guides/web-java-spring-boot/README.mdx b/packages/console/src/assets/docs/guides/web-java-spring-boot/README.mdx new file mode 100644 index 00000000000..7019654e233 --- /dev/null +++ b/packages/console/src/assets/docs/guides/web-java-spring-boot/README.mdx @@ -0,0 +1,330 @@ +import UriInputField from '@/mdx-components/UriInputField'; +import Steps from '@/mdx-components/Steps'; +import Step from '@/mdx-components/Step'; + + + + + This tutorial will show you how to integrate Logto into your Java Spring Boot web application. + +
    +
  • + The sample was created using the Spring Boot [securing web + starter](https://spring.io/guides/gs/securing-web). Following the instructions to bootstrap a + new web application. +
  • +
  • + The sample uses the [Spring Security + OAuth2](https://spring.io/guides/tutorials/spring-boot-oauth2) library to handle OIDC + authentication and integrate with Logto. +
  • +
+ +Before we begin, make sure you have went through the spring boot guides linked above. + +
+ + + Include the following dependencies in your `build.gradle` file: + +```gradle +dependencies { + implementation 'org.springframework.boot:spring-boot-starter-thymeleaf' + implementation 'org.springframework.boot:spring-boot-starter-web' + implementation 'org.springframework.boot:spring-boot-starter-security' + implementation 'org.springframework.boot:spring-boot-starter-oauth2-client' +} +``` + +The sample uses [gradle](https://spring.io/guides/gs/gradle) as the build tool. You can use +maven or any other build tool as well. The configurations might be slightly different. + +For maven, include the following dependencies in your `pom.xml` file: + +```maven + + org.springframework.boot + spring-boot-starter-thymeleaf + + + org.springframework.boot + spring-boot-starter-web + + + org.springframework.boot + spring-boot-starter-security + + + org.springframework.boot + spring-boot-starter-oauth2-client + +``` + + + + + +Register your application with Logto to get the client credentials and IdP configurations. +Add the following configuration to your `application.properties` file: + +
+  
+    {`spring.security.oauth2.client.registration.logto.client-name=logto
+spring.security.oauth2.client.registration.logto.client-id=${props.app.id}
+spring.security.oauth2.client.registration.logto.client-secret=${props.app.secret}
+spring.security.oauth2.client.registration.logto.redirect-uri={baseUrl}/login/oauth2/code/{registrationId}
+spring.security.oauth2.client.registration.logto.authorization-grant-type=authorization_code
+spring.security.oauth2.client.registration.logto.scope=openid,profile,email,offline_access
+spring.security.oauth2.client.registration.logto.provider=logto
+
+spring.security.oauth2.client.provider.logto.issuer-uri=${props.endpoint}oidc
+spring.security.oauth2.client.provider.logto.authorization-uri=${props.endpoint}oidc/auth
+spring.security.oauth2.client.provider.logto.jwk-set-uri=${props.endpoint}oidc/jwks
+  `}
+  
+
+ +
+ + + +In order to redirect users back to your application after they sign in, you need to set the redirect URI using the `client.registration.logto.redirect-uri` property in the previous step. + + + +e.g. In our example, the redirect URI is `http://localhost:8080/login/oauth2/code/logto`. + + + + + +#### Create a new class `WebSecurityConfig` in your project: + +```java +package com.example.securingweb; + +import org.springframework.context.annotation.Configuration; +import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; + +@Configuration +@EnableWebSecurity + +public class WebSecurityConfig { + // ... +} +``` + +#### Create a idTokenDecoderFactory bean to set the JWS algorithm to `ES384`: + +This is required because Logto uses ES384 as the default algorithm, we need to update the OidcIdTokenDecoderFactory to use the same algorithm. + +```java +import org.springframework.context.annotation.Bean; +import org.springframework.security.oauth2.client.oidc.authentication.OidcIdTokenDecoderFactory; +import org.springframework.security.oauth2.client.registration.ClientRegistration; +import org.springframework.security.oauth2.jose.jws.SignatureAlgorithm; +import org.springframework.security.oauth2.jwt.JwtDecoderFactory; + +public class WebSecurityConfig { + // ... + + @Bean + public JwtDecoderFactory idTokenDecoderFactory() { + OidcIdTokenDecoderFactory idTokenDecoderFactory = new OidcIdTokenDecoderFactory(); + idTokenDecoderFactory.setJwsAlgorithmResolver(clientRegistration -> SignatureAlgorithm.ES384); + return idTokenDecoderFactory; + } +} +``` + +#### Create a LoginSuccessHandler class to handle the login success event: + +Redirect the user to the user page after successful login: + +```java +package com.example.securingweb; + +import java.io.IOException; + +import org.springframework.security.core.Authentication; +import org.springframework.security.web.authentication.AuthenticationSuccessHandler; + +import jakarta.servlet.ServletException; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; + +public class CustomSuccessHandler implements AuthenticationSuccessHandler { + @Override + public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response, + Authentication authentication) throws IOException, ServletException { + response.sendRedirect("/user"); + } +} +``` + +#### Create a LogoutSuccessHandler class to handle the logout success event: + +Clear the session and redirect the user to the home page. + +```java +package com.example.securingweb; + +import java.io.IOException; + +import org.springframework.security.core.Authentication; +import org.springframework.security.web.authentication.logout.LogoutSuccessHandler; + +import jakarta.servlet.ServletException; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; +import jakarta.servlet.http.HttpSession; + +public class CustomLogoutHandler implements LogoutSuccessHandler { + @Override + public void onLogoutSuccess(HttpServletRequest request, HttpServletResponse response, Authentication authentication) + throws IOException, ServletException { + HttpSession session = request.getSession(); + + if (session != null) { + session.invalidate(); + } + + response.sendRedirect("/home"); + } +} +``` + +#### Create a `securityFilterChain` bean to configure the security configuration: + +Add the following code to complete the `WebSecurityConfig` class: + +```java +import org.springframework.context.annotation.Bean; +import org.springframework.security.config.annotation.web.builders.HttpSecurity; +import org.springframework.security.web.DefaultSecurityFilterChain; + +public class WebSecurityConfig { + // ... + + @Bean + public DefaultSecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception { + http + .authorizeRequests(authorizeRequests -> + authorizeRequests + .antMatchers("/", "/home").permitAll() // Allow access to the home page + .anyRequest().authenticated() // All other requests require authentication + ) + .oauth2Login(oauth2Login -> + oauth2Login + .successHandler(new CustomSuccessHandler()) + ) + .logout(logout -> + logout + .logoutSuccessHandler(new CustomLogoutHandler()) + ); + return http.build(); + } +} +``` + + + + + +(You may skip this step if you already have a home page in your project) + +HomeController.java: + +```java +package com.example.securingweb; + +import java.security.Principal; + +import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.GetMapping; + +@Controller +public class HomeController { + @GetMapping({ "/", "/home" }) + public String home(Principal principal) { + return principal != null ? "redirect:/user" : "home"; + } +} +``` + +This controller will redirect the user to the user page if the user is authenticated, otherwise, it will show the home page. + +home.html: + +```html + +

Welcome!

+ +

Login with Logto

+ +``` + +
+ + + +Create a new controller to handle the user page: + +```java +package com.example.securingweb; + +import java.security.Principal; +import java.util.Map; + +import org.springframework.security.oauth2.client.authentication.OAuth2AuthenticationToken; +import org.springframework.security.oauth2.core.user.OAuth2User; +import org.springframework.stereotype.Controller; +import org.springframework.ui.Model; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestMapping; + +@Controller +@RequestMapping("/user") +public class UserController { + + @GetMapping + public String user(Model model, Principal principal) { + if (principal instanceof OAuth2AuthenticationToken) { + OAuth2AuthenticationToken token = (OAuth2AuthenticationToken) principal; + OAuth2User oauth2User = token.getPrincipal(); + Map attributes = oauth2User.getAttributes(); + + model.addAttribute("username", attributes.get("username")); + model.addAttribute("email", attributes.get("email")); + model.addAttribute("sub", attributes.get("sub")); + } + + return "user"; + } +} +``` + +Read the user information from the `OAuth2User` object and pass it to the `user.html` template. + +user.html: + +```html + +

User Details

+
+

+

name:
+
email:
+
id:
+

+
+ +
+ +
+ +``` + +
+ +
diff --git a/packages/console/src/assets/docs/guides/web-java/config.json b/packages/console/src/assets/docs/guides/web-java-spring-boot/config.json similarity index 100% rename from packages/console/src/assets/docs/guides/web-java/config.json rename to packages/console/src/assets/docs/guides/web-java-spring-boot/config.json diff --git a/packages/console/src/assets/docs/guides/web-java-spring-boot/index.ts b/packages/console/src/assets/docs/guides/web-java-spring-boot/index.ts new file mode 100644 index 00000000000..cf1e468a2cb --- /dev/null +++ b/packages/console/src/assets/docs/guides/web-java-spring-boot/index.ts @@ -0,0 +1,16 @@ +import { ApplicationType } from '@logto/schemas'; + +import { type GuideMetadata } from '../types'; + +const metadata: Readonly = Object.freeze({ + name: 'Java Spring Boot Web', + description: + 'Spring Boot is a web framework for Java that enables developers to build secure, fast, and scalable server applications with the Java programming language.', + target: ApplicationType.Traditional, + sample: { + repo: 'spring-boot-sample', + path: '', + }, +}); + +export default metadata; diff --git a/packages/console/src/assets/docs/guides/web-java-spring-boot/logo.svg b/packages/console/src/assets/docs/guides/web-java-spring-boot/logo.svg new file mode 100644 index 00000000000..d7256ddcf41 --- /dev/null +++ b/packages/console/src/assets/docs/guides/web-java-spring-boot/logo.svg @@ -0,0 +1 @@ + diff --git a/packages/console/src/assets/docs/guides/web-java/index.ts b/packages/console/src/assets/docs/guides/web-java/index.ts deleted file mode 100644 index 61b56a2be49..00000000000 --- a/packages/console/src/assets/docs/guides/web-java/index.ts +++ /dev/null @@ -1,12 +0,0 @@ -import { ApplicationType } from '@logto/schemas'; - -import { type GuideMetadata } from '../types'; - -const metadata: Readonly = Object.freeze({ - name: 'Java Web', - description: - 'Java Web is a web framework for Java that enables developers to build secure, fast, and scalable server applications with the Java programming language.', - target: ApplicationType.Traditional, -}); - -export default metadata; diff --git a/packages/console/src/assets/docs/guides/web-java/logo.svg b/packages/console/src/assets/docs/guides/web-java/logo.svg deleted file mode 100644 index cb4151622a5..00000000000 --- a/packages/console/src/assets/docs/guides/web-java/logo.svg +++ /dev/null @@ -1,11 +0,0 @@ - - - - - - - - - - - From b575f57ac33e8757ea9d33893f86dd15bdbcf24c Mon Sep 17 00:00:00 2001 From: Charles Zhao Date: Tue, 23 Apr 2024 15:11:39 +0800 Subject: [PATCH 313/687] feat(core): support comma separated resource param (#5773) --- .changeset/rare-lamps-worry.md | 9 ++++ .../src/middleware/koa-resource-param.test.ts | 45 +++++++++++++++++++ .../core/src/middleware/koa-resource-param.ts | 31 +++++++++++++ packages/core/src/oidc/init.ts | 7 +++ 4 files changed, 92 insertions(+) create mode 100644 .changeset/rare-lamps-worry.md create mode 100644 packages/core/src/middleware/koa-resource-param.test.ts create mode 100644 packages/core/src/middleware/koa-resource-param.ts diff --git a/.changeset/rare-lamps-worry.md b/.changeset/rare-lamps-worry.md new file mode 100644 index 00000000000..12d84219bb9 --- /dev/null +++ b/.changeset/rare-lamps-worry.md @@ -0,0 +1,9 @@ +--- +"@logto/core": patch +--- + +Support comma separated resource parameter + +Some third-party libraries or plugins do not support array of resources, and can only specify `resource` through `additionalParameters` config, e.g. `flutter-appauth`. However, only one resource can be specified at a time in this way. This PR enables comma separated resource parameter support in Logto core service, so that multiple resources can be specified via a single string. + +For example: Auth URL like `/oidc/auth?resource=https://example.com/api1,https://example.com/api2` will be interpreted and parsed to Logto core service as `/ordc/auth?resource=https://example.com/api1&resource=https://example.com/api2`. diff --git a/packages/core/src/middleware/koa-resource-param.test.ts b/packages/core/src/middleware/koa-resource-param.test.ts new file mode 100644 index 00000000000..235f8fa03ce --- /dev/null +++ b/packages/core/src/middleware/koa-resource-param.test.ts @@ -0,0 +1,45 @@ +import createMockContext from '#src/test-utils/jest-koa-mocks/create-mock-context.js'; + +const { jest } = import.meta; + +const { default: koaResourceParam } = await import('./koa-resource-param.js'); + +// eslint-disable-next-line @typescript-eslint/no-empty-function +const noop = async () => {}; + +const endpoint = 'https://logto.io/oidc/auth'; + +describe('koaResourceParam() middleware', () => { + it('should check and process comma separated resource params in the URL', async () => { + const ctx = createMockContext({ url: endpoint + '?resource=foo,bar' }); + const run = koaResourceParam(); + + await run(ctx, noop); + + expect(ctx.request.query).toEqual({ + resource: ['foo', 'bar'], + }); + }); + + it('should also work with both comma separated and single resource params', async () => { + const ctx = createMockContext({ url: endpoint + '?resource=foo,bar&resource=baz' }); + const run = koaResourceParam(); + + await run(ctx, noop); + + expect(ctx.request.query).toEqual({ + resource: ['foo', 'bar', 'baz'], + }); + }); + + it('should not affect the URL if no comma separated resource params are found', async () => { + const ctx = createMockContext({ url: endpoint + '?resource=foo&resource=bar' }); + const run = koaResourceParam(); + + await run(ctx, noop); + + expect(ctx.request.query).toEqual({ + resource: ['foo', 'bar'], + }); + }); +}); diff --git a/packages/core/src/middleware/koa-resource-param.ts b/packages/core/src/middleware/koa-resource-param.ts new file mode 100644 index 00000000000..8728407df7f --- /dev/null +++ b/packages/core/src/middleware/koa-resource-param.ts @@ -0,0 +1,31 @@ +import type { Nullable } from '@silverhand/essentials'; +import type { MiddlewareType } from 'koa'; + +/** + * Create a middleware function that checks if the request URL contains comma separated `resource` query parameter. + * If yes, split the values and reconstruct the URL with multiple `resource` query parameters. + * E.g. `?resource=foo,bar` => `?resource=foo&resource=bar` + */ +export default function koaResourceParam(): MiddlewareType< + StateT, + ContextT, + Nullable +> { + return async (ctx, next) => { + const { query } = ctx.request; + const { resource } = query; + + if (!resource) { + return next(); + } + + const resources = Array.isArray(resource) ? resource : [resource]; + const resourceParams = resources.flatMap((resource) => resource.split(',')); + + ctx.request.query = { + ...query, + resource: resourceParams, + }; + return next(); + }; +} diff --git a/packages/core/src/oidc/init.ts b/packages/core/src/oidc/init.ts index 4d9ff4d7c65..769985d1587 100644 --- a/packages/core/src/oidc/init.ts +++ b/packages/core/src/oidc/init.ts @@ -28,6 +28,7 @@ import { type CloudConnectionLibrary } from '#src/libraries/cloud-connection.js' import { type LogtoConfigLibrary } from '#src/libraries/logto-config.js'; import koaAuditLog from '#src/middleware/koa-audit-log.js'; import koaBodyEtag from '#src/middleware/koa-body-etag.js'; +import koaResourceParam from '#src/middleware/koa-resource-param.js'; import postgresAdapter from '#src/oidc/adapter.js'; import { buildLoginPromptUrl, @@ -377,6 +378,12 @@ export default function initOidc( throw error; } }); + /** + * Check if the request URL contains comma separated `resource` query parameter. If yes, split the values and + * reconstruct the URL with multiple `resource` query parameters. + * E.g. `?resource=foo,bar` => `?resource=foo&resource=bar` + */ + oidc.use(koaResourceParam()); /** * `oidc-provider` [strictly checks](https://github.com/panva/node-oidc-provider/blob/6a0bcbcd35ed3e6179e81f0ab97a45f5e4e58f48/lib/shared/selective_body.js#L11) * the `content-type` header for further processing. From 61a2422601dcb27c3ed424293c62633c0449ff75 Mon Sep 17 00:00:00 2001 From: Darcy Ye Date: Tue, 23 Apr 2024 18:53:45 +0800 Subject: [PATCH 314/687] chore(console,core): remove custom JWT dev feature guard (#5775) --- .../console/src/containers/ConsoleContent/Sidebar/hook.tsx | 2 +- packages/console/src/hooks/use-console-routes/index.tsx | 2 +- packages/core/src/oidc/extra-token-claims.ts | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/packages/console/src/containers/ConsoleContent/Sidebar/hook.tsx b/packages/console/src/containers/ConsoleContent/Sidebar/hook.tsx index 5a160896cc2..1d1cb002e15 100644 --- a/packages/console/src/containers/ConsoleContent/Sidebar/hook.tsx +++ b/packages/console/src/containers/ConsoleContent/Sidebar/hook.tsx @@ -130,7 +130,7 @@ export const useSidebarMenuItems = (): { { Icon: JwtClaims, title: 'customize_jwt', - isHidden: !(isCloud && isDevFeaturesEnabled), + isHidden: !isCloud, }, { Icon: Hook, diff --git a/packages/console/src/hooks/use-console-routes/index.tsx b/packages/console/src/hooks/use-console-routes/index.tsx index 47ee00f0440..9739b14c4b2 100644 --- a/packages/console/src/hooks/use-console-routes/index.tsx +++ b/packages/console/src/hooks/use-console-routes/index.tsx @@ -65,7 +65,7 @@ export const useConsoleRoutes = () => { profile, { path: 'signing-keys', element: }, isCloud && tenantSettings, - isCloud && isDevFeaturesEnabled && customizeJwt + isCloud && customizeJwt ), [tenantSettings] ); diff --git a/packages/core/src/oidc/extra-token-claims.ts b/packages/core/src/oidc/extra-token-claims.ts index 139f518cdfd..5b9fbb42bb5 100644 --- a/packages/core/src/oidc/extra-token-claims.ts +++ b/packages/core/src/oidc/extra-token-claims.ts @@ -66,9 +66,9 @@ export const getExtraTokenClaimsForJwtCustomization = async ( cloudConnection: CloudConnectionLibrary; } ): Promise => { - const { isDevFeaturesEnabled, isCloud } = EnvSet.values; + const { isCloud } = EnvSet.values; // No cloud connection for OSS version, skip. - if (!isDevFeaturesEnabled || !isCloud) { + if (!isCloud) { return; } From fec60c8edf66392dc3e08d5440a415b25acd049e Mon Sep 17 00:00:00 2001 From: Darcy Ye Date: Tue, 23 Apr 2024 20:15:54 +0800 Subject: [PATCH 315/687] chore(phrases): update custom JWT console phrases (#5776) --- .../src/locales/de/errors/jwt-customizer.ts | 8 +- .../de/translation/admin-console/errors.ts | 5 +- .../de/translation/admin-console/general.ts | 12 +- .../translation/admin-console/jwt-claims.ts | 120 +++++++----------- .../admin-console/subscription/quota-item.ts | 38 ++---- .../admin-console/subscription/quota-table.ts | 20 +-- .../de/translation/admin-console/tabs.ts | 3 +- .../translation/admin-console/upsell/index.ts | 5 +- .../admin-console/upsell/paywall.ts | 18 +-- .../src/locales/es/errors/jwt-customizer.ts | 8 +- .../es/translation/admin-console/errors.ts | 3 +- .../es/translation/admin-console/general.ts | 12 +- .../translation/admin-console/jwt-claims.ts | 119 +++++++---------- .../admin-console/subscription/quota-item.ts | 42 ++---- .../admin-console/subscription/quota-table.ts | 24 ++-- .../es/translation/admin-console/tabs.ts | 3 +- .../translation/admin-console/upsell/index.ts | 3 +- .../admin-console/upsell/paywall.ts | 18 +-- .../src/locales/fr/errors/jwt-customizer.ts | 8 +- .../fr/translation/admin-console/errors.ts | 3 +- .../fr/translation/admin-console/general.ts | 12 +- .../translation/admin-console/jwt-claims.ts | 120 +++++++----------- .../admin-console/subscription/quota-item.ts | 42 ++---- .../admin-console/subscription/quota-table.ts | 24 ++-- .../fr/translation/admin-console/tabs.ts | 3 +- .../translation/admin-console/upsell/index.ts | 3 +- .../admin-console/upsell/paywall.ts | 6 - .../src/locales/it/errors/jwt-customizer.ts | 8 +- .../it/translation/admin-console/errors.ts | 3 +- .../it/translation/admin-console/general.ts | 12 +- .../translation/admin-console/jwt-claims.ts | 119 +++++++---------- .../admin-console/subscription/quota-item.ts | 42 ++---- .../admin-console/subscription/quota-table.ts | 20 +-- .../it/translation/admin-console/tabs.ts | 3 +- .../translation/admin-console/upsell/index.ts | 3 +- .../admin-console/upsell/paywall.ts | 18 +-- .../src/locales/ja/errors/jwt-customizer.ts | 6 +- .../ja/translation/admin-console/errors.ts | 9 +- .../ja/translation/admin-console/general.ts | 12 +- .../translation/admin-console/jwt-claims.ts | 117 ++++++----------- .../admin-console/subscription/quota-item.ts | 54 +++----- .../admin-console/subscription/quota-table.ts | 26 ++-- .../ja/translation/admin-console/tabs.ts | 3 +- .../translation/admin-console/upsell/index.ts | 3 +- .../admin-console/upsell/paywall.ts | 6 - .../src/locales/ko/errors/jwt-customizer.ts | 6 +- .../ko/translation/admin-console/errors.ts | 3 +- .../ko/translation/admin-console/general.ts | 12 +- .../translation/admin-console/jwt-claims.ts | 116 ++++++----------- .../admin-console/subscription/quota-item.ts | 42 ++---- .../admin-console/subscription/quota-table.ts | 29 ++--- .../ko/translation/admin-console/tabs.ts | 3 +- .../translation/admin-console/upsell/index.ts | 3 +- .../admin-console/upsell/paywall.ts | 18 +-- .../locales/pl-pl/errors/jwt-customizer.ts | 7 +- .../pl-pl/translation/admin-console/errors.ts | 5 +- .../translation/admin-console/general.ts | 12 +- .../translation/admin-console/jwt-claims.ts | 118 ++++++----------- .../admin-console/subscription/quota-item.ts | 42 ++---- .../admin-console/subscription/quota-table.ts | 22 +--- .../pl-pl/translation/admin-console/tabs.ts | 3 +- .../translation/admin-console/upsell/index.ts | 7 +- .../admin-console/upsell/paywall.ts | 18 +-- .../locales/pt-br/errors/jwt-customizer.ts | 7 +- .../pt-br/translation/admin-console/errors.ts | 3 +- .../translation/admin-console/general.ts | 12 +- .../translation/admin-console/jwt-claims.ts | 118 ++++++----------- .../admin-console/subscription/quota-item.ts | 42 ++---- .../admin-console/subscription/quota-table.ts | 22 +--- .../pt-br/translation/admin-console/tabs.ts | 3 +- .../translation/admin-console/upsell/index.ts | 3 +- .../admin-console/upsell/paywall.ts | 18 +-- .../locales/pt-pt/errors/jwt-customizer.ts | 7 +- .../pt-pt/translation/admin-console/errors.ts | 5 +- .../translation/admin-console/general.ts | 10 +- .../translation/admin-console/jwt-claims.ts | 118 ++++++----------- .../admin-console/subscription/quota-item.ts | 42 ++---- .../admin-console/subscription/quota-table.ts | 22 +--- .../pt-pt/translation/admin-console/tabs.ts | 3 +- .../translation/admin-console/upsell/index.ts | 3 +- .../admin-console/upsell/paywall.ts | 72 +++++------ .../src/locales/ru/errors/jwt-customizer.ts | 7 +- .../ru/translation/admin-console/errors.ts | 3 +- .../ru/translation/admin-console/general.ts | 12 +- .../translation/admin-console/jwt-claims.ts | 117 ++++++----------- .../admin-console/subscription/quota-item.ts | 42 ++---- .../admin-console/subscription/quota-table.ts | 36 ++---- .../ru/translation/admin-console/tabs.ts | 3 +- .../translation/admin-console/upsell/index.ts | 3 +- .../admin-console/upsell/paywall.ts | 18 +-- .../locales/tr-tr/errors/jwt-customizer.ts | 6 +- .../tr-tr/translation/admin-console/errors.ts | 3 +- .../translation/admin-console/general.ts | 12 +- .../translation/admin-console/jwt-claims.ts | 118 ++++++----------- .../admin-console/subscription/quota-item.ts | 42 ++---- .../admin-console/subscription/quota-table.ts | 24 ++-- .../tr-tr/translation/admin-console/tabs.ts | 3 +- .../translation/admin-console/upsell/index.ts | 3 +- .../admin-console/upsell/paywall.ts | 50 ++++---- .../locales/zh-cn/errors/jwt-customizer.ts | 6 +- .../zh-cn/translation/admin-console/errors.ts | 3 +- .../translation/admin-console/general.ts | 12 +- .../translation/admin-console/jwt-claims.ts | 119 ++++++----------- .../admin-console/subscription/quota-item.ts | 48 +++---- .../admin-console/subscription/quota-table.ts | 23 +--- .../zh-cn/translation/admin-console/tabs.ts | 3 +- .../translation/admin-console/upsell/index.ts | 3 +- .../admin-console/upsell/paywall.ts | 74 +++++------ .../locales/zh-hk/errors/jwt-customizer.ts | 6 +- .../zh-hk/translation/admin-console/errors.ts | 7 +- .../translation/admin-console/general.ts | 12 +- .../translation/admin-console/jwt-claims.ts | 119 ++++++----------- .../admin-console/subscription/quota-item.ts | 58 ++++----- .../admin-console/subscription/quota-table.ts | 27 ++-- .../zh-hk/translation/admin-console/tabs.ts | 3 +- .../translation/admin-console/upsell/index.ts | 5 +- .../admin-console/upsell/paywall.ts | 50 +++----- .../locales/zh-tw/errors/jwt-customizer.ts | 6 +- .../zh-tw/translation/admin-console/errors.ts | 3 +- .../translation/admin-console/general.ts | 12 +- .../translation/admin-console/jwt-claims.ts | 119 ++++++----------- .../admin-console/subscription/quota-item.ts | 44 +++---- .../admin-console/subscription/quota-table.ts | 25 ++-- .../zh-tw/translation/admin-console/tabs.ts | 3 +- .../translation/admin-console/upsell/index.ts | 3 +- .../admin-console/upsell/paywall.ts | 34 ++--- 126 files changed, 1215 insertions(+), 2236 deletions(-) diff --git a/packages/phrases/src/locales/de/errors/jwt-customizer.ts b/packages/phrases/src/locales/de/errors/jwt-customizer.ts index c7c5c1e2af9..51c26359d59 100644 --- a/packages/phrases/src/locales/de/errors/jwt-customizer.ts +++ b/packages/phrases/src/locales/de/errors/jwt-customizer.ts @@ -1,8 +1,8 @@ const jwt_customizer = { - /** UNTRANSLATED */ - general: 'An error occurred while customizing the JWT token. Please try again later.', - /** UNTRANSLATED */ - can_not_create_for_admin_tenant: 'Cannot create a JWT token customizer for the admin tenant.', + general: + 'Bei der Anpassung des JWT-Tokens ist ein Fehler aufgetreten. Bitte versuchen Sie es später erneut.', + can_not_create_for_admin_tenant: + 'Kann keinen JWT-Token-Anpasser für den Admin-Mandanten erstellen.', }; export default Object.freeze(jwt_customizer); diff --git a/packages/phrases/src/locales/de/translation/admin-console/errors.ts b/packages/phrases/src/locales/de/translation/admin-console/errors.ts index 62b6342fb44..890eb576fb5 100644 --- a/packages/phrases/src/locales/de/translation/admin-console/errors.ts +++ b/packages/phrases/src/locales/de/translation/admin-console/errors.ts @@ -7,8 +7,7 @@ const errors = { invalid_uri_format: 'Ungültiges URI-Format', invalid_origin_format: 'Ungültiges URI Origin-Format', invalid_json_format: 'Ungültiges JSON-Format', - /** UNTRANSLATED */ - invalid_regex: 'Invalid regular expression', + invalid_regex: 'Ungültiger regulärer Ausdruck', invalid_error_message_format: 'Ungültiges Fehlermeldung-Format.', required_field_missing: 'Bitte fülle {{field}} aus', required_field_missing_plural: 'Mindestens ein {{field}} muss ausgefüllt sein', @@ -19,7 +18,7 @@ const errors = { phone_pattern_error: 'Die Telefonnummer ist ungültig.', insecure_contexts: 'Unsichere Kontexte (nicht-HTTPS) werden nicht unterstützt.', unexpected_error: 'Ein unerwarteter Fehler ist aufgetreten', - not_found: '404 not found', + not_found: '404 nicht gefunden', create_internal_role_violation: 'Sie erstellen eine neue interne Rolle, die von Logto verboten ist. Versuchen Sie einen anderen Namen, der nicht mit "#internal:" beginnt.', should_be_an_integer: 'Sollte eine Ganzzahl sein.', diff --git a/packages/phrases/src/locales/de/translation/admin-console/general.ts b/packages/phrases/src/locales/de/translation/admin-console/general.ts index 6a3e528dcb1..e2fd47b4cda 100644 --- a/packages/phrases/src/locales/de/translation/admin-console/general.ts +++ b/packages/phrases/src/locales/de/translation/admin-console/general.ts @@ -25,11 +25,9 @@ const general = { customize: 'Anpassen', enable: 'Aktivieren', reminder: 'Erinnerung', - /** UNTRANSLATED */ - edit: 'Edit', + edit: 'Bearbeiten', delete: 'Löschen', - /** UNTRANSLATED */ - deleted: 'Deleted', + deleted: 'Gelöscht', more_options: 'MEHR OPTIONEN', close: 'Schließen', copy: 'Kopieren', @@ -59,8 +57,7 @@ const general = { demo: 'Demo', unnamed: 'Unbenannt', view: 'Anzeigen', - /** UNTRANSLATED */ - open: 'Open', + open: 'Öffnen', hide: 'Verbergen', unknown_error: 'Unbekannter Fehler, bitte versuchen Sie es später erneut.', select: 'Auswählen', @@ -72,8 +69,7 @@ const general = { edit_field: 'Bearbeite {{field}}', delete_field: 'Lösche {{field}}', coming_soon: 'Demnächst verfügbar', - /** UNTRANSLATED */ - or: 'Or', + or: 'Oder', }; export default Object.freeze(general); diff --git a/packages/phrases/src/locales/de/translation/admin-console/jwt-claims.ts b/packages/phrases/src/locales/de/translation/admin-console/jwt-claims.ts index f0d189ab412..dde13429467 100644 --- a/packages/phrases/src/locales/de/translation/admin-console/jwt-claims.ts +++ b/packages/phrases/src/locales/de/translation/admin-console/jwt-claims.ts @@ -1,98 +1,66 @@ const jwt_claims = { - /** UNTRANSLATED */ - title: 'Custom JWT', - /** UNTRANSLATED */ + title: 'Benutzerdefiniertes JWT', description: - 'Set up custom JWT claims to include in the access token. These claims can be used to pass additional information to your application.', + 'Legen Sie benutzerdefinierte JWT-Ansprüche fest, die im Zugriffstoken enthalten sein sollen. Diese Ansprüche können verwendet werden, um zusätzliche Informationen an Ihre Anwendung zu übergeben.', user_jwt: { - /** UNTRANSLATED */ - card_title: 'For user', - /** UNTRANSLATED */ - card_field: 'User access token', - /** UNTRANSLATED */ - card_description: 'Add user-specific data during access token issuance.', - /** UNTRANSLATED */ - for: 'for user', + card_title: 'Für Benutzer', + card_field: 'Benutzerzugriffstoken', + card_description: + 'Fügen Sie benutzerspezifische Daten während der Ausstellung des Zugriffstokens hinzu.', + for: 'für Benutzer', }, machine_to_machine_jwt: { - /** UNTRANSLATED */ - card_title: 'For M2M', - /** UNTRANSLATED */ - card_field: 'Machine-to-machine token', - /** UNTRANSLATED */ - card_description: 'Add extra data during machine-to-machine token issuance.', - /** UNTRANSLATED */ - for: 'for M2M', + card_title: 'Für M2M', + card_field: 'Maschine-zu-Maschine-Token', + card_description: + 'Fügen Sie zusätzliche Daten während der Ausstellung des Maschine-zu-Maschine-Tokens hinzu.', + for: 'für M2M', }, - /** UNTRANSLATED */ - code_editor_title: 'Customize the {{token}} claims', - /** UNTRANSLATED */ - custom_jwt_create_button: 'Add custom claims', - /** UNTRANSLATED */ - custom_jwt_item: 'Custom claims {{for}}', - /** UNTRANSLATED */ - delete_modal_title: 'Delete custom claims', - /** UNTRANSLATED */ - delete_modal_content: 'Are you sure you want to delete the custom claims?', - /** UNTRANSLATED */ - clear: 'Clear', - /** UNTRANSLATED */ - cleared: 'Cleared', - /** UNTRANSLATED */ - restore: 'Restore defaults', - /** UNTRANSLATED */ - restored: 'Restored', - /** UNTRANSLATED */ - data_source_tab: 'Data source', - /** UNTRANSLATED */ - test_tab: 'Test context', - /** UNTRANSLATED */ - jwt_claims_description: 'Default claims are auto-included in the JWT and cannot be overridden.', + code_editor_title: 'Passen Sie die {{token}}-Ansprüche an', + custom_jwt_create_button: 'Benutzerdefinierte Ansprüche hinzufügen', + custom_jwt_item: 'Benutzerdefinierte Ansprüche {{for}}', + delete_modal_title: 'Benutzerdefinierte Ansprüche löschen', + delete_modal_content: + 'Sind Sie sicher, dass Sie die benutzerdefinierten Ansprüche löschen möchten?', + clear: 'Löschen', + cleared: 'Gelöscht', + restore: 'Standard wiederherstellen', + restored: 'Wiederhergestellt', + data_source_tab: 'Datenquelle', + test_tab: 'Testumgebung', + jwt_claims_description: + 'Standardansprüche werden automatisch im JWT enthalten und können nicht überschrieben werden.', user_data: { - /** UNTRANSLATED */ - title: 'User data', - /** UNTRANSLATED */ - subtitle: 'Use `data.user` input parameter to provide vital user info.', + title: 'Benutzerdaten', + subtitle: + 'Verwenden Sie den `data.user` Eingabeparameter, um wichtige Benutzerinformationen bereitzustellen.', }, token_data: { - /** UNTRANSLATED */ - title: 'Token data', - /** UNTRANSLATED */ - subtitle: 'Use `token` input parameter for current access token payload. ', + title: 'Token-Daten', + subtitle: 'Verwenden Sie den `token` Eingabeparameter für die aktuelle Zugriffstoken-Payload.', }, fetch_external_data: { - /** UNTRANSLATED */ - title: 'Fetch external data', - /** UNTRANSLATED */ - subtitle: 'Incorporate data from your external APIs directly into claims.', - /** UNTRANSLATED */ + title: 'Externe Daten abrufen', + subtitle: 'Integrieren Sie Daten direkt aus Ihren externen APIs in die Ansprüche.', description: - 'Use the `fetch` function to call your external APIs and include the data in your custom claims. Example: ', + 'Verwenden Sie die `fetch`-Funktion, um Ihre externen APIs aufzurufen und die Daten in Ihre benutzerdefinierten Ansprüche einzubeziehen. Beispiel: ', }, environment_variables: { - /** UNTRANSLATED */ - title: 'Set environment variables', - /** UNTRANSLATED */ - subtitle: 'Use environment variables to store sensitive information.', - /** UNTRANSLATED */ - input_field_title: 'Add environment variables', - /** UNTRANSLATED */ - sample_code: 'Accessing environment variables in your custom JWT claims handler. Example: ', + title: 'Umgebungsvariablen festlegen', + subtitle: 'Verwenden Sie Umgebungsvariablen, um vertrauliche Informationen zu speichern.', + input_field_title: 'Umgebungsvariablen hinzufügen', + sample_code: + 'Zugriff auf Umgebungsvariablen in Ihrem benutzerdefinierten JWT-Anspruchshandler. Beispiel: ', }, - /** UNTRANSLATED */ jwt_claims_hint: - 'Limit custom claims to under 50KB. Default JWT claims are automatically included in the token and can not be overridden.', + 'Beschränken Sie benutzerdefinierte Ansprüche auf weniger als 50 KB. Standard-JWT-Ansprüche werden automatisch im Token enthalten und können nicht überschrieben werden.', tester: { - /** UNTRANSLATED */ - subtitle: 'Adjust mock token and user data for testing.', - /** UNTRANSLATED */ - run_button: 'Run test', - /** UNTRANSLATED */ - result_title: 'Test result', + subtitle: 'Mock-Token und Benutzerdaten für Tests anpassen.', + run_button: 'Test ausführen', + result_title: 'Testergebnis', }, form_error: { - /** UNTRANSLATED */ - invalid_json: 'Invalid JSON format', + invalid_json: 'Ungültiges JSON-Format', }, }; diff --git a/packages/phrases/src/locales/de/translation/admin-console/subscription/quota-item.ts b/packages/phrases/src/locales/de/translation/admin-console/subscription/quota-item.ts index 7f869a6248b..b31e80bd585 100644 --- a/packages/phrases/src/locales/de/translation/admin-console/subscription/quota-item.ts +++ b/packages/phrases/src/locales/de/translation/admin-console/subscription/quota-item.ts @@ -34,16 +34,11 @@ const quota_item = { not_eligible: 'Entferne deine Maschine-zu-Maschine-Apps', }, third_party_applications_limit: { - /** UNTRANSLATED */ - name: 'Third-party apps', - /** UNTRANSLATED */ - limited: '{{count, number}} third-party app', - /** UNTRANSLATED */ - limited_other: '{{count, number}} third-party apps', - /** UNTRANSLATED */ - unlimited: 'Unlimited third-party apps', - /** UNTRANSLATED */ - not_eligible: 'Remove your third-party apps', + name: 'Drittanbieter-Apps', + limited: '{{count, number}} Drittanbieter-App', + limited_other: '{{count, number}} Drittanbieter-Apps', + unlimited: 'Unbegrenzte Drittanbieter-Apps', + not_eligible: 'Entferne deine Drittanbieter-Apps', }, resources_limit: { name: 'API-Ressourcen', @@ -152,25 +147,16 @@ const quota_item = { not_eligible: 'Entferne dein Enterprise SSO', }, tenant_members_limit: { - /** UNTRANSLATED */ - name: 'Tenant members', - /** UNTRANSLATED */ - limited: '{{count, number}} tenant member', - /** UNTRANSLATED */ - limited_other: '{{count, number}} tenant members', - /** UNTRANSLATED */ - unlimited: 'Unlimited tenant members', - /** UNTRANSLATED */ + name: 'Mandantenmitglieder', + limited: '{{count, number}} Mandantenmitglied', + limited_other: '{{count, number}} Mandantenmitglieder', + unlimited: 'Unbegrenzte Mandantenmitglieder', not_eligible: 'Remove your tenant members', }, custom_jwt_enabled: { - /** UNTRANSLATED */ - name: 'Custom JWT', - /** UNTRANSLATED */ - limited: 'Custom JWT', - /** UNTRANSLATED */ - unlimited: 'Custom JWT', - /** UNTRANSLATED */ + name: 'Benutzerdefiniertes JWT', + limited: 'Benutzerdefiniertes JWT', + unlimited: 'Benutzerdefiniertes JWT', not_eligible: 'Remove your JWT claims customizer', }, }; diff --git a/packages/phrases/src/locales/de/translation/admin-console/subscription/quota-table.ts b/packages/phrases/src/locales/de/translation/admin-console/subscription/quota-table.ts index 867357a6b11..17274ffe3ad 100644 --- a/packages/phrases/src/locales/de/translation/admin-console/subscription/quota-table.ts +++ b/packages/phrases/src/locales/de/translation/admin-console/subscription/quota-table.ts @@ -9,7 +9,6 @@ const quota_table = { title: 'Anwendungen', total: 'Gesamtzahl der Anwendungen', m2m: 'Maschine-zu-Maschine', - /** UNTRANSLATED */ third_party: 'Third-party apps', }, resource: { @@ -66,16 +65,11 @@ const quota_table = { hipaa_or_baa_report: 'HIPAA/BAA-Bericht', }, developers_and_platform: { - /** UNTRANSLATED */ - title: 'Developers and platform', - /** UNTRANSLATED */ + title: 'Entwickler und Plattform', hooks: 'Webhooks', - /** UNTRANSLATED */ - audit_logs_retention: 'Audit logs retention', - /** UNTRANSLATED */ - jwt_claims: 'JWT claims', - /** UNTRANSLATED */ - tenant_members: 'Tenant members', + audit_logs_retention: 'Auditprotokolle Aufbewahrung', + jwt_claims: 'JWT-Ansprüche', + tenant_members: 'Mandantenmitglieder', }, unlimited: 'Unbegrenzt', contact: 'Kontakt', @@ -97,17 +91,15 @@ const quota_table = { 'Alle Arten von Tokens, die von Logto ausgegeben wurden, einschließlich Zugriffstoken, Aktualisierungstoken, usw.', mao_tip: 'MAO (Monthly Active Org) bezeichnet die Anzahl der einzigartigen Organisationen, die in einem Abrechnungszyklus mindestens einen MAU (Monthly Active User) haben.', - /** UNTRANSLATED */ third_party_tip: - 'Use Logto as your OIDC identity provider for third-party app sign-ins and permission grants.', + 'Verwenden Sie Logto als Ihren OIDC-Identitätsanbieter für Anmeldungen von Drittanbieter-Apps und Berechtigungsvergaben.', included: '{{value, number}} inklusive', included_mao: '{{value, number}} MAO enthalten', extra_quota_price: 'Dann ${{value, number}} pro Monat / je danach', per_month_each: '${{value, number}} pro Monat / je', extra_mao_price: 'Dann ${{value, number}} pro MAO', per_month: '${{value, number}} pro Monat', - /** UNTRANSLATED */ - per_member: 'Then ${{value, number}} per member', + per_member: 'Dann ${{value, number}} pro Mitglied', }; export default Object.freeze(quota_table); diff --git a/packages/phrases/src/locales/de/translation/admin-console/tabs.ts b/packages/phrases/src/locales/de/translation/admin-console/tabs.ts index 0d3f5ad389a..a00a6b53586 100644 --- a/packages/phrases/src/locales/de/translation/admin-console/tabs.ts +++ b/packages/phrases/src/locales/de/translation/admin-console/tabs.ts @@ -14,8 +14,7 @@ const tabs = { docs: 'Dokumentation', tenant_settings: 'Einstellungen', mfa: 'Multi-Faktor-Authentifizierung', - /** UNTRANSLATED */ - customize_jwt: 'Custom JWT', + customize_jwt: 'Benutzerdefiniertes JWT', signing_keys: 'Signierschlüssel', organization_template: 'Organisationstemplate', }; diff --git a/packages/phrases/src/locales/de/translation/admin-console/upsell/index.ts b/packages/phrases/src/locales/de/translation/admin-console/upsell/index.ts index ecc7f650b48..83ec93ea419 100644 --- a/packages/phrases/src/locales/de/translation/admin-console/upsell/index.ts +++ b/packages/phrases/src/locales/de/translation/admin-console/upsell/index.ts @@ -34,9 +34,8 @@ const upsell = { add_on_quota_item: { api_resource: 'API-Ressource', machine_to_machine: 'Machine-to-Machine-Anwendung', - tokens: '{{limit}}M Tokens', - /** UNTRANSLATED */ - tenant_member: 'tenant member', + tokens: '{{limit}}M Token', + tenant_member: 'Mietermitglied', }, charge_notification_for_quota_limit: 'Sie haben Ihr {{item}}-Quotenlimit überschritten. Logto wird Gebühren für die Nutzung über Ihr Quotenlimit hinaus hinzufügen. Die Abrechnung beginnt am Tag der Veröffentlichung des neuen Add-On-Preisdesigns. Mehr erfahren', diff --git a/packages/phrases/src/locales/de/translation/admin-console/upsell/paywall.ts b/packages/phrases/src/locales/de/translation/admin-console/upsell/paywall.ts index 77845a8b90b..71af9c0fd99 100644 --- a/packages/phrases/src/locales/de/translation/admin-console/upsell/paywall.ts +++ b/packages/phrases/src/locales/de/translation/admin-console/upsell/paywall.ts @@ -52,24 +52,18 @@ const paywall = { mfa: 'Schalten Sie MFA zur Sicherheitsüberprüfung frei, indem Sie auf einen kostenpflichtigen Plan aktualisieren. Zögern Sie nicht, uns zu kontaktieren, wenn Sie Unterstützung benötigen.', organizations: 'Organisationen freischalten, indem Sie auf einen kostenpflichtigen Plan aktualisieren. Zögern Sie nicht, kontaktieren Sie uns, wenn Sie Unterstützung benötigen.', - /** UNTRANSLATED */ third_party_apps: - 'Unlock Logto as IdP for third-party apps by upgrading to a paid plan. For any assistance, feel free to contact us.', - /** UNTRANSLATED */ + 'Entsperren Sie Logto als IdP für Drittanbieter-Apps, indem Sie auf einen kostenpflichtigen Plan aktualisieren. Bei Bedarf können Sie uns gerne kontaktieren.', sso_connectors: - 'Unlock enterprise sso by upgrading to a paid plan. For any assistance, feel free to contact us.', - /** UNTRANSLATED */ + 'Schalten Sie Enterprise-SSO frei, indem Sie auf einen kostenpflichtigen Plan aktualisieren. Bei Bedarf können Sie uns gerne kontaktieren.', tenant_members: - 'Unlock collaboration feature by upgrading to a paid plan. For any assistance, feel free to contact us.', - /** UNTRANSLATED */ + 'Aktivieren Sie die Kollaborationsfunktion durch ein Upgrade auf einen kostenpflichtigen Plan. Bei Bedarf können Sie uns gerne kontaktieren.', tenant_members_dev_plan: - "You've reached your {{limit}}-member limit. Release a member or revoke a pending invitation to add someone new. Need more seats? Feel free to contact us.", + 'Sie haben Ihr Limit von {{limit}} Mitgliedern erreicht. Geben Sie ein Mitglied frei oder widerrufen Sie eine ausstehende Einladung, um jemand neuen hinzuzufügen. Benötigen Sie mehr Plätze? Zögern Sie nicht, uns zu kontaktieren.', custom_jwt: { - /** UNTRANSLATED */ - title: 'Add custom claims', - /** UNTRANSLATED */ + title: 'Benutzerdefinierte Claims hinzufügen', description: - "Upgrade to a paid plan for custom JWT functionality and premium benefits. Don't hesitate to contact us if you have any questions.", + 'Upgrade auf einen kostenpflichtigen Plan für benutzerdefinierte JWT-Funktionalität und Premium-Vorteile. Wenn Sie Fragen haben, zögern Sie nicht, uns zu kontaktieren.', }, }; diff --git a/packages/phrases/src/locales/es/errors/jwt-customizer.ts b/packages/phrases/src/locales/es/errors/jwt-customizer.ts index c7c5c1e2af9..06afccf8ed0 100644 --- a/packages/phrases/src/locales/es/errors/jwt-customizer.ts +++ b/packages/phrases/src/locales/es/errors/jwt-customizer.ts @@ -1,8 +1,8 @@ const jwt_customizer = { - /** UNTRANSLATED */ - general: 'An error occurred while customizing the JWT token. Please try again later.', - /** UNTRANSLATED */ - can_not_create_for_admin_tenant: 'Cannot create a JWT token customizer for the admin tenant.', + general: + 'Ocurrió un error al personalizar el token JWT. Por favor, inténtalo de nuevo más tarde.', + can_not_create_for_admin_tenant: + 'No se puede crear un personalizador de token JWT para el inquilino de administrador.', }; export default Object.freeze(jwt_customizer); diff --git a/packages/phrases/src/locales/es/translation/admin-console/errors.ts b/packages/phrases/src/locales/es/translation/admin-console/errors.ts index 43e2207605e..9187828703f 100644 --- a/packages/phrases/src/locales/es/translation/admin-console/errors.ts +++ b/packages/phrases/src/locales/es/translation/admin-console/errors.ts @@ -7,8 +7,7 @@ const errors = { invalid_uri_format: 'Formato de URI no válido', invalid_origin_format: 'Formato de origen de URI no válido', invalid_json_format: 'Formato JSON no válido', - /** UNTRANSLATED */ - invalid_regex: 'Invalid regular expression', + invalid_regex: 'Expresión regular no válida', invalid_error_message_format: 'El formato del mensaje de error es inválido.', required_field_missing: 'Por favor ingrese {{field}}', required_field_missing_plural: 'Tienes que ingresar al menos un {{field}}', diff --git a/packages/phrases/src/locales/es/translation/admin-console/general.ts b/packages/phrases/src/locales/es/translation/admin-console/general.ts index 2632917a57d..246bb821913 100644 --- a/packages/phrases/src/locales/es/translation/admin-console/general.ts +++ b/packages/phrases/src/locales/es/translation/admin-console/general.ts @@ -25,11 +25,9 @@ const general = { customize: 'Personalizar', enable: 'Habilitar', reminder: 'Recordatorio', - /** UNTRANSLATED */ - edit: 'Edit', + edit: 'Editar', delete: 'Eliminar', - /** UNTRANSLATED */ - deleted: 'Deleted', + deleted: 'Eliminado', more_options: 'MÁS OPCIONES', close: 'Cerrar', copy: 'Copiar', @@ -59,8 +57,7 @@ const general = { demo: 'Demostración', unnamed: 'Sin nombre', view: 'Ver', - /** UNTRANSLATED */ - open: 'Open', + open: 'Abrir', hide: 'Ocultar', unknown_error: 'Error desconocido, por favor inténtalo de nuevo más tarde.', select: 'Seleccionar', @@ -72,8 +69,7 @@ const general = { edit_field: 'Editar {{field}}', delete_field: 'Eliminar {{field}}', coming_soon: 'Próximamente', - /** UNTRANSLATED */ - or: 'Or', + or: 'O ', }; export default Object.freeze(general); diff --git a/packages/phrases/src/locales/es/translation/admin-console/jwt-claims.ts b/packages/phrases/src/locales/es/translation/admin-console/jwt-claims.ts index f0d189ab412..d1d210d6640 100644 --- a/packages/phrases/src/locales/es/translation/admin-console/jwt-claims.ts +++ b/packages/phrases/src/locales/es/translation/admin-console/jwt-claims.ts @@ -1,98 +1,65 @@ const jwt_claims = { - /** UNTRANSLATED */ - title: 'Custom JWT', - /** UNTRANSLATED */ + title: 'JWT Personalizado', description: - 'Set up custom JWT claims to include in the access token. These claims can be used to pass additional information to your application.', + 'Configure los reclamos personalizados del JWT para incluir en el token de acceso. Estos reclamos se pueden usar para pasar información adicional a su aplicación.', user_jwt: { - /** UNTRANSLATED */ - card_title: 'For user', - /** UNTRANSLATED */ - card_field: 'User access token', - /** UNTRANSLATED */ - card_description: 'Add user-specific data during access token issuance.', - /** UNTRANSLATED */ - for: 'for user', + card_title: 'Para usuario', + card_field: 'Token de acceso de usuario', + card_description: + 'Añadir datos específicos del usuario durante la emisión del token de acceso.', + for: 'para usuario', }, machine_to_machine_jwt: { - /** UNTRANSLATED */ - card_title: 'For M2M', - /** UNTRANSLATED */ - card_field: 'Machine-to-machine token', - /** UNTRANSLATED */ - card_description: 'Add extra data during machine-to-machine token issuance.', - /** UNTRANSLATED */ - for: 'for M2M', + card_title: 'Para M2M', + card_field: 'Token de máquina a máquina', + card_description: 'Añadir datos adicionales durante la emisión del token de máquina a máquina.', + for: 'para M2M', }, - /** UNTRANSLATED */ - code_editor_title: 'Customize the {{token}} claims', - /** UNTRANSLATED */ - custom_jwt_create_button: 'Add custom claims', - /** UNTRANSLATED */ - custom_jwt_item: 'Custom claims {{for}}', - /** UNTRANSLATED */ - delete_modal_title: 'Delete custom claims', - /** UNTRANSLATED */ - delete_modal_content: 'Are you sure you want to delete the custom claims?', - /** UNTRANSLATED */ - clear: 'Clear', - /** UNTRANSLATED */ - cleared: 'Cleared', - /** UNTRANSLATED */ - restore: 'Restore defaults', - /** UNTRANSLATED */ - restored: 'Restored', - /** UNTRANSLATED */ - data_source_tab: 'Data source', - /** UNTRANSLATED */ - test_tab: 'Test context', - /** UNTRANSLATED */ - jwt_claims_description: 'Default claims are auto-included in the JWT and cannot be overridden.', + code_editor_title: 'Personalizar los reclamos de {{token}}', + custom_jwt_create_button: 'Añadir reclamos personalizados', + custom_jwt_item: 'Reclamos personalizados {{for}}', + delete_modal_title: 'Eliminar reclamos personalizados', + delete_modal_content: '¿Está seguro de que desea eliminar los reclamos personalizados?', + clear: 'Limpiar', + cleared: 'Limpiado', + restore: 'Restaurar valores predeterminados', + restored: 'Restaurado', + data_source_tab: 'Fuente de datos', + test_tab: 'Contexto de prueba', + jwt_claims_description: + 'Los reclamos predeterminados se incluyen automáticamente en el JWT y no se pueden anular.', user_data: { - /** UNTRANSLATED */ - title: 'User data', - /** UNTRANSLATED */ - subtitle: 'Use `data.user` input parameter to provide vital user info.', + title: 'Datos del usuario', + subtitle: + 'Utilice el parámetro de entrada `data.user` para proporcionar información vital del usuario.', }, token_data: { - /** UNTRANSLATED */ - title: 'Token data', - /** UNTRANSLATED */ - subtitle: 'Use `token` input parameter for current access token payload. ', + title: 'Datos del token', + subtitle: + 'Utilice el parámetro de entrada `token` para la carga útil actual del token de acceso. ', }, fetch_external_data: { - /** UNTRANSLATED */ - title: 'Fetch external data', - /** UNTRANSLATED */ - subtitle: 'Incorporate data from your external APIs directly into claims.', - /** UNTRANSLATED */ + title: 'Obtener datos externos', + subtitle: 'Incorpore datos de sus API externas directamente en los reclamos.', description: - 'Use the `fetch` function to call your external APIs and include the data in your custom claims. Example: ', + 'Utilice la función `fetch` para llamar a sus API externas e incluir los datos en sus reclamos personalizados. Ejemplo: ', }, environment_variables: { - /** UNTRANSLATED */ - title: 'Set environment variables', - /** UNTRANSLATED */ - subtitle: 'Use environment variables to store sensitive information.', - /** UNTRANSLATED */ - input_field_title: 'Add environment variables', - /** UNTRANSLATED */ - sample_code: 'Accessing environment variables in your custom JWT claims handler. Example: ', + title: 'Establecer variables de entorno', + subtitle: 'Utilice variables de entorno para almacenar información confidencial.', + input_field_title: 'Añadir variables de entorno', + sample_code: + 'Acceso a variables de entorno en el gestor de reclamos JWT personalizados. Ejemplo: ', }, - /** UNTRANSLATED */ jwt_claims_hint: - 'Limit custom claims to under 50KB. Default JWT claims are automatically included in the token and can not be overridden.', + 'Limite los reclamos personalizados a menos de 50 KB. Los reclamos predeterminados del JWT se incluyen automáticamente en el token y no se pueden anular.', tester: { - /** UNTRANSLATED */ - subtitle: 'Adjust mock token and user data for testing.', - /** UNTRANSLATED */ - run_button: 'Run test', - /** UNTRANSLATED */ - result_title: 'Test result', + subtitle: 'Ajustar el token simulado y los datos de usuario para pruebas.', + run_button: 'Ejecutar prueba', + result_title: 'Resultado de prueba', }, form_error: { - /** UNTRANSLATED */ - invalid_json: 'Invalid JSON format', + invalid_json: 'Formato JSON no válido', }, }; diff --git a/packages/phrases/src/locales/es/translation/admin-console/subscription/quota-item.ts b/packages/phrases/src/locales/es/translation/admin-console/subscription/quota-item.ts index 6b390ee16e3..369ac7f8731 100644 --- a/packages/phrases/src/locales/es/translation/admin-console/subscription/quota-item.ts +++ b/packages/phrases/src/locales/es/translation/admin-console/subscription/quota-item.ts @@ -34,16 +34,11 @@ const quota_item = { not_eligible: 'Elimine sus aplicaciones de dispositivo a dispositivo', }, third_party_applications_limit: { - /** UNTRANSLATED */ - name: 'Third-party apps', - /** UNTRANSLATED */ - limited: '{{count, number}} third-party app', - /** UNTRANSLATED */ - limited_other: '{{count, number}} third-party apps', - /** UNTRANSLATED */ - unlimited: 'Unlimited third-party apps', - /** UNTRANSLATED */ - not_eligible: 'Remove your third-party apps', + name: 'Aplicaciones de terceros', + limited: '{{count, number}} aplicación de terceros', + limited_other: '{{count, number}} aplicaciones de terceros', + unlimited: 'Aplicaciones de terceros ilimitadas', + not_eligible: 'Elimine sus aplicaciones de terceros', }, resources_limit: { name: 'Recursos de API', @@ -152,26 +147,17 @@ const quota_item = { not_eligible: 'Elimine su SSO empresarial', }, tenant_members_limit: { - /** UNTRANSLATED */ - name: 'Tenant members', - /** UNTRANSLATED */ - limited: '{{count, number}} tenant member', - /** UNTRANSLATED */ - limited_other: '{{count, number}} tenant members', - /** UNTRANSLATED */ - unlimited: 'Unlimited tenant members', - /** UNTRANSLATED */ - not_eligible: 'Remove your tenant members', + name: 'Miembros del inquilino', + limited: '{{count, number}} miembro del inquilino', + limited_other: '{{count, number}} miembros del inquilino', + unlimited: 'Miembros del inquilino ilimitados', + not_eligible: 'Elimine sus miembros del inquilino', }, custom_jwt_enabled: { - /** UNTRANSLATED */ - name: 'Custom JWT', - /** UNTRANSLATED */ - limited: 'Custom JWT', - /** UNTRANSLATED */ - unlimited: 'Custom JWT', - /** UNTRANSLATED */ - not_eligible: 'Remove your JWT claims customizer', + name: 'JWT personalizado', + limited: 'JWT personalizado', + unlimited: 'JWT personalizado', + not_eligible: 'Elimine su personalizador de reclamos JWT', }, }; diff --git a/packages/phrases/src/locales/es/translation/admin-console/subscription/quota-table.ts b/packages/phrases/src/locales/es/translation/admin-console/subscription/quota-table.ts index c3210f48e54..60e6d714ec0 100644 --- a/packages/phrases/src/locales/es/translation/admin-console/subscription/quota-table.ts +++ b/packages/phrases/src/locales/es/translation/admin-console/subscription/quota-table.ts @@ -9,8 +9,7 @@ const quota_table = { title: 'Aplicaciones', total: 'Total de aplicaciones', m2m: 'Aplicación machine-to-machine', - /** UNTRANSLATED */ - third_party: 'Third-party apps', + third_party: 'Aplicaciones de terceros', }, resource: { title: 'Recursos de API', @@ -29,7 +28,7 @@ const quota_table = { title: 'Autenticación de usuario', omni_sign_in: 'Inicio de sesión omnicanal', password: 'Contraseña', - passwordless: 'Sin contraseña - Correo electrónico y SMS', + passwordless: 'Inicio de sesión sin contraseña - Correo electrónico y SMS', email_connector: 'Conector de correo electrónico', sms_connector: 'Conector de SMS', social_connectors: 'Conectores sociales', @@ -66,16 +65,11 @@ const quota_table = { hipaa_or_baa_report: 'Informe HIPAA/BAA (Próximamente)', }, developers_and_platform: { - /** UNTRANSLATED */ - title: 'Developers and platform', - /** UNTRANSLATED */ + title: 'Desarrolladores y plataforma', hooks: 'Webhooks', - /** UNTRANSLATED */ - audit_logs_retention: 'Audit logs retention', - /** UNTRANSLATED */ - jwt_claims: 'JWT claims', - /** UNTRANSLATED */ - tenant_members: 'Tenant members', + audit_logs_retention: 'Retención de registros de auditoría', + jwt_claims: 'Reclamos JWT', + tenant_members: 'Miembros del inquilino', }, unlimited: 'Ilimitado', contact: 'Contacto', @@ -97,17 +91,15 @@ const quota_table = { 'Todo tipo de tokens emitidos por Logto, incluyendo tokens de acceso, tokens de actualización, etc.', mao_tip: 'MAO (Organización activa mensual) significa la cantidad de organizaciones únicas que tienen al menos un MAU (usuario activo mensual) en un ciclo de facturación.', - /** UNTRANSLATED */ third_party_tip: - 'Use Logto as your OIDC identity provider for third-party app sign-ins and permission grants.', + 'Utilice Logto como su proveedor de identidades OIDC para iniciar sesión en aplicaciones de terceros y otorgar permisos.', included: 'incluido{{value, number}}', included_mao: '{{value, number}} MAO incluido', extra_quota_price: 'Luego ${{value, number}} por mes / cada uno después', per_month_each: '${{value, number}} por mes / cada uno', extra_mao_price: 'Luego ${{value, number}} por MAO', per_month: '${{value, number}} por mes', - /** UNTRANSLATED */ - per_member: 'Then ${{value, number}} per member', + per_member: 'Luego ${{value, number}} por miembro', }; export default Object.freeze(quota_table); diff --git a/packages/phrases/src/locales/es/translation/admin-console/tabs.ts b/packages/phrases/src/locales/es/translation/admin-console/tabs.ts index 81e526eeb79..d61ba42916d 100644 --- a/packages/phrases/src/locales/es/translation/admin-console/tabs.ts +++ b/packages/phrases/src/locales/es/translation/admin-console/tabs.ts @@ -14,8 +14,7 @@ const tabs = { docs: 'Documentos', tenant_settings: 'Configuraciones del inquilino', mfa: 'Autenticación multifactor', - /** UNTRANSLATED */ - customize_jwt: 'Custom JWT', + customize_jwt: 'JWT personalizado', signing_keys: 'Claves de firma', organization_template: 'Plantilla de organización', }; diff --git a/packages/phrases/src/locales/es/translation/admin-console/upsell/index.ts b/packages/phrases/src/locales/es/translation/admin-console/upsell/index.ts index aa23183184d..da8342c52ae 100644 --- a/packages/phrases/src/locales/es/translation/admin-console/upsell/index.ts +++ b/packages/phrases/src/locales/es/translation/admin-console/upsell/index.ts @@ -35,8 +35,7 @@ const upsell = { api_resource: 'Recurso de API', machine_to_machine: 'aplicación de máquina a máquina', tokens: '{{limit}}M tokens', - /** UNTRANSLATED */ - tenant_member: 'tenant member', + tenant_member: 'miembro del tenant', }, charge_notification_for_quota_limit: 'Has superado tu límite de cuota de {{item}}. Logto agregará cargos por el uso más allá de tu límite de cuota. La facturación comenzará el día en que se lance el nuevo diseño de precios del complemento. Más información', diff --git a/packages/phrases/src/locales/es/translation/admin-console/upsell/paywall.ts b/packages/phrases/src/locales/es/translation/admin-console/upsell/paywall.ts index 10f81da3845..14c7569e248 100644 --- a/packages/phrases/src/locales/es/translation/admin-console/upsell/paywall.ts +++ b/packages/phrases/src/locales/es/translation/admin-console/upsell/paywall.ts @@ -52,24 +52,18 @@ const paywall = { mfa: 'Desbloquea MFA para verificar la seguridad al actualizar a un plan pago. No dudes en contactarnos si necesitas ayuda.', organizations: 'Desbloquea las organizaciones al actualizar a un plan pago. No dudes en contactarnos si necesitas ayuda.', - /** UNTRANSLATED */ third_party_apps: - 'Unlock Logto as IdP for third-party apps by upgrading to a paid plan. For any assistance, feel free to contact us.', - /** UNTRANSLATED */ + 'Desbloquea Logto como proveedor de identidades para aplicaciones de terceros al actualizar a un plan de pago. Para cualquier asistencia, no dudes en contactarnos.', sso_connectors: - 'Unlock enterprise sso by upgrading to a paid plan. For any assistance, feel free to contact us.', - /** UNTRANSLATED */ + 'Desbloquea el SSO empresarial al actualizar a un plan de pago. Para cualquier asistencia, no dudes en contactarnos.', tenant_members: - 'Unlock collaboration feature by upgrading to a paid plan. For any assistance, feel free to contact us.', - /** UNTRANSLATED */ + 'Desbloquea la función de colaboración al actualizar a un plan de pago. Para cualquier asistencia, no dudes en contactarnos.', tenant_members_dev_plan: - "You've reached your {{limit}}-member limit. Release a member or revoke a pending invitation to add someone new. Need more seats? Feel free to contact us.", + 'Has alcanzado tu límite de {{limit}} miembros. Libera a un miembro o revoca una invitación pendiente para agregar a alguien nuevo. ¿Necesitas más puestos? No dudes en contactarnos.', custom_jwt: { - /** UNTRANSLATED */ - title: 'Add custom claims', - /** UNTRANSLATED */ + title: 'Agregar reclamaciones personalizadas', description: - "Upgrade to a paid plan for custom JWT functionality and premium benefits. Don't hesitate to contact us if you have any questions.", + 'Actualiza a un plan de pago para obtener funcionalidades personalizadas de JWT y beneficios premium. No dudes en contactarnos si tienes alguna pregunta.', }, }; diff --git a/packages/phrases/src/locales/fr/errors/jwt-customizer.ts b/packages/phrases/src/locales/fr/errors/jwt-customizer.ts index c7c5c1e2af9..432027acd40 100644 --- a/packages/phrases/src/locales/fr/errors/jwt-customizer.ts +++ b/packages/phrases/src/locales/fr/errors/jwt-customizer.ts @@ -1,8 +1,8 @@ const jwt_customizer = { - /** UNTRANSLATED */ - general: 'An error occurred while customizing the JWT token. Please try again later.', - /** UNTRANSLATED */ - can_not_create_for_admin_tenant: 'Cannot create a JWT token customizer for the admin tenant.', + general: + "Une erreur s'est produite lors de la personnalisation du jeton JWT. Veuillez réessayer ultérieurement.", + can_not_create_for_admin_tenant: + 'Impossible de créer un personnaliseur de jeton JWT pour le locataire administratif.', }; export default Object.freeze(jwt_customizer); diff --git a/packages/phrases/src/locales/fr/translation/admin-console/errors.ts b/packages/phrases/src/locales/fr/translation/admin-console/errors.ts index 8b03560305c..658312c93e5 100644 --- a/packages/phrases/src/locales/fr/translation/admin-console/errors.ts +++ b/packages/phrases/src/locales/fr/translation/admin-console/errors.ts @@ -7,8 +7,7 @@ const errors = { invalid_uri_format: "Format d'URI non valide", invalid_origin_format: "Format d'origine URI non valide", invalid_json_format: 'Format JSON non valide', - /** UNTRANSLATED */ - invalid_regex: 'Invalid regular expression', + invalid_regex: 'Expression régulière non valide', invalid_error_message_format: "Le format du message d'erreur n'est pas valide.", required_field_missing: 'Veuillez saisir {{field}}', required_field_missing_plural: 'Vous devez entrer au moins un {{field}}.', diff --git a/packages/phrases/src/locales/fr/translation/admin-console/general.ts b/packages/phrases/src/locales/fr/translation/admin-console/general.ts index cdcd1c2cee7..f610dad3cd0 100644 --- a/packages/phrases/src/locales/fr/translation/admin-console/general.ts +++ b/packages/phrases/src/locales/fr/translation/admin-console/general.ts @@ -25,11 +25,9 @@ const general = { customize: 'Personnaliser', enable: 'Activer', reminder: 'Rappel', - /** UNTRANSLATED */ - edit: 'Edit', + edit: 'Éditer', delete: 'Supprimer', - /** UNTRANSLATED */ - deleted: 'Deleted', + deleted: 'Supprimé', more_options: "PLUS D'OPTIONS", close: 'Fermer', copy: 'Copier', @@ -59,8 +57,7 @@ const general = { demo: 'Démo', unnamed: 'Sans nom', view: 'Vue', - /** UNTRANSLATED */ - open: 'Open', + open: 'Ouvrir', hide: 'Cacher', unknown_error: 'Erreur inconnue, veuillez réessayer ultérieurement.', select: 'Sélectionner', @@ -72,8 +69,7 @@ const general = { edit_field: 'Modifier {{field}}', delete_field: 'Supprimer {{field}}', coming_soon: 'Bientôt disponible', - /** UNTRANSLATED */ - or: 'Or', + or: 'Ou', }; export default Object.freeze(general); diff --git a/packages/phrases/src/locales/fr/translation/admin-console/jwt-claims.ts b/packages/phrases/src/locales/fr/translation/admin-console/jwt-claims.ts index f0d189ab412..b74b2664596 100644 --- a/packages/phrases/src/locales/fr/translation/admin-console/jwt-claims.ts +++ b/packages/phrases/src/locales/fr/translation/admin-console/jwt-claims.ts @@ -1,98 +1,66 @@ const jwt_claims = { - /** UNTRANSLATED */ - title: 'Custom JWT', - /** UNTRANSLATED */ + title: 'JWT personnalisé', description: - 'Set up custom JWT claims to include in the access token. These claims can be used to pass additional information to your application.', + "Configurer des revendications JWT personnalisées à inclure dans le jeton d'accès. Ces revendications peuvent être utilisées pour transmettre des informations supplémentaires à votre application.", user_jwt: { - /** UNTRANSLATED */ - card_title: 'For user', - /** UNTRANSLATED */ - card_field: 'User access token', - /** UNTRANSLATED */ - card_description: 'Add user-specific data during access token issuance.', - /** UNTRANSLATED */ - for: 'for user', + card_title: "Pour l'utilisateur", + card_field: "Jeton d'accès utilisateur", + card_description: + "Ajouter des données spécifiques à l'utilisateur lors de l'émission du jeton d'accès.", + for: "pour l'utilisateur", }, machine_to_machine_jwt: { - /** UNTRANSLATED */ - card_title: 'For M2M', - /** UNTRANSLATED */ - card_field: 'Machine-to-machine token', - /** UNTRANSLATED */ - card_description: 'Add extra data during machine-to-machine token issuance.', - /** UNTRANSLATED */ - for: 'for M2M', + card_title: 'Pour M2M', + card_field: 'Jeton machine-à-machine', + card_description: + "Ajouter des données supplémentaires lors de l'émission du jeton machine-à-machine.", + for: 'pour M2M', }, - /** UNTRANSLATED */ - code_editor_title: 'Customize the {{token}} claims', - /** UNTRANSLATED */ - custom_jwt_create_button: 'Add custom claims', - /** UNTRANSLATED */ - custom_jwt_item: 'Custom claims {{for}}', - /** UNTRANSLATED */ - delete_modal_title: 'Delete custom claims', - /** UNTRANSLATED */ - delete_modal_content: 'Are you sure you want to delete the custom claims?', - /** UNTRANSLATED */ - clear: 'Clear', - /** UNTRANSLATED */ - cleared: 'Cleared', - /** UNTRANSLATED */ - restore: 'Restore defaults', - /** UNTRANSLATED */ - restored: 'Restored', - /** UNTRANSLATED */ - data_source_tab: 'Data source', - /** UNTRANSLATED */ - test_tab: 'Test context', - /** UNTRANSLATED */ - jwt_claims_description: 'Default claims are auto-included in the JWT and cannot be overridden.', + code_editor_title: 'Personnalisez les revendications {{token}}', + custom_jwt_create_button: 'Ajouter des revendications personnalisées', + custom_jwt_item: 'Revendications personnalisées {{for}}', + delete_modal_title: 'Supprimer les revendications personnalisées', + delete_modal_content: 'Êtes-vous sûr de vouloir supprimer les revendications personnalisées ?', + clear: 'Effacer', + cleared: 'Effacé', + restore: 'Restaurer les paramètres par défaut', + restored: 'Restauré', + data_source_tab: 'Source de données', + test_tab: 'Contexte de test', + jwt_claims_description: + 'Les revendications par défaut sont automatiquement incluses dans le JWT et ne peuvent pas être remplacées.', user_data: { - /** UNTRANSLATED */ - title: 'User data', - /** UNTRANSLATED */ - subtitle: 'Use `data.user` input parameter to provide vital user info.', + title: 'Données utilisateur', + subtitle: + "Utilisez le paramètre d'entrée `data.user` pour fournir des informations vitales sur l'utilisateur.", }, token_data: { - /** UNTRANSLATED */ - title: 'Token data', - /** UNTRANSLATED */ - subtitle: 'Use `token` input parameter for current access token payload. ', + title: 'Données du jeton', + subtitle: "Utilisez le paramètre d'entrée `token` pour le payload du jeton d'accès actuel. ", }, fetch_external_data: { - /** UNTRANSLATED */ - title: 'Fetch external data', - /** UNTRANSLATED */ - subtitle: 'Incorporate data from your external APIs directly into claims.', - /** UNTRANSLATED */ + title: 'Récupérer des données externes', + subtitle: + 'Incorporer des données provenant directement de vos API externes dans les revendications.', description: - 'Use the `fetch` function to call your external APIs and include the data in your custom claims. Example: ', + 'Utilisez la fonction `fetch` pour appeler vos API externes et inclure les données dans vos revendications personnalisées. Exemple : ', }, environment_variables: { - /** UNTRANSLATED */ - title: 'Set environment variables', - /** UNTRANSLATED */ - subtitle: 'Use environment variables to store sensitive information.', - /** UNTRANSLATED */ - input_field_title: 'Add environment variables', - /** UNTRANSLATED */ - sample_code: 'Accessing environment variables in your custom JWT claims handler. Example: ', + title: "Définir des variables d'environnement", + subtitle: "Utilisez des variables d'environnement pour stocker des informations sensibles.", + input_field_title: "Ajouter des variables d'environnement", + sample_code: + "Accès aux variables d'environnement dans votre gestionnaire de revendications JWT personnalisées. Exemple : ", }, - /** UNTRANSLATED */ jwt_claims_hint: - 'Limit custom claims to under 50KB. Default JWT claims are automatically included in the token and can not be overridden.', + 'Limitez les revendications personnalisées à moins de 50 Ko. Les revendications JWT par défaut sont automatiquement incluses dans le jeton et ne peuvent pas être remplacées.', tester: { - /** UNTRANSLATED */ - subtitle: 'Adjust mock token and user data for testing.', - /** UNTRANSLATED */ - run_button: 'Run test', - /** UNTRANSLATED */ - result_title: 'Test result', + subtitle: 'Ajustez le jeton et les données utilisateur simulés pour les tests.', + run_button: 'Exécuter le test', + result_title: 'Résultat du test', }, form_error: { - /** UNTRANSLATED */ - invalid_json: 'Invalid JSON format', + invalid_json: 'Format JSON invalide', }, }; diff --git a/packages/phrases/src/locales/fr/translation/admin-console/subscription/quota-item.ts b/packages/phrases/src/locales/fr/translation/admin-console/subscription/quota-item.ts index 169a845f6ea..44ce7baf295 100644 --- a/packages/phrases/src/locales/fr/translation/admin-console/subscription/quota-item.ts +++ b/packages/phrases/src/locales/fr/translation/admin-console/subscription/quota-item.ts @@ -27,22 +27,17 @@ const quota_item = { not_eligible: 'Supprimez vos applications', }, machine_to_machine_limit: { - name: 'Machine to machine', + name: 'Machine à machine', limited: '{{count, number}} application machine à machine', limited_other: '{{count, number}} applications machine à machine', unlimited: 'Illimité applications machine à machine', not_eligible: 'Supprimez vos applications machine à machine', }, third_party_applications_limit: { - /** UNTRANSLATED */ - name: 'Third-party apps', - /** UNTRANSLATED */ - limited: '{{count, number}} third-party app', - /** UNTRANSLATED */ - limited_other: '{{count, number}} third-party apps', - /** UNTRANSLATED */ + name: 'Applications tierces', + limited: '{{count, number}} application tierce', + limited_other: '{{count, number}} applications tierces', unlimited: 'Unlimited third-party apps', - /** UNTRANSLATED */ not_eligible: 'Remove your third-party apps', }, resources_limit: { @@ -99,9 +94,9 @@ const quota_item = { not_eligible: 'Supprimez vos rôles', }, machine_to_machine_roles_limit: { - name: 'Machine to machine roles', - limited: '{{count, number}} machine to machine role', - limited_other: '{{count, number}} machine to machine roles', + name: 'Roles Machine à machine', + limited: '{{count, number}} rôle machine à machine', + limited_other: '{{count, number}} rôles machine à machine', unlimited: 'Unlimited machine to machine roles', not_eligible: 'Remove your machine to machine roles', }, @@ -120,9 +115,9 @@ const quota_item = { not_eligible: 'Supprimez vos webhooks', }, organizations_enabled: { - name: 'Organizations', - limited: 'Organizations', - unlimited: 'Organizations', + name: 'Organisations', + limited: 'Organisations', + unlimited: 'Organisations', not_eligible: 'Remove your organizations', }, audit_logs_retention_days: { @@ -152,25 +147,16 @@ const quota_item = { not_eligible: 'Supprimez votre SSO Entreprise', }, tenant_members_limit: { - /** UNTRANSLATED */ - name: 'Tenant members', - /** UNTRANSLATED */ - limited: '{{count, number}} tenant member', - /** UNTRANSLATED */ - limited_other: '{{count, number}} tenant members', - /** UNTRANSLATED */ + name: 'Membres du locataires', + limited: '{{count, number}} membre du locataire', + limited_other: '{{count, number}} membres du locataire', unlimited: 'Unlimited tenant members', - /** UNTRANSLATED */ not_eligible: 'Remove your tenant members', }, custom_jwt_enabled: { - /** UNTRANSLATED */ - name: 'Custom JWT', - /** UNTRANSLATED */ + name: 'JWT personnalisé', limited: 'Custom JWT', - /** UNTRANSLATED */ unlimited: 'Custom JWT', - /** UNTRANSLATED */ not_eligible: 'Remove your JWT claims customizer', }, }; diff --git a/packages/phrases/src/locales/fr/translation/admin-console/subscription/quota-table.ts b/packages/phrases/src/locales/fr/translation/admin-console/subscription/quota-table.ts index 954abbde7b5..f7bdd9df09a 100644 --- a/packages/phrases/src/locales/fr/translation/admin-console/subscription/quota-table.ts +++ b/packages/phrases/src/locales/fr/translation/admin-console/subscription/quota-table.ts @@ -9,8 +9,7 @@ const quota_table = { title: 'Applications', total: 'Total des applications', m2m: 'Machine-à-machine', - /** UNTRANSLATED */ - third_party: 'Third-party apps', + third_party: 'Applications tierces', }, resource: { title: 'Ressources API', @@ -66,16 +65,11 @@ const quota_table = { hipaa_or_baa_report: 'Rapport HIPAA/BAA', }, developers_and_platform: { - /** UNTRANSLATED */ - title: 'Developers and platform', - /** UNTRANSLATED */ + title: 'Développeurs et plateforme', hooks: 'Webhooks', - /** UNTRANSLATED */ - audit_logs_retention: 'Audit logs retention', - /** UNTRANSLATED */ - jwt_claims: 'JWT claims', - /** UNTRANSLATED */ - tenant_members: 'Tenant members', + audit_logs_retention: "Conservation des journaux d'audit", + jwt_claims: 'Revendications JWT', + tenant_members: 'Membres du locataire', }, unlimited: 'Illimité', contact: 'Contact', @@ -83,7 +77,7 @@ const quota_table = { days_one: '{{count, number}} jour', days_other: '{{count, number}} jours', add_on: 'Module complémentaire', - tier: 'Niveau{{value, number}} : ', + tier: 'Niveau{{value, number}} :', paid_token_limit_tip: "Logto facturera des frais pour les fonctionnalités qui dépassent votre limite de quota. Vous pouvez l'utiliser gratuitement jusqu'à ce que nous commencions à facturer vers le deuxième trimestre 2024. Si vous avez besoin de plus de jetons, veuillez nous contacter. Par défaut, nous facturons 80 $ par mois pour chaque million de jetons.", paid_quota_limit_tip: @@ -97,17 +91,15 @@ const quota_table = { "Tous types de jetons émis par Logto, y compris les jetons d'accès, les jetons de rafraîchissement, etc.", mao_tip: "MAO (Organisation active mensuelle) désigne le nombre d'organisations uniques ayant au moins un MAU (utilisateur actif mensuel) au cours d'un cycle de facturation.", - /** UNTRANSLATED */ third_party_tip: - 'Use Logto as your OIDC identity provider for third-party app sign-ins and permission grants.', + "Utilisez Logto comme votre fournisseur d'identité OIDC pour les connexions et les autorisations des applications tierces.", included: '{{value, number}} inclus', included_mao: '{{value, number}} MAO inclus', extra_quota_price: 'Ensuite ${{value, number}} par mois / chacun après', per_month_each: '${{value, number}} par mois / chacun', extra_mao_price: 'Ensuite ${{value, number}} par MAO', per_month: '${{value, number}} par mois', - /** UNTRANSLATED */ - per_member: 'Then ${{value, number}} per member', + per_member: 'Ensuite ${{value, number}} par membre', }; export default Object.freeze(quota_table); diff --git a/packages/phrases/src/locales/fr/translation/admin-console/tabs.ts b/packages/phrases/src/locales/fr/translation/admin-console/tabs.ts index 8d396d70670..c65853c8210 100644 --- a/packages/phrases/src/locales/fr/translation/admin-console/tabs.ts +++ b/packages/phrases/src/locales/fr/translation/admin-console/tabs.ts @@ -14,8 +14,7 @@ const tabs = { docs: 'Documentation', tenant_settings: 'Paramètres du locataire', mfa: 'Authentification multi-facteur', - /** UNTRANSLATED */ - customize_jwt: 'Custom JWT', + customize_jwt: 'Personnaliser JWT', signing_keys: 'Clés de signature', organization_template: "Modèle d'organisation", }; diff --git a/packages/phrases/src/locales/fr/translation/admin-console/upsell/index.ts b/packages/phrases/src/locales/fr/translation/admin-console/upsell/index.ts index 765cea9c377..81030f7ca0d 100644 --- a/packages/phrases/src/locales/fr/translation/admin-console/upsell/index.ts +++ b/packages/phrases/src/locales/fr/translation/admin-console/upsell/index.ts @@ -35,8 +35,7 @@ const upsell = { api_resource: 'Ressource API', machine_to_machine: 'application machine à machine', tokens: '{{limit}}M jetons', - /** UNTRANSLATED */ - tenant_member: 'tenant member', + tenant_member: 'membre du locataire', }, charge_notification_for_quota_limit: "Vous avez dépassé votre limite de quota {{item}}. Logto ajoutera des frais pour l'utilisation au-delà de votre limite de quota. La facturation commencera le jour de la publication du nouveau design tarifaire de l'extension. En savoir plus", diff --git a/packages/phrases/src/locales/fr/translation/admin-console/upsell/paywall.ts b/packages/phrases/src/locales/fr/translation/admin-console/upsell/paywall.ts index cdd0b151df1..2b9fb9e37ee 100644 --- a/packages/phrases/src/locales/fr/translation/admin-console/upsell/paywall.ts +++ b/packages/phrases/src/locales/fr/translation/admin-console/upsell/paywall.ts @@ -52,22 +52,16 @@ const paywall = { mfa: "Déverrouillez MFA pour vérifier la sécurité en passant à un plan payant. N'hésitez pas à nous contacter si vous avez besoin d'aide.", organizations: "Débloquez les organisations en passant à un plan payant. N’hésitez pas à nous contacter si vous avez besoin d'aide.", - /** UNTRANSLATED */ third_party_apps: 'Unlock Logto as IdP for third-party apps by upgrading to a paid plan. For any assistance, feel free to contact us.', - /** UNTRANSLATED */ sso_connectors: 'Unlock enterprise sso by upgrading to a paid plan. For any assistance, feel free to contact us.', - /** UNTRANSLATED */ tenant_members: 'Unlock collaboration feature by upgrading to a paid plan. For any assistance, feel free to contact us.', - /** UNTRANSLATED */ tenant_members_dev_plan: "You've reached your {{limit}}-member limit. Release a member or revoke a pending invitation to add someone new. Need more seats? Feel free to contact us.", custom_jwt: { - /** UNTRANSLATED */ title: 'Add custom claims', - /** UNTRANSLATED */ description: "Upgrade to a paid plan for custom JWT functionality and premium benefits. Don't hesitate to contact us if you have any questions.", }, diff --git a/packages/phrases/src/locales/it/errors/jwt-customizer.ts b/packages/phrases/src/locales/it/errors/jwt-customizer.ts index c7c5c1e2af9..edc04df8dea 100644 --- a/packages/phrases/src/locales/it/errors/jwt-customizer.ts +++ b/packages/phrases/src/locales/it/errors/jwt-customizer.ts @@ -1,8 +1,8 @@ const jwt_customizer = { - /** UNTRANSLATED */ - general: 'An error occurred while customizing the JWT token. Please try again later.', - /** UNTRANSLATED */ - can_not_create_for_admin_tenant: 'Cannot create a JWT token customizer for the admin tenant.', + general: + 'Si è verificato un errore durante la personalizzazione del token JWT. Si prega di riprovare più tardi.', + can_not_create_for_admin_tenant: + "Impossibile creare un personalizzatore di token JWT per l'amministratore del locatario.", }; export default Object.freeze(jwt_customizer); diff --git a/packages/phrases/src/locales/it/translation/admin-console/errors.ts b/packages/phrases/src/locales/it/translation/admin-console/errors.ts index 31df18936e8..61a95b95b9f 100644 --- a/packages/phrases/src/locales/it/translation/admin-console/errors.ts +++ b/packages/phrases/src/locales/it/translation/admin-console/errors.ts @@ -7,8 +7,7 @@ const errors = { invalid_uri_format: 'Formato URI non valido', invalid_origin_format: 'Formato origine URI non valido', invalid_json_format: 'Formato JSON non valido', - /** UNTRANSLATED */ - invalid_regex: 'Invalid regular expression', + invalid_regex: 'Espressione regolare non valida', invalid_error_message_format: 'Il formato del messaggio di errore non è valido.', required_field_missing: 'Inserisci {{field}}', required_field_missing_plural: 'Devi inserire almeno un {{field}}', diff --git a/packages/phrases/src/locales/it/translation/admin-console/general.ts b/packages/phrases/src/locales/it/translation/admin-console/general.ts index b4715e915b9..690332d6458 100644 --- a/packages/phrases/src/locales/it/translation/admin-console/general.ts +++ b/packages/phrases/src/locales/it/translation/admin-console/general.ts @@ -25,11 +25,9 @@ const general = { customize: 'Personalizza', enable: 'Abilita', reminder: 'Promemoria', - /** UNTRANSLATED */ - edit: 'Edit', + edit: 'Modifica', delete: 'Elimina', - /** UNTRANSLATED */ - deleted: 'Deleted', + deleted: 'Eliminato', more_options: 'PIÙ OPZIONI', close: 'Chiudi', copy: 'Copia', @@ -59,8 +57,7 @@ const general = { demo: 'Demo', unnamed: 'Senza nome', view: 'Vista', - /** UNTRANSLATED */ - open: 'Open', + open: 'Apri', hide: 'Nascondi', unknown_error: 'Errore sconosciuto, riprova più tardi.', select: 'Seleziona', @@ -72,8 +69,7 @@ const general = { edit_field: 'Modifica {{field}}', delete_field: 'Elimina {{field}}', coming_soon: 'Prossimamente', - /** UNTRANSLATED */ - or: 'Or', + or: 'O', }; export default Object.freeze(general); diff --git a/packages/phrases/src/locales/it/translation/admin-console/jwt-claims.ts b/packages/phrases/src/locales/it/translation/admin-console/jwt-claims.ts index f0d189ab412..3dd3529bf59 100644 --- a/packages/phrases/src/locales/it/translation/admin-console/jwt-claims.ts +++ b/packages/phrases/src/locales/it/translation/admin-console/jwt-claims.ts @@ -1,98 +1,65 @@ const jwt_claims = { - /** UNTRANSLATED */ - title: 'Custom JWT', - /** UNTRANSLATED */ + title: 'JWT personalizzato', description: - 'Set up custom JWT claims to include in the access token. These claims can be used to pass additional information to your application.', + 'Imposta richieste JWT personalizzate da includere nel token di accesso. Queste richieste possono essere utilizzate per passare informazioni aggiuntive alla tua applicazione.', user_jwt: { - /** UNTRANSLATED */ - card_title: 'For user', - /** UNTRANSLATED */ - card_field: 'User access token', - /** UNTRANSLATED */ - card_description: 'Add user-specific data during access token issuance.', - /** UNTRANSLATED */ - for: 'for user', + card_title: 'Per utente', + card_field: 'Token di accesso utente', + card_description: + "Aggiungi dati specifici dell'utente durante l'emissione del token di accesso.", + for: 'per utente', }, machine_to_machine_jwt: { - /** UNTRANSLATED */ - card_title: 'For M2M', - /** UNTRANSLATED */ - card_field: 'Machine-to-machine token', - /** UNTRANSLATED */ - card_description: 'Add extra data during machine-to-machine token issuance.', - /** UNTRANSLATED */ - for: 'for M2M', + card_title: 'Per M2M', + card_field: 'Token da macchina a macchina', + card_description: "Aggiungi dati extra durante l'emissione del token da macchina a macchina.", + for: 'per M2M', }, - /** UNTRANSLATED */ - code_editor_title: 'Customize the {{token}} claims', - /** UNTRANSLATED */ - custom_jwt_create_button: 'Add custom claims', - /** UNTRANSLATED */ - custom_jwt_item: 'Custom claims {{for}}', - /** UNTRANSLATED */ - delete_modal_title: 'Delete custom claims', - /** UNTRANSLATED */ - delete_modal_content: 'Are you sure you want to delete the custom claims?', - /** UNTRANSLATED */ - clear: 'Clear', - /** UNTRANSLATED */ - cleared: 'Cleared', - /** UNTRANSLATED */ - restore: 'Restore defaults', - /** UNTRANSLATED */ - restored: 'Restored', - /** UNTRANSLATED */ - data_source_tab: 'Data source', - /** UNTRANSLATED */ - test_tab: 'Test context', - /** UNTRANSLATED */ - jwt_claims_description: 'Default claims are auto-included in the JWT and cannot be overridden.', + code_editor_title: 'Personalizza le richieste {{token}}', + custom_jwt_create_button: 'Aggiungi richieste personalizzate', + custom_jwt_item: 'Richieste personalizzate {{for}}', + delete_modal_title: 'Elimina richieste personalizzate', + delete_modal_content: 'Sei sicuro di voler eliminare le richieste personalizzate?', + clear: 'Pulisci', + cleared: 'Pulito', + restore: 'Ripristina predefiniti', + restored: 'Ripristinato', + data_source_tab: 'Sorgente dati', + test_tab: 'Contesto di test', + jwt_claims_description: + 'Le richieste predefinite sono incluse automaticamente nel JWT e non possono essere sovrascritte.', user_data: { - /** UNTRANSLATED */ - title: 'User data', - /** UNTRANSLATED */ - subtitle: 'Use `data.user` input parameter to provide vital user info.', + title: 'Dati utente', + subtitle: + "Utilizza il parametro di input `data.user` per fornire informazioni vitali sull'utente.", }, token_data: { - /** UNTRANSLATED */ - title: 'Token data', - /** UNTRANSLATED */ - subtitle: 'Use `token` input parameter for current access token payload. ', + title: 'Dati token', + subtitle: + 'Utilizza il parametro di input `token` per il payload corrente del token di accesso. ', }, fetch_external_data: { - /** UNTRANSLATED */ - title: 'Fetch external data', - /** UNTRANSLATED */ - subtitle: 'Incorporate data from your external APIs directly into claims.', - /** UNTRANSLATED */ + title: 'Recupera dati esterni', + subtitle: 'Incorpora dati direttamente dai tuoi API esterni nelle richieste.', description: - 'Use the `fetch` function to call your external APIs and include the data in your custom claims. Example: ', + 'Utilizza la funzione `fetch` per chiamare le tue API esterne e includere i dati nelle richieste personalizzate. Esempio: ', }, environment_variables: { - /** UNTRANSLATED */ - title: 'Set environment variables', - /** UNTRANSLATED */ - subtitle: 'Use environment variables to store sensitive information.', - /** UNTRANSLATED */ - input_field_title: 'Add environment variables', - /** UNTRANSLATED */ - sample_code: 'Accessing environment variables in your custom JWT claims handler. Example: ', + title: "Imposta variabili d'ambiente", + subtitle: "Utilizza variabili d'ambiente per memorizzare informazioni sensibili.", + input_field_title: "Aggiungi variabili d'ambiente", + sample_code: + "Accesso alle variabili d'ambiente nel gestore delle richieste JWT personalizzate. Esempio: ", }, - /** UNTRANSLATED */ jwt_claims_hint: - 'Limit custom claims to under 50KB. Default JWT claims are automatically included in the token and can not be overridden.', + 'Limita le richieste personalizzate a meno di 50KB. Le richieste JWT predefinite sono incluse automaticamente nel token e non possono essere sovrascritte.', tester: { - /** UNTRANSLATED */ - subtitle: 'Adjust mock token and user data for testing.', - /** UNTRANSLATED */ - run_button: 'Run test', - /** UNTRANSLATED */ - result_title: 'Test result', + subtitle: 'Regola il token fittizio e i dati utente per il test.', + run_button: 'Esegui test', + result_title: 'Risultato del test', }, form_error: { - /** UNTRANSLATED */ - invalid_json: 'Invalid JSON format', + invalid_json: 'Formato JSON non valido', }, }; diff --git a/packages/phrases/src/locales/it/translation/admin-console/subscription/quota-item.ts b/packages/phrases/src/locales/it/translation/admin-console/subscription/quota-item.ts index 8e0c9ba0858..3886f1115c9 100644 --- a/packages/phrases/src/locales/it/translation/admin-console/subscription/quota-item.ts +++ b/packages/phrases/src/locales/it/translation/admin-console/subscription/quota-item.ts @@ -34,16 +34,11 @@ const quota_item = { not_eligible: 'Rimuovi le tue applicazioni Machine-to-Machine', }, third_party_applications_limit: { - /** UNTRANSLATED */ - name: 'Third-party apps', - /** UNTRANSLATED */ - limited: '{{count, number}} third-party app', - /** UNTRANSLATED */ - limited_other: '{{count, number}} third-party apps', - /** UNTRANSLATED */ - unlimited: 'Unlimited third-party apps', - /** UNTRANSLATED */ - not_eligible: 'Remove your third-party apps', + name: 'App di terze parti', + limited: '{{count, number}} app di terze parti', + limited_other: '{{count, number}} app di terze parti', + unlimited: 'App di terze parti illimitate', + not_eligible: 'Rimuovi le tue app di terze parti', }, resources_limit: { name: 'Risorse API', @@ -152,26 +147,17 @@ const quota_item = { not_eligible: 'Rimuovi il tuo SSO aziendale', }, tenant_members_limit: { - /** UNTRANSLATED */ - name: 'Tenant members', - /** UNTRANSLATED */ - limited: '{{count, number}} tenant member', - /** UNTRANSLATED */ - limited_other: '{{count, number}} tenant members', - /** UNTRANSLATED */ - unlimited: 'Unlimited tenant members', - /** UNTRANSLATED */ - not_eligible: 'Remove your tenant members', + name: 'Membri Tenant', + limited: '{{count, number}} membro Tenant', + limited_other: '{{count, number}} membri Tenant', + unlimited: 'Membri Tenant illimitati', + not_eligible: 'Rimuovi i tuoi membri Tenant', }, custom_jwt_enabled: { - /** UNTRANSLATED */ - name: 'Custom JWT', - /** UNTRANSLATED */ - limited: 'Custom JWT', - /** UNTRANSLATED */ - unlimited: 'Custom JWT', - /** UNTRANSLATED */ - not_eligible: 'Remove your JWT claims customizer', + name: 'JWT personalizzato', + limited: 'JWT personalizzato', + unlimited: 'JWT personalizzato', + not_eligible: 'Rimuovi il tuo personalizzatore di claim JWT', }, }; diff --git a/packages/phrases/src/locales/it/translation/admin-console/subscription/quota-table.ts b/packages/phrases/src/locales/it/translation/admin-console/subscription/quota-table.ts index de2ed791124..e13548fbfb9 100644 --- a/packages/phrases/src/locales/it/translation/admin-console/subscription/quota-table.ts +++ b/packages/phrases/src/locales/it/translation/admin-console/subscription/quota-table.ts @@ -9,8 +9,7 @@ const quota_table = { title: 'Applicazioni', total: 'Totale applicazioni', m2m: 'Machine-to-machine', - /** UNTRANSLATED */ - third_party: 'Third-party apps', + third_party: 'App di terze parti', }, resource: { title: 'Risorse API', @@ -66,16 +65,11 @@ const quota_table = { hipaa_or_baa_report: 'Rapporto HIPAA/BAA', }, developers_and_platform: { - /** UNTRANSLATED */ - title: 'Developers and platform', - /** UNTRANSLATED */ + title: 'Sviluppatori e piattaforma', hooks: 'Webhooks', - /** UNTRANSLATED */ - audit_logs_retention: 'Audit logs retention', - /** UNTRANSLATED */ + audit_logs_retention: 'Conservazione dei log di audit', jwt_claims: 'JWT claims', - /** UNTRANSLATED */ - tenant_members: 'Tenant members', + tenant_members: 'Membri del tenant', }, unlimited: 'Illimitato', contact: 'Contatta', @@ -97,17 +91,15 @@ const quota_table = { 'Tutti i tipi di token emessi da Logto, inclusi token di accesso, token di aggiornamento, ecc.', mao_tip: 'MAO (Organizzazione attiva mensile) indica il numero di organizzazioni uniche che hanno almeno un MAU (utente attivo mensile) in un ciclo di fatturazione.', - /** UNTRANSLATED */ third_party_tip: - 'Use Logto as your OIDC identity provider for third-party app sign-ins and permission grants.', + "Usa Logto come provider di identità OIDC per l'accesso e il rilascio di permessi di app di terze parti.", included: '{{value, number}} incluso', included_mao: '{{value, number}} MAO inclusi', extra_quota_price: 'Quindi ${{value, number}} al mese / ognuno dopo', per_month_each: '${{value, number}} al mese / ognuno', extra_mao_price: 'Quindi ${{value, number}} per MAO', per_month: '${{value, number}} al mese', - /** UNTRANSLATED */ - per_member: 'Then ${{value, number}} per member', + per_member: 'Quindi ${{value, number}} per membro', }; export default Object.freeze(quota_table); diff --git a/packages/phrases/src/locales/it/translation/admin-console/tabs.ts b/packages/phrases/src/locales/it/translation/admin-console/tabs.ts index a8245f265ef..2988d354b89 100644 --- a/packages/phrases/src/locales/it/translation/admin-console/tabs.ts +++ b/packages/phrases/src/locales/it/translation/admin-console/tabs.ts @@ -14,8 +14,7 @@ const tabs = { docs: 'Documenti', tenant_settings: 'Impostazioni', mfa: 'Autenticazione multi-fattore', - /** UNTRANSLATED */ - customize_jwt: 'Custom JWT', + customize_jwt: 'JWT personalizzato', signing_keys: 'Chiavi di firma', organization_template: 'Modello di organizzazione', }; diff --git a/packages/phrases/src/locales/it/translation/admin-console/upsell/index.ts b/packages/phrases/src/locales/it/translation/admin-console/upsell/index.ts index 6644d8a6c88..942edf9b8ee 100644 --- a/packages/phrases/src/locales/it/translation/admin-console/upsell/index.ts +++ b/packages/phrases/src/locales/it/translation/admin-console/upsell/index.ts @@ -35,8 +35,7 @@ const upsell = { api_resource: 'Risorsa API', machine_to_machine: 'applicazione macchina-macchina', tokens: '{{limit}}M token', - /** UNTRANSLATED */ - tenant_member: 'tenant member', + tenant_member: 'membro del tenant', }, charge_notification_for_quota_limit: "Hai superato il limite di quota {{item}}. Logto aggiungerà addebiti per l'uso oltre il limite di quota. La fatturazione inizierà il giorno in cui verrà rilasciato il nuovo design dei prezzi dell'addon. Ulteriori informazioni", diff --git a/packages/phrases/src/locales/it/translation/admin-console/upsell/paywall.ts b/packages/phrases/src/locales/it/translation/admin-console/upsell/paywall.ts index 1d6d0a6f327..276854c8a1a 100644 --- a/packages/phrases/src/locales/it/translation/admin-console/upsell/paywall.ts +++ b/packages/phrases/src/locales/it/translation/admin-console/upsell/paywall.ts @@ -52,24 +52,18 @@ const paywall = { mfa: 'Sblocca MFA per verificare la sicurezza passando a un piano a pagamento. Non esitare a contattarci se hai bisogno di assistenza.', organizations: 'Sblocca le organizzazioni passando a un piano a pagamento. Non esitare a contattarci se hai bisogno di assistenza.', - /** UNTRANSLATED */ third_party_apps: - 'Unlock Logto as IdP for third-party apps by upgrading to a paid plan. For any assistance, feel free to contact us.', - /** UNTRANSLATED */ + 'Sblocca Logto come IdP per applicazioni di terze parti passando a un piano a pagamento. Per qualsiasi assistenza, non esitare a contattarci.', sso_connectors: - 'Unlock enterprise sso by upgrading to a paid plan. For any assistance, feel free to contact us.', - /** UNTRANSLATED */ + 'Sblocca SSO aziendale passando a un piano a pagamento. Per qualsiasi assistenza, non esitare a contattarci.', tenant_members: - 'Unlock collaboration feature by upgrading to a paid plan. For any assistance, feel free to contact us.', - /** UNTRANSLATED */ + 'Sblocca la funzionalità di collaborazione passando a un piano a pagamento. Per qualsiasi assistenza, non esitare a contattarci.', tenant_members_dev_plan: - "You've reached your {{limit}}-member limit. Release a member or revoke a pending invitation to add someone new. Need more seats? Feel free to contact us.", + 'Hai raggiunto il limite di {{limit}} membri. Rilascia un membro o revoca un invito in sospeso per aggiungerne uno nuovo. Hai bisogno di più posti? Non esitare a contattarci.', custom_jwt: { - /** UNTRANSLATED */ - title: 'Add custom claims', - /** UNTRANSLATED */ + title: 'Aggiungi reclami personalizzati', description: - "Upgrade to a paid plan for custom JWT functionality and premium benefits. Don't hesitate to contact us if you have any questions.", + 'Aggiorna a un piano a pagamento per la funzionalità JWT personalizzata e benefici premium. Non esitare a contattarci se hai domande.', }, }; diff --git a/packages/phrases/src/locales/ja/errors/jwt-customizer.ts b/packages/phrases/src/locales/ja/errors/jwt-customizer.ts index c7c5c1e2af9..e9daaace508 100644 --- a/packages/phrases/src/locales/ja/errors/jwt-customizer.ts +++ b/packages/phrases/src/locales/ja/errors/jwt-customizer.ts @@ -1,8 +1,6 @@ const jwt_customizer = { - /** UNTRANSLATED */ - general: 'An error occurred while customizing the JWT token. Please try again later.', - /** UNTRANSLATED */ - can_not_create_for_admin_tenant: 'Cannot create a JWT token customizer for the admin tenant.', + general: 'カスタマイズJWTトークン中にエラーが発生しました。後でもう一度お試しください。', + can_not_create_for_admin_tenant: '管理テナントのJWTトークンカスタマイザを作成できません。', }; export default Object.freeze(jwt_customizer); diff --git a/packages/phrases/src/locales/ja/translation/admin-console/errors.ts b/packages/phrases/src/locales/ja/translation/admin-console/errors.ts index 468d990e691..0eabe11351c 100644 --- a/packages/phrases/src/locales/ja/translation/admin-console/errors.ts +++ b/packages/phrases/src/locales/ja/translation/admin-console/errors.ts @@ -7,11 +7,10 @@ const errors = { invalid_uri_format: '無効なURI形式', invalid_origin_format: '無効なURIの起源の形式', invalid_json_format: '無効なJSON形式', - /** UNTRANSLATED */ - invalid_regex: 'Invalid regular expression', + invalid_regex: '無効な正規表現', invalid_error_message_format: 'エラーメッセージの形式が無効です。', - required_field_missing: '{{field}}を入力してください', - required_field_missing_plural: '少なくとも1つの{{field}}を入力する必要があります', + required_field_missing: "'{{field}}'を入力してください", + required_field_missing_plural: "少なくとも1つの'{{field}}'を入力する必要があります", more_details: '詳細を見る', username_pattern_error: 'ユーザー名には、文字、数字、またはアンダースコアしか含めることができず、数字で始めることはできません。', @@ -24,7 +23,7 @@ const errors = { '新しい内部ロールを作成しているため、Logtoによって禁止されています。 「#internal:」で始まらない別の名前を試してください。', should_be_an_integer: '整数である必要があります。', number_should_be_between_inclusive: - '{{min}}から{{max}}(両方含む)までの数値である必要があります。', + "'{{min}}'から'{{max}}'(両方含む)までの数値である必要があります。", }; export default Object.freeze(errors); diff --git a/packages/phrases/src/locales/ja/translation/admin-console/general.ts b/packages/phrases/src/locales/ja/translation/admin-console/general.ts index e86c03d46d0..961660d32f4 100644 --- a/packages/phrases/src/locales/ja/translation/admin-console/general.ts +++ b/packages/phrases/src/locales/ja/translation/admin-console/general.ts @@ -25,11 +25,9 @@ const general = { customize: 'カスタマイズする', enable: '有効にする', reminder: 'リマインダー', - /** UNTRANSLATED */ - edit: 'Edit', + edit: '編集', delete: '削除', - /** UNTRANSLATED */ - deleted: 'Deleted', + deleted: '削除済', more_options: 'その他のオプション', close: '閉じる', copy: 'コピーする', @@ -58,8 +56,7 @@ const general = { demo: 'デモ', unnamed: '名前がありません', view: '表示', - /** UNTRANSLATED */ - open: 'Open', + open: '開く', hide: '非表示', unknown_error: '不明なエラーが発生しました。後で再試行してください。', select: '選択する', @@ -71,8 +68,7 @@ const general = { edit_field: '{{field}}を編集', delete_field: '{{field}}を削除', coming_soon: '近日公開予定', - /** UNTRANSLATED */ - or: 'Or', + or: 'または', }; export default Object.freeze(general); diff --git a/packages/phrases/src/locales/ja/translation/admin-console/jwt-claims.ts b/packages/phrases/src/locales/ja/translation/admin-console/jwt-claims.ts index f0d189ab412..beca3aa8e6c 100644 --- a/packages/phrases/src/locales/ja/translation/admin-console/jwt-claims.ts +++ b/packages/phrases/src/locales/ja/translation/admin-console/jwt-claims.ts @@ -1,98 +1,59 @@ const jwt_claims = { - /** UNTRANSLATED */ - title: 'Custom JWT', - /** UNTRANSLATED */ + title: 'カスタムJWT', description: - 'Set up custom JWT claims to include in the access token. These claims can be used to pass additional information to your application.', + 'アクセストークンに含めるカスタムJWTクレームを設定します。これらのクレームを使用して、追加の情報をアプリケーションに渡すことができます。', user_jwt: { - /** UNTRANSLATED */ - card_title: 'For user', - /** UNTRANSLATED */ - card_field: 'User access token', - /** UNTRANSLATED */ - card_description: 'Add user-specific data during access token issuance.', - /** UNTRANSLATED */ - for: 'for user', + card_title: 'ユーザー向け', + card_field: 'ユーザーアクセストークン', + card_description: 'アクセストークン発行時にユーザー固有のデータを追加します。', + for: 'ユーザー向け', }, machine_to_machine_jwt: { - /** UNTRANSLATED */ - card_title: 'For M2M', - /** UNTRANSLATED */ - card_field: 'Machine-to-machine token', - /** UNTRANSLATED */ - card_description: 'Add extra data during machine-to-machine token issuance.', - /** UNTRANSLATED */ - for: 'for M2M', - }, - /** UNTRANSLATED */ - code_editor_title: 'Customize the {{token}} claims', - /** UNTRANSLATED */ - custom_jwt_create_button: 'Add custom claims', - /** UNTRANSLATED */ - custom_jwt_item: 'Custom claims {{for}}', - /** UNTRANSLATED */ - delete_modal_title: 'Delete custom claims', - /** UNTRANSLATED */ - delete_modal_content: 'Are you sure you want to delete the custom claims?', - /** UNTRANSLATED */ - clear: 'Clear', - /** UNTRANSLATED */ - cleared: 'Cleared', - /** UNTRANSLATED */ - restore: 'Restore defaults', - /** UNTRANSLATED */ - restored: 'Restored', - /** UNTRANSLATED */ - data_source_tab: 'Data source', - /** UNTRANSLATED */ - test_tab: 'Test context', - /** UNTRANSLATED */ - jwt_claims_description: 'Default claims are auto-included in the JWT and cannot be overridden.', + card_title: 'M2M向け', + card_field: 'マシン対マシントークン', + card_description: 'マシン対マシントークン発行時に追加データを含めます。', + for: 'M2M向け', + }, + code_editor_title: 'カスタマイズ{{token}}クレーム', + custom_jwt_create_button: 'カスタムクレームを追加', + custom_jwt_item: 'カスタムクレーム{{for}}', + delete_modal_title: 'カスタムクレームを削除', + delete_modal_content: 'カスタムクレームを削除してもよろしいですか?', + clear: 'クリア', + cleared: 'クリアされた', + restore: 'デフォルトに戻す', + restored: '復元されました', + data_source_tab: 'データソース', + test_tab: 'コンテキストをテスト', + jwt_claims_description: 'デフォルトクレームはJWTに自動的に含まれ、オーバーライドできません。', user_data: { - /** UNTRANSLATED */ - title: 'User data', - /** UNTRANSLATED */ - subtitle: 'Use `data.user` input parameter to provide vital user info.', + title: 'ユーザーデータ', + subtitle: '`data.user`入力パラメータを使用して重要なユーザー情報を提供します。', }, token_data: { - /** UNTRANSLATED */ - title: 'Token data', - /** UNTRANSLATED */ - subtitle: 'Use `token` input parameter for current access token payload. ', + title: 'トークンデータ', + subtitle: '現在のアクセストークンペイロードに対して`token`入力パラメータを使用します。', }, fetch_external_data: { - /** UNTRANSLATED */ - title: 'Fetch external data', - /** UNTRANSLATED */ - subtitle: 'Incorporate data from your external APIs directly into claims.', - /** UNTRANSLATED */ - description: - 'Use the `fetch` function to call your external APIs and include the data in your custom claims. Example: ', + title: '外部データを取得', + subtitle: '外部APIからデータを直接クレームに組み込みます。', + description: '`fetch`関数を使用して外部APIを呼び出し、データをカスタムクレームに含めます。例:', }, environment_variables: { - /** UNTRANSLATED */ - title: 'Set environment variables', - /** UNTRANSLATED */ - subtitle: 'Use environment variables to store sensitive information.', - /** UNTRANSLATED */ - input_field_title: 'Add environment variables', - /** UNTRANSLATED */ - sample_code: 'Accessing environment variables in your custom JWT claims handler. Example: ', + title: '環境変数を設定', + subtitle: '機密情報を保存するために環境変数を使用します。', + input_field_title: '環境変数を追加', + sample_code: 'カスタムJWTクレームハンドラで環境変数にアクセスする方法。例:', }, - /** UNTRANSLATED */ jwt_claims_hint: - 'Limit custom claims to under 50KB. Default JWT claims are automatically included in the token and can not be overridden.', + 'カスタムクレームの制限は50KB未満です。デフォルトのJWTクレームは自動的にトークンに含まれ、オーバーライドできません。', tester: { - /** UNTRANSLATED */ - subtitle: 'Adjust mock token and user data for testing.', - /** UNTRANSLATED */ - run_button: 'Run test', - /** UNTRANSLATED */ - result_title: 'Test result', + subtitle: 'テストのためにモックトークンとユーザーデータを調整します。', + run_button: 'テストを実行', + result_title: 'テスト結果', }, form_error: { - /** UNTRANSLATED */ - invalid_json: 'Invalid JSON format', + invalid_json: '無効なJSON形式', }, }; diff --git a/packages/phrases/src/locales/ja/translation/admin-console/subscription/quota-item.ts b/packages/phrases/src/locales/ja/translation/admin-console/subscription/quota-item.ts index 1ed586e1621..ab0bafdcd1f 100644 --- a/packages/phrases/src/locales/ja/translation/admin-console/subscription/quota-item.ts +++ b/packages/phrases/src/locales/ja/translation/admin-console/subscription/quota-item.ts @@ -34,16 +34,11 @@ const quota_item = { not_eligible: 'マシン間アプリケーションを削除してください', }, third_party_applications_limit: { - /** UNTRANSLATED */ - name: 'Third-party apps', - /** UNTRANSLATED */ - limited: '{{count, number}} third-party app', - /** UNTRANSLATED */ - limited_other: '{{count, number}} third-party apps', - /** UNTRANSLATED */ - unlimited: 'Unlimited third-party apps', - /** UNTRANSLATED */ - not_eligible: 'Remove your third-party apps', + name: 'サードパーティーアプリ', + limited: '{{count, number}} サードパーティーアプリ', + limited_other: '{{count, number}} サードパーティーアプリ', + unlimited: '無制限のサードパーティーアプリ', + not_eligible: 'サードパーティーアプリを削除してください', }, resources_limit: { name: 'APIリソース', @@ -53,11 +48,11 @@ const quota_item = { not_eligible: 'APIリソースを削除してください', }, scopes_per_resource_limit: { - name: 'リソースの権限', - limited: '{{count, number}} リソースごとの権限', - limited_other: '{{count, number}} リソースごとの権限', - unlimited: '無制限のリソースごとの権限', - not_eligible: 'リソースの権限を削除してください', + name: 'リソースごとのスコープ', + limited: '{{count, number}} リソースごとのスコープ', + limited_other: '{{count, number}} リソースごとのスコープ', + unlimited: '無制限のリソースごとのスコープ', + not_eligible: 'リソースごとのスコープを削除してください', }, custom_domain_enabled: { name: 'カスタムドメイン', @@ -106,7 +101,7 @@ const quota_item = { not_eligible: 'マシン間ロールを削除してください', }, scopes_per_role_limit: { - name: 'ロールの権限', + name: 'ロールごとの権限', limited: '{{count, number}} ロールごとの権限', limited_other: '{{count, number}} ロールごとの権限', unlimited: '無制限のロールごとの権限', @@ -152,26 +147,17 @@ const quota_item = { not_eligible: 'エンタープライズSSOを削除してください', }, tenant_members_limit: { - /** UNTRANSLATED */ - name: 'Tenant members', - /** UNTRANSLATED */ - limited: '{{count, number}} tenant member', - /** UNTRANSLATED */ - limited_other: '{{count, number}} tenant members', - /** UNTRANSLATED */ - unlimited: 'Unlimited tenant members', - /** UNTRANSLATED */ - not_eligible: 'Remove your tenant members', + name: 'テナントメンバー', + limited: '{{count, number}} テナントメンバー', + limited_other: '{{count, number}} テナントメンバー', + unlimited: '無制限のテナントメンバー', + not_eligible: 'テナントメンバーを削除してください', }, custom_jwt_enabled: { - /** UNTRANSLATED */ - name: 'Custom JWT', - /** UNTRANSLATED */ - limited: 'Custom JWT', - /** UNTRANSLATED */ - unlimited: 'Custom JWT', - /** UNTRANSLATED */ - not_eligible: 'Remove your JWT claims customizer', + name: 'カスタムJWT', + limited: 'カスタムJWT', + unlimited: 'カスタムJWT', + not_eligible: 'JWTクレームカスタマイザーを削除してください', }, }; diff --git a/packages/phrases/src/locales/ja/translation/admin-console/subscription/quota-table.ts b/packages/phrases/src/locales/ja/translation/admin-console/subscription/quota-table.ts index db48ae0e151..67525687c5c 100644 --- a/packages/phrases/src/locales/ja/translation/admin-console/subscription/quota-table.ts +++ b/packages/phrases/src/locales/ja/translation/admin-console/subscription/quota-table.ts @@ -9,8 +9,7 @@ const quota_table = { title: 'アプリケーション', total: '総アプリケーション数', m2m: 'マシン・ツー・マシン', - /** UNTRANSLATED */ - third_party: 'Third-party apps', + third_party: 'サードパーティーアプリ', }, resource: { title: 'APIリソース', @@ -66,22 +65,17 @@ const quota_table = { hipaa_or_baa_report: 'HIPAA/BAAレポート', }, developers_and_platform: { - /** UNTRANSLATED */ - title: 'Developers and platform', - /** UNTRANSLATED */ + title: 'デベロッパーとプラットフォーム', hooks: 'Webhooks', - /** UNTRANSLATED */ - audit_logs_retention: 'Audit logs retention', - /** UNTRANSLATED */ - jwt_claims: 'JWT claims', - /** UNTRANSLATED */ - tenant_members: 'Tenant members', + audit_logs_retention: '監査ログの保持', + jwt_claims: 'JWTクレーム', + tenant_members: 'テナントメンバー', }, unlimited: '無制限', contact: 'お問い合わせ', monthly_price: '${{value, number}}/mo', - days_one: '{{count, number}}日', - days_other: '{{count, number}}日', + days_one: '{{count, number}} 日', + days_other: '{{count, number}} 日', add_on: 'アドオン', tier: 'レベル{{value, number}}: ', paid_token_limit_tip: @@ -97,17 +91,15 @@ const quota_table = { 'Logtoによって発行されたすべての種類のトークン、アクセストークン、リフレッシュトークンなどを含みます。', mao_tip: 'MAO(月間アクティブ組織)は、請求サイクル内で少なくとも1つのMAU(月間アクティブユーザー)を持つユニークな組織の数を意味します。', - /** UNTRANSLATED */ third_party_tip: - 'Use Logto as your OIDC identity provider for third-party app sign-ins and permission grants.', + 'LogtoをOIDCアイデンティティプロバイダーとして使用して、サードパーティーアプリケーションのサインインや権限の付与を行います。', included: '{{value, number}} 込み', included_mao: '{{value, number}} MAO込み', extra_quota_price: 'その後、各${{value, number}} / 月ごと', per_month_each: '各${{value, number}} / 月ごと', extra_mao_price: 'その後、MAOごとに${{value, number}}', per_month: '${{value, number}} / 月ごと', - /** UNTRANSLATED */ - per_member: 'Then ${{value, number}} per member', + per_member: 'メンバーごとに ${{value, number}}', }; export default Object.freeze(quota_table); diff --git a/packages/phrases/src/locales/ja/translation/admin-console/tabs.ts b/packages/phrases/src/locales/ja/translation/admin-console/tabs.ts index fcb63830353..72aabadf0fe 100644 --- a/packages/phrases/src/locales/ja/translation/admin-console/tabs.ts +++ b/packages/phrases/src/locales/ja/translation/admin-console/tabs.ts @@ -14,8 +14,7 @@ const tabs = { docs: 'ドキュメント', tenant_settings: '設定', mfa: 'Multi-factor auth', - /** UNTRANSLATED */ - customize_jwt: 'Custom JWT', + customize_jwt: 'カスタム JWT', signing_keys: '署名キー', organization_template: '組織テンプレート', }; diff --git a/packages/phrases/src/locales/ja/translation/admin-console/upsell/index.ts b/packages/phrases/src/locales/ja/translation/admin-console/upsell/index.ts index 4f863f9b668..fb87388b99f 100644 --- a/packages/phrases/src/locales/ja/translation/admin-console/upsell/index.ts +++ b/packages/phrases/src/locales/ja/translation/admin-console/upsell/index.ts @@ -35,8 +35,7 @@ const upsell = { api_resource: 'API リソース', machine_to_machine: 'マシン対マシンアプリケーション', tokens: '{{limit}}M トークン', - /** UNTRANSLATED */ - tenant_member: 'tenant member', + tenant_member: 'テナントメンバー', }, charge_notification_for_quota_limit: '{{item}} のクォータ制限を超えています。Logto はクォータ制限を超える利用に対して料金を追加します。新しいアドオン価格設計がリリースされる日から請求が開始されます。 詳細', diff --git a/packages/phrases/src/locales/ja/translation/admin-console/upsell/paywall.ts b/packages/phrases/src/locales/ja/translation/admin-console/upsell/paywall.ts index a96af34b760..113637b7399 100644 --- a/packages/phrases/src/locales/ja/translation/admin-console/upsell/paywall.ts +++ b/packages/phrases/src/locales/ja/translation/admin-console/upsell/paywall.ts @@ -52,22 +52,16 @@ const paywall = { mfa: 'セキュリティを確認するためにMFAを解除して有料プランにアップグレードしてください。ご質問があれば、お問い合わせください。', organizations: 'Unlock organizations by upgrading to a paid plan. Don’t hesitate to contact us if you need any assistance.', - /** UNTRANSLATED */ third_party_apps: 'Unlock Logto as IdP for third-party apps by upgrading to a paid plan. For any assistance, feel free to contact us.', - /** UNTRANSLATED */ sso_connectors: 'Unlock enterprise sso by upgrading to a paid plan. For any assistance, feel free to contact us.', - /** UNTRANSLATED */ tenant_members: 'Unlock collaboration feature by upgrading to a paid plan. For any assistance, feel free to contact us.', - /** UNTRANSLATED */ tenant_members_dev_plan: "You've reached your {{limit}}-member limit. Release a member or revoke a pending invitation to add someone new. Need more seats? Feel free to contact us.", custom_jwt: { - /** UNTRANSLATED */ title: 'Add custom claims', - /** UNTRANSLATED */ description: "Upgrade to a paid plan for custom JWT functionality and premium benefits. Don't hesitate to contact us if you have any questions.", }, diff --git a/packages/phrases/src/locales/ko/errors/jwt-customizer.ts b/packages/phrases/src/locales/ko/errors/jwt-customizer.ts index c7c5c1e2af9..68296e8c524 100644 --- a/packages/phrases/src/locales/ko/errors/jwt-customizer.ts +++ b/packages/phrases/src/locales/ko/errors/jwt-customizer.ts @@ -1,8 +1,6 @@ const jwt_customizer = { - /** UNTRANSLATED */ - general: 'An error occurred while customizing the JWT token. Please try again later.', - /** UNTRANSLATED */ - can_not_create_for_admin_tenant: 'Cannot create a JWT token customizer for the admin tenant.', + general: 'JWT 토큰을 사용자 지정하는 중에 오류가 발생했습니다. 나중에 다시 시도해주세요.', + can_not_create_for_admin_tenant: '관리자 테넌트에 대해 JWT 토큰 사용자 지정을 만들 수 없습니다.', }; export default Object.freeze(jwt_customizer); diff --git a/packages/phrases/src/locales/ko/translation/admin-console/errors.ts b/packages/phrases/src/locales/ko/translation/admin-console/errors.ts index 2204568821b..2c369bc506c 100644 --- a/packages/phrases/src/locales/ko/translation/admin-console/errors.ts +++ b/packages/phrases/src/locales/ko/translation/admin-console/errors.ts @@ -7,8 +7,7 @@ const errors = { invalid_uri_format: 'URI 형식이 유효하지 않음', invalid_origin_format: 'URI origin 형식이 유효하지 않음', invalid_json_format: 'JSON 형식이 유효하지 않음', - /** UNTRANSLATED */ - invalid_regex: 'Invalid regular expression', + invalid_regex: '잘못된 정규 표현식', invalid_error_message_format: '오류 메세지 형식이 유효하지 않아요.', required_field_missing: '{{field}}을/를 입력해 주세요.', required_field_missing_plural: '최소 1개의 {{field}}을/를 입력해야 해요.', diff --git a/packages/phrases/src/locales/ko/translation/admin-console/general.ts b/packages/phrases/src/locales/ko/translation/admin-console/general.ts index 9437a9f51a5..fe2b35870a2 100644 --- a/packages/phrases/src/locales/ko/translation/admin-console/general.ts +++ b/packages/phrases/src/locales/ko/translation/admin-console/general.ts @@ -25,11 +25,9 @@ const general = { customize: '사용자화', enable: '활성화', reminder: '리마인더', - /** UNTRANSLATED */ - edit: 'Edit', + edit: '편집', delete: '삭제', - /** UNTRANSLATED */ - deleted: 'Deleted', + deleted: '삭제됨', more_options: '더 많은 설정', close: '닫기', copy: '복사', @@ -58,8 +56,7 @@ const general = { demo: '데모', unnamed: '이름없음', view: '보기', - /** UNTRANSLATED */ - open: 'Open', + open: '열기', hide: '숨기기', unknown_error: '알 수 없는 오류가 발생했습니다. 나중에 다시 시도해주세요.', select: '선택', @@ -71,8 +68,7 @@ const general = { edit_field: '{{field}} 편집', delete_field: '{{field}} 삭제', coming_soon: '곧 출시 예정', - /** UNTRANSLATED */ - or: 'Or', + or: '또는', }; export default Object.freeze(general); diff --git a/packages/phrases/src/locales/ko/translation/admin-console/jwt-claims.ts b/packages/phrases/src/locales/ko/translation/admin-console/jwt-claims.ts index f0d189ab412..3735dde4742 100644 --- a/packages/phrases/src/locales/ko/translation/admin-console/jwt-claims.ts +++ b/packages/phrases/src/locales/ko/translation/admin-console/jwt-claims.ts @@ -1,98 +1,60 @@ const jwt_claims = { - /** UNTRANSLATED */ - title: 'Custom JWT', - /** UNTRANSLATED */ + title: '사용자 정의 JWT', description: - 'Set up custom JWT claims to include in the access token. These claims can be used to pass additional information to your application.', + '액세스 토큰에 포함할 사용자 정의 JWT 클레임을 설정하세요. 이러한 클레임은 추가 정보를 응용 프로그램에 전달하는 데 사용될 수 있습니다.', user_jwt: { - /** UNTRANSLATED */ - card_title: 'For user', - /** UNTRANSLATED */ - card_field: 'User access token', - /** UNTRANSLATED */ - card_description: 'Add user-specific data during access token issuance.', - /** UNTRANSLATED */ - for: 'for user', + card_title: '사용자용', + card_field: '사용자 액세스 토큰', + card_description: '액세스 토큰 발급 시 사용자별 데이터 추가.', + for: '사용자용', }, machine_to_machine_jwt: { - /** UNTRANSLATED */ - card_title: 'For M2M', - /** UNTRANSLATED */ - card_field: 'Machine-to-machine token', - /** UNTRANSLATED */ - card_description: 'Add extra data during machine-to-machine token issuance.', - /** UNTRANSLATED */ - for: 'for M2M', - }, - /** UNTRANSLATED */ - code_editor_title: 'Customize the {{token}} claims', - /** UNTRANSLATED */ - custom_jwt_create_button: 'Add custom claims', - /** UNTRANSLATED */ - custom_jwt_item: 'Custom claims {{for}}', - /** UNTRANSLATED */ - delete_modal_title: 'Delete custom claims', - /** UNTRANSLATED */ - delete_modal_content: 'Are you sure you want to delete the custom claims?', - /** UNTRANSLATED */ - clear: 'Clear', - /** UNTRANSLATED */ - cleared: 'Cleared', - /** UNTRANSLATED */ - restore: 'Restore defaults', - /** UNTRANSLATED */ - restored: 'Restored', - /** UNTRANSLATED */ - data_source_tab: 'Data source', - /** UNTRANSLATED */ - test_tab: 'Test context', - /** UNTRANSLATED */ - jwt_claims_description: 'Default claims are auto-included in the JWT and cannot be overridden.', + card_title: 'M2M용', + card_field: '기기 간 토큰', + card_description: '기기 간 토큰 발급 시 추가 데이터 추가.', + for: 'M2M용', + }, + code_editor_title: '{{$token}} 클레임을 사용자화', + custom_jwt_create_button: '사용자 정의 클레임 추가', + custom_jwt_item: '사용자 정의 클레임 {{$for}}', + delete_modal_title: '사용자 정의 클레임 삭제', + delete_modal_content: '사용자 정의 클레임을 삭제하시겠습니까?', + clear: '지우기', + cleared: '지움', + restore: '기본값으로 복원', + restored: '복원됨', + data_source_tab: '데이터 소스', + test_tab: '테스트 컨텍스트', + jwt_claims_description: '기본 클레임은 JWT에 자동으로 추가되며 재정의할 수 없습니다.', user_data: { - /** UNTRANSLATED */ - title: 'User data', - /** UNTRANSLATED */ - subtitle: 'Use `data.user` input parameter to provide vital user info.', + title: '사용자 데이터', + subtitle: '`data.user` 입력 매개변수를 사용하여 중요한 사용자 정보 제공.', }, token_data: { - /** UNTRANSLATED */ - title: 'Token data', - /** UNTRANSLATED */ - subtitle: 'Use `token` input parameter for current access token payload. ', + title: '토큰 데이터', + subtitle: '현재 액세스 토큰 페이로드에 대한 `token` 입력 매개변수 사용.', }, fetch_external_data: { - /** UNTRANSLATED */ - title: 'Fetch external data', - /** UNTRANSLATED */ - subtitle: 'Incorporate data from your external APIs directly into claims.', - /** UNTRANSLATED */ + title: '외부 데이터 가져오기', + subtitle: '외부 API에서 데이터 직접 클레임에 통합.', description: - 'Use the `fetch` function to call your external APIs and include the data in your custom claims. Example: ', + '`fetch` 함수를 사용하여 외부 API를 호출하고 해당 데이터를 사용자 정의 클레임에 포함시킵니다. 예시: ', }, environment_variables: { - /** UNTRANSLATED */ - title: 'Set environment variables', - /** UNTRANSLATED */ - subtitle: 'Use environment variables to store sensitive information.', - /** UNTRANSLATED */ - input_field_title: 'Add environment variables', - /** UNTRANSLATED */ - sample_code: 'Accessing environment variables in your custom JWT claims handler. Example: ', + title: '환경 변수 설정', + subtitle: '중요 정보를 저장하기 위해 환경 변수를 사용하세요.', + input_field_title: '환경 변수 추가', + sample_code: '사용자 정의 JWT 클레임 핸들러에서 환경 변수에 접근하는 방법. 예시: ', }, - /** UNTRANSLATED */ jwt_claims_hint: - 'Limit custom claims to under 50KB. Default JWT claims are automatically included in the token and can not be overridden.', + '사용자 정의 클레임을 50KB 미만으로 제한하세요. 기본 JWT 클레임은 토큰에 자동으로 포함되며 재정의할 수 없습니다.', tester: { - /** UNTRANSLATED */ - subtitle: 'Adjust mock token and user data for testing.', - /** UNTRANSLATED */ - run_button: 'Run test', - /** UNTRANSLATED */ - result_title: 'Test result', + subtitle: '테스트를 위해 모의 토큰 및 사용자 데이터 조정.', + run_button: '테스트 실행', + result_title: '테스트 결과', }, form_error: { - /** UNTRANSLATED */ - invalid_json: 'Invalid JSON format', + invalid_json: '잘못된 JSON 형식', }, }; diff --git a/packages/phrases/src/locales/ko/translation/admin-console/subscription/quota-item.ts b/packages/phrases/src/locales/ko/translation/admin-console/subscription/quota-item.ts index 1e6dd90a4ab..0d93670ce79 100644 --- a/packages/phrases/src/locales/ko/translation/admin-console/subscription/quota-item.ts +++ b/packages/phrases/src/locales/ko/translation/admin-console/subscription/quota-item.ts @@ -34,16 +34,11 @@ const quota_item = { not_eligible: '기계 간 앱을 제거하십시오', }, third_party_applications_limit: { - /** UNTRANSLATED */ - name: 'Third-party apps', - /** UNTRANSLATED */ - limited: '{{count, number}} third-party app', - /** UNTRANSLATED */ - limited_other: '{{count, number}} third-party apps', - /** UNTRANSLATED */ - unlimited: 'Unlimited third-party apps', - /** UNTRANSLATED */ - not_eligible: 'Remove your third-party apps', + name: '타사 앱', + limited: '{{count, number}} 타사 앱', + limited_other: '{{count, number}} 타사 앱', + unlimited: '무제한 타사 앱', + not_eligible: '타사 앱을 제거하십시오', }, resources_limit: { name: 'API 리소스', @@ -152,26 +147,17 @@ const quota_item = { not_eligible: '기업 SSO를 제거하십시오', }, tenant_members_limit: { - /** UNTRANSLATED */ - name: 'Tenant members', - /** UNTRANSLATED */ - limited: '{{count, number}} tenant member', - /** UNTRANSLATED */ - limited_other: '{{count, number}} tenant members', - /** UNTRANSLATED */ - unlimited: 'Unlimited tenant members', - /** UNTRANSLATED */ - not_eligible: 'Remove your tenant members', + name: '테넌트 멤버', + limited: '{{count, number}} 테넌트 멤버', + limited_other: '{{count, number}} 테넌트 멤버', + unlimited: '제한 없는 테넌트 멤버', + not_eligible: '테넌트 멤버를 제거하십시오', }, custom_jwt_enabled: { - /** UNTRANSLATED */ - name: 'Custom JWT', - /** UNTRANSLATED */ - limited: 'Custom JWT', - /** UNTRANSLATED */ - unlimited: 'Custom JWT', - /** UNTRANSLATED */ - not_eligible: 'Remove your JWT claims customizer', + name: '사용자 정의 JWT', + limited: '사용자 정의 JWT', + unlimited: '사용자 정의 JWT', + not_eligible: '사용자 정의 JWT 클레임 사용자를 제거하십시오', }, }; diff --git a/packages/phrases/src/locales/ko/translation/admin-console/subscription/quota-table.ts b/packages/phrases/src/locales/ko/translation/admin-console/subscription/quota-table.ts index 58dac7287cc..2f657646b51 100644 --- a/packages/phrases/src/locales/ko/translation/admin-console/subscription/quota-table.ts +++ b/packages/phrases/src/locales/ko/translation/admin-console/subscription/quota-table.ts @@ -9,8 +9,7 @@ const quota_table = { title: '애플리케이션', total: '총 애플리케이션 수', m2m: '머신 투 머신', - /** UNTRANSLATED */ - third_party: 'Third-party apps', + third_party: '타사 앱', }, resource: { title: 'API 리소스', @@ -27,9 +26,9 @@ const quota_table = { }, user_authn: { title: '사용자 인증', - omni_sign_in: '옴니 사인인', + omni_sign_in: '옴니 로그인', password: '비밀번호', - passwordless: '비밀번호 없음 - 이메일과 SMS', + passwordless: '비밀번호 없음 - 이메일 및 SMS', email_connector: '이메일 커넥터', sms_connector: 'SMS 커넥터', social_connectors: '소셜 커넥터', @@ -66,16 +65,11 @@ const quota_table = { hipaa_or_baa_report: 'HIPAA/BAA 보고서', }, developers_and_platform: { - /** UNTRANSLATED */ - title: 'Developers and platform', - /** UNTRANSLATED */ - hooks: 'Webhooks', - /** UNTRANSLATED */ - audit_logs_retention: 'Audit logs retention', - /** UNTRANSLATED */ - jwt_claims: 'JWT claims', - /** UNTRANSLATED */ - tenant_members: 'Tenant members', + title: '개발자와 플랫폼', + hooks: '웹훅', + audit_logs_retention: '감사 로그 보존', + jwt_claims: 'JWT 클레임', + tenant_members: '테넌트 멤버', }, unlimited: '무제한', contact: '문의', @@ -96,17 +90,14 @@ const quota_table = { tokens_tip: 'Logto에서 발행한 모든 종류의 토큰, 액세스 토큰, 리프레시 토큰 등을 포함합니다.', mao_tip: 'MAO (월간 활성 조직)는 빌링 주기 내에서 적어도 하나의 MAU (월간 활성 사용자)를 가진 고유한 조직의 수를 의미합니다.', - /** UNTRANSLATED */ - third_party_tip: - 'Use Logto as your OIDC identity provider for third-party app sign-ins and permission grants.', + third_party_tip: '타사 앱의 로그인 및 권한 부여에 대해 OIDC ID 공급자로서 Logto를 사용합니다.', included: '{{value, number}} 포함', included_mao: '{{value, number}} MAO 포함', extra_quota_price: '이후 월당 ${{value, number}} / 각각', per_month_each: '월당 ${{value, number}} / 각각', extra_mao_price: '이후 MAO당 ${{value, number}}', per_month: '월당 ${{value, number}}', - /** UNTRANSLATED */ - per_member: 'Then ${{value, number}} per member', + per_member: '그런 다음 ${{value, number}} / 회원', }; export default Object.freeze(quota_table); diff --git a/packages/phrases/src/locales/ko/translation/admin-console/tabs.ts b/packages/phrases/src/locales/ko/translation/admin-console/tabs.ts index f47317f2f92..93743319e69 100644 --- a/packages/phrases/src/locales/ko/translation/admin-console/tabs.ts +++ b/packages/phrases/src/locales/ko/translation/admin-console/tabs.ts @@ -14,8 +14,7 @@ const tabs = { docs: '문서', tenant_settings: '테넌트 설정', mfa: '다중 요소 인증', - /** UNTRANSLATED */ - customize_jwt: 'Custom JWT', + customize_jwt: '사용자 지정 JWT', signing_keys: '서명 키', organization_template: '조직 템플릿', }; diff --git a/packages/phrases/src/locales/ko/translation/admin-console/upsell/index.ts b/packages/phrases/src/locales/ko/translation/admin-console/upsell/index.ts index b19df9c36de..c8de2b92c28 100644 --- a/packages/phrases/src/locales/ko/translation/admin-console/upsell/index.ts +++ b/packages/phrases/src/locales/ko/translation/admin-console/upsell/index.ts @@ -35,8 +35,7 @@ const upsell = { api_resource: 'API 리소스', machine_to_machine: '머신 투 머신 애플리케이션', tokens: '{{limit}}M 토큰', - /** UNTRANSLATED */ - tenant_member: 'tenant member', + tenant_member: 'tenant 회원', }, charge_notification_for_quota_limit: '{{item}} 할당량 한도를 초과했습니다. Logto는 할당량을 초과하는 사용에 대한 요금을 추가합니다. 새로운 애드온 가격 디자인이 출시된 날부터 청구가 시작됩니다. 더 알아보기', diff --git a/packages/phrases/src/locales/ko/translation/admin-console/upsell/paywall.ts b/packages/phrases/src/locales/ko/translation/admin-console/upsell/paywall.ts index 0c221135192..8d39230dc4e 100644 --- a/packages/phrases/src/locales/ko/translation/admin-console/upsell/paywall.ts +++ b/packages/phrases/src/locales/ko/translation/admin-console/upsell/paywall.ts @@ -52,24 +52,18 @@ const paywall = { mfa: '보안을 확인하기 위해 MFA를 잠금 해제하여 유료 플랜으로 업그레이드하세요. 궁금한 점이 있으면 문의하세요.', organizations: 'Unlock organizations by upgrading to a paid plan. Don’t hesitate to contact us if you need any assistance.', - /** UNTRANSLATED */ third_party_apps: - 'Unlock Logto as IdP for third-party apps by upgrading to a paid plan. For any assistance, feel free to contact us.', - /** UNTRANSLATED */ + '로그토를 IdP로서 타사 앱에 대해 잠금 해제하려면 유료 플랜으로 업그레이드하세요. 도움이 필요하면 문의하세요.', sso_connectors: - 'Unlock enterprise sso by upgrading to a paid plan. For any assistance, feel free to contact us.', - /** UNTRANSLATED */ + '엔터프라이즈 SSO를 잠금 해제하려면 유료 플랜으로 업그레이드하세요. 도움이 필요하면 문의하세요.', tenant_members: - 'Unlock collaboration feature by upgrading to a paid plan. For any assistance, feel free to contact us.', - /** UNTRANSLATED */ + '협력 기능을 잠금 해제하려면 유료 플랜으로 업그레이드하세요. 도움이 필요하면 문의하세요.', tenant_members_dev_plan: - "You've reached your {{limit}}-member limit. Release a member or revoke a pending invitation to add someone new. Need more seats? Feel free to contact us.", + '회원 제한에 도달했습니다. 새로운 회원을 추가하려면 회원을 해제하거나 보류 중인 초대를 철회하십시오. 더 많은 좌석이 필요하면 문의하십시오.', custom_jwt: { - /** UNTRANSLATED */ - title: 'Add custom claims', - /** UNTRANSLATED */ + title: '사용자 정의 클레임 추가', description: - "Upgrade to a paid plan for custom JWT functionality and premium benefits. Don't hesitate to contact us if you have any questions.", + '사용자 정의 JWT 기능 및 프리미엄 혜택을 위해 유료 플랜으로 업그레이드하세요. 궁금한 점이 있으면 문의하세요.', }, }; diff --git a/packages/phrases/src/locales/pl-pl/errors/jwt-customizer.ts b/packages/phrases/src/locales/pl-pl/errors/jwt-customizer.ts index c7c5c1e2af9..0f228677804 100644 --- a/packages/phrases/src/locales/pl-pl/errors/jwt-customizer.ts +++ b/packages/phrases/src/locales/pl-pl/errors/jwt-customizer.ts @@ -1,8 +1,7 @@ const jwt_customizer = { - /** UNTRANSLATED */ - general: 'An error occurred while customizing the JWT token. Please try again later.', - /** UNTRANSLATED */ - can_not_create_for_admin_tenant: 'Cannot create a JWT token customizer for the admin tenant.', + general: 'Wystąpił błąd podczas dostosowywania tokenu JWT. Spróbuj ponownie później.', + can_not_create_for_admin_tenant: + 'Nie można utworzyć dostosowywania tokenu JWT dla administratora.', }; export default Object.freeze(jwt_customizer); diff --git a/packages/phrases/src/locales/pl-pl/translation/admin-console/errors.ts b/packages/phrases/src/locales/pl-pl/translation/admin-console/errors.ts index ba79cf988b7..d672e91a55b 100644 --- a/packages/phrases/src/locales/pl-pl/translation/admin-console/errors.ts +++ b/packages/phrases/src/locales/pl-pl/translation/admin-console/errors.ts @@ -7,8 +7,7 @@ const errors = { invalid_uri_format: 'Nieprawidłowy format URI', invalid_origin_format: 'Nieprawidłowy format pochodzenia URI', invalid_json_format: 'Nieprawidłowy format JSON', - /** UNTRANSLATED */ - invalid_regex: 'Invalid regular expression', + invalid_regex: 'Nieprawidłowe wyrażenie regularne', invalid_error_message_format: 'Nieprawidłowy format komunikatu błędu.', required_field_missing: 'Wpisz {{field}}', required_field_missing_plural: 'Musisz wprowadzić przynajmniej jeden {{field}}', @@ -21,7 +20,7 @@ const errors = { unexpected_error: 'Wystąpił nieoczekiwany błąd.', not_found: '404 nie znaleziono', create_internal_role_violation: - 'Tworzysz nową wewnętrzną rolę, co jest zabronione przez Logto. Spróbuj użyć innego nazwy, która nie zaczyna się od "#internal:".', + 'Tworzysz nową wewnętrzną rolę, co jest zabronione przez Logto. Spróbuj użyć innego nazwy, która nie zaczyna się od "#internal:". ', should_be_an_integer: 'Powinno być liczbą całkowitą.', number_should_be_between_inclusive: 'Następnie liczba powinna być między {{min}} a {{max}} (włącznie).', diff --git a/packages/phrases/src/locales/pl-pl/translation/admin-console/general.ts b/packages/phrases/src/locales/pl-pl/translation/admin-console/general.ts index 14cf496642d..d803bf4796f 100644 --- a/packages/phrases/src/locales/pl-pl/translation/admin-console/general.ts +++ b/packages/phrases/src/locales/pl-pl/translation/admin-console/general.ts @@ -25,11 +25,9 @@ const general = { customize: 'Dostosuj', enable: 'Włącz', reminder: 'Przypomnienie', - /** UNTRANSLATED */ - edit: 'Edit', + edit: 'Edytuj', delete: 'Usuń', - /** UNTRANSLATED */ - deleted: 'Deleted', + deleted: 'Usunięto', more_options: 'WIĘCEJ OPCJI', close: 'Zamknij', copy: 'Kopiuj', @@ -58,8 +56,7 @@ const general = { demo: 'Demo', unnamed: 'Bez nazwy', view: 'Pokaż', - /** UNTRANSLATED */ - open: 'Open', + open: 'Otwórz', hide: 'Ukryj', unknown_error: 'Nieznany błąd, spróbuj ponownie później.', select: 'Wybierz', @@ -71,8 +68,7 @@ const general = { edit_field: 'Edytuj {{field}}', delete_field: 'Usuń {{field}}', coming_soon: 'Wkrótce dostępne', - /** UNTRANSLATED */ - or: 'Or', + or: 'Lub', }; export default Object.freeze(general); diff --git a/packages/phrases/src/locales/pl-pl/translation/admin-console/jwt-claims.ts b/packages/phrases/src/locales/pl-pl/translation/admin-console/jwt-claims.ts index f0d189ab412..5e6ca23390f 100644 --- a/packages/phrases/src/locales/pl-pl/translation/admin-console/jwt-claims.ts +++ b/packages/phrases/src/locales/pl-pl/translation/admin-console/jwt-claims.ts @@ -1,98 +1,64 @@ const jwt_claims = { - /** UNTRANSLATED */ - title: 'Custom JWT', - /** UNTRANSLATED */ + title: 'Niestandardowe JWT', description: - 'Set up custom JWT claims to include in the access token. These claims can be used to pass additional information to your application.', + 'Ustaw niestandardowe roszczenia JWT, które mają być dołączone do tokenu dostępowego. Te roszczenia mogą być wykorzystane do przekazywania dodatkowych informacji do Twojej aplikacji.', user_jwt: { - /** UNTRANSLATED */ - card_title: 'For user', - /** UNTRANSLATED */ - card_field: 'User access token', - /** UNTRANSLATED */ - card_description: 'Add user-specific data during access token issuance.', - /** UNTRANSLATED */ - for: 'for user', + card_title: 'Dla użytkownika', + card_field: 'Token dostępowy użytkownika', + card_description: + 'Dodaj dane specyficzne dla użytkownika podczas wydawania tokenu dostępowego.', + for: 'dla użytkownika', }, machine_to_machine_jwt: { - /** UNTRANSLATED */ - card_title: 'For M2M', - /** UNTRANSLATED */ - card_field: 'Machine-to-machine token', - /** UNTRANSLATED */ - card_description: 'Add extra data during machine-to-machine token issuance.', - /** UNTRANSLATED */ - for: 'for M2M', + card_title: 'Dla M2M', + card_field: 'Token maszynowy do maszyny', + card_description: 'Dodaj dodatkowe dane podczas wydawania tokena maszynowego do maszyny.', + for: 'dla M2M', }, - /** UNTRANSLATED */ - code_editor_title: 'Customize the {{token}} claims', - /** UNTRANSLATED */ - custom_jwt_create_button: 'Add custom claims', - /** UNTRANSLATED */ - custom_jwt_item: 'Custom claims {{for}}', - /** UNTRANSLATED */ - delete_modal_title: 'Delete custom claims', - /** UNTRANSLATED */ - delete_modal_content: 'Are you sure you want to delete the custom claims?', - /** UNTRANSLATED */ - clear: 'Clear', - /** UNTRANSLATED */ - cleared: 'Cleared', - /** UNTRANSLATED */ - restore: 'Restore defaults', - /** UNTRANSLATED */ - restored: 'Restored', - /** UNTRANSLATED */ - data_source_tab: 'Data source', - /** UNTRANSLATED */ - test_tab: 'Test context', - /** UNTRANSLATED */ - jwt_claims_description: 'Default claims are auto-included in the JWT and cannot be overridden.', + code_editor_title: 'Dostosuj roszczenia {{token}}', + custom_jwt_create_button: 'Dodaj niestandardowe roszczenia', + custom_jwt_item: 'Niestandardowe roszczenia {{for}}', + delete_modal_title: 'Usuń niestandardowe roszczenia', + delete_modal_content: 'Czy na pewno chcesz usunąć niestandardowe roszczenia?', + clear: 'Wyczyść', + cleared: 'Wyczyszczono', + restore: 'Przywróć domyślne', + restored: 'Przywrócono', + data_source_tab: 'Źródło danych', + test_tab: 'Kontekst testowy', + jwt_claims_description: + 'Domyślne roszczenia są automatycznie dołączane do JWT i nie mogą być nadpisane.', user_data: { - /** UNTRANSLATED */ - title: 'User data', - /** UNTRANSLATED */ - subtitle: 'Use `data.user` input parameter to provide vital user info.', + title: 'Dane użytkownika', + subtitle: + 'Użyj parametru wejściowego `data.user`, aby dostarczyć istotne informacje o użytkowniku.', }, token_data: { - /** UNTRANSLATED */ - title: 'Token data', - /** UNTRANSLATED */ - subtitle: 'Use `token` input parameter for current access token payload. ', + title: 'Dane tokenu', + subtitle: 'Użyj parametru wejściowego `token`, aby uzyskać bieżący ładunek tokenu dostępu.', }, fetch_external_data: { - /** UNTRANSLATED */ - title: 'Fetch external data', - /** UNTRANSLATED */ - subtitle: 'Incorporate data from your external APIs directly into claims.', - /** UNTRANSLATED */ + title: 'Pobierz zewnętrzne dane', + subtitle: 'Włóż dane bezpośrednio z Twoich zewnętrznych API do roszczeń.', description: - 'Use the `fetch` function to call your external APIs and include the data in your custom claims. Example: ', + 'Użyj funkcji `fetch`, aby wywołać Twoje zewnętrzne API i dołączyć dane do niestandardowych roszczeń. Przykład: ', }, environment_variables: { - /** UNTRANSLATED */ - title: 'Set environment variables', - /** UNTRANSLATED */ - subtitle: 'Use environment variables to store sensitive information.', - /** UNTRANSLATED */ - input_field_title: 'Add environment variables', - /** UNTRANSLATED */ - sample_code: 'Accessing environment variables in your custom JWT claims handler. Example: ', + title: 'Ustaw zmienne środowiskowe', + subtitle: 'Użyj zmiennych środowiskowych do przechowywania poufnych informacji.', + input_field_title: 'Dodaj zmienne środowiskowe', + sample_code: + 'Dostęp do zmiennych środowiskowych w twoim programie obsługi niestandardowych roszczeń JWT. Przykład: ', }, - /** UNTRANSLATED */ jwt_claims_hint: - 'Limit custom claims to under 50KB. Default JWT claims are automatically included in the token and can not be overridden.', + 'Ogranicz niestandardowe roszczenia do mniej niż 50 KB. Domyślne roszczenia JWT są automatycznie dołączane do tokenu i nie mogą być nadpisane.', tester: { - /** UNTRANSLATED */ - subtitle: 'Adjust mock token and user data for testing.', - /** UNTRANSLATED */ - run_button: 'Run test', - /** UNTRANSLATED */ - result_title: 'Test result', + subtitle: 'Dostosuj fałszywy token i dane użytkownika do testowania.', + run_button: 'Uruchom test', + result_title: 'Wynik testu', }, form_error: { - /** UNTRANSLATED */ - invalid_json: 'Invalid JSON format', + invalid_json: 'Nieprawidłowy format JSON', }, }; diff --git a/packages/phrases/src/locales/pl-pl/translation/admin-console/subscription/quota-item.ts b/packages/phrases/src/locales/pl-pl/translation/admin-console/subscription/quota-item.ts index 146c4f1e7f8..82798b7aa5b 100644 --- a/packages/phrases/src/locales/pl-pl/translation/admin-console/subscription/quota-item.ts +++ b/packages/phrases/src/locales/pl-pl/translation/admin-console/subscription/quota-item.ts @@ -34,16 +34,11 @@ const quota_item = { not_eligible: 'Usuń swoje aplikacje machine to machine', }, third_party_applications_limit: { - /** UNTRANSLATED */ - name: 'Third-party apps', - /** UNTRANSLATED */ - limited: '{{count, number}} third-party app', - /** UNTRANSLATED */ - limited_other: '{{count, number}} third-party apps', - /** UNTRANSLATED */ - unlimited: 'Unlimited third-party apps', - /** UNTRANSLATED */ - not_eligible: 'Remove your third-party apps', + name: 'Aplikacje osób trzecich', + limited: '{{count, number}} aplikacja osób trzecich', + limited_other: '{{count, number}} aplikacje osób trzecich', + unlimited: 'Nieograniczona liczba aplikacji osób trzecich', + not_eligible: 'Usuń swoje aplikacje osób trzecich', }, resources_limit: { name: 'Zasoby API', @@ -152,26 +147,17 @@ const quota_item = { not_eligible: 'Usuń swoje SSO przedsiębiorstwa', }, tenant_members_limit: { - /** UNTRANSLATED */ - name: 'Tenant members', - /** UNTRANSLATED */ - limited: '{{count, number}} tenant member', - /** UNTRANSLATED */ - limited_other: '{{count, number}} tenant members', - /** UNTRANSLATED */ - unlimited: 'Unlimited tenant members', - /** UNTRANSLATED */ - not_eligible: 'Remove your tenant members', + name: 'Członkowie najemcy', + limited: '{{count, number}} członek najemcy', + limited_other: '{{count, number}} członków najemcy', + unlimited: 'Nieograniczona liczba członków najemcy', + not_eligible: 'Usuń swoich członków najemcy', }, custom_jwt_enabled: { - /** UNTRANSLATED */ - name: 'Custom JWT', - /** UNTRANSLATED */ - limited: 'Custom JWT', - /** UNTRANSLATED */ - unlimited: 'Custom JWT', - /** UNTRANSLATED */ - not_eligible: 'Remove your JWT claims customizer', + name: 'Niestandardowy JWT', + limited: 'Niestandardowy JWT', + unlimited: 'Niestandardowy JWT', + not_eligible: 'Usuń swoje niestandardowe narzędzie tworzące JWT', }, }; diff --git a/packages/phrases/src/locales/pl-pl/translation/admin-console/subscription/quota-table.ts b/packages/phrases/src/locales/pl-pl/translation/admin-console/subscription/quota-table.ts index 3be1dd3e325..c0d7840d36e 100644 --- a/packages/phrases/src/locales/pl-pl/translation/admin-console/subscription/quota-table.ts +++ b/packages/phrases/src/locales/pl-pl/translation/admin-console/subscription/quota-table.ts @@ -9,8 +9,7 @@ const quota_table = { title: 'Aplikacje', total: 'Liczba aplikacji', m2m: 'Aplikacja typu maszyna-maszyna', - /** UNTRANSLATED */ - third_party: 'Third-party apps', + third_party: 'Aplikacje firm trzecich', }, resource: { title: 'Zasoby API', @@ -66,16 +65,11 @@ const quota_table = { hipaa_or_baa_report: 'Raport HIPAA/BAA', }, developers_and_platform: { - /** UNTRANSLATED */ - title: 'Developers and platform', - /** UNTRANSLATED */ + title: 'Deweloperzy i platforma', hooks: 'Webhooks', - /** UNTRANSLATED */ - audit_logs_retention: 'Audit logs retention', - /** UNTRANSLATED */ - jwt_claims: 'JWT claims', - /** UNTRANSLATED */ - tenant_members: 'Tenant members', + audit_logs_retention: 'Retention logów audit', + jwt_claims: 'Pretensje JWT', + tenant_members: 'Członkowie najemcy', }, unlimited: 'Nieograniczone', contact: 'Kontakt', @@ -97,17 +91,15 @@ const quota_table = { 'Wszystkie rodzaje tokenów wydanych przez Logto, w tym tokeny dostępu, tokeny odświeżania, itp.', mao_tip: 'MAO (aktywna organizacja miesięczna) oznacza liczbę unikalnych organizacji, które mają co najmniej jednego aktywnego użytkownika miesięcznie w cyklu rozliczeniowym.', - /** UNTRANSLATED */ third_party_tip: - 'Use Logto as your OIDC identity provider for third-party app sign-ins and permission grants.', + 'Używaj Logto jako dostawcy tożsamości OIDC do logowania firm trzecich i udzielania zgód.', included: '{{value, number}} zawarte', included_mao: '{{value, number}} MAO wliczone', extra_quota_price: 'Następnie ${{value, number}} za miesiąc / każdy po', per_month_each: '${{value, number}} za miesiąc / każdy', extra_mao_price: 'Następnie ${{value, number}} za MAO', per_month: '${{value, number}} za miesiąc', - /** UNTRANSLATED */ - per_member: 'Then ${{value, number}} per member', + per_member: 'Następnie ${{value, number}} za członka', }; export default Object.freeze(quota_table); diff --git a/packages/phrases/src/locales/pl-pl/translation/admin-console/tabs.ts b/packages/phrases/src/locales/pl-pl/translation/admin-console/tabs.ts index c9044d51321..baafdb323b9 100644 --- a/packages/phrases/src/locales/pl-pl/translation/admin-console/tabs.ts +++ b/packages/phrases/src/locales/pl-pl/translation/admin-console/tabs.ts @@ -14,8 +14,7 @@ const tabs = { docs: 'Dokumentacja', tenant_settings: 'Ustawienia', mfa: 'Multi-factor auth', - /** UNTRANSLATED */ - customize_jwt: 'Custom JWT', + customize_jwt: 'Niestandardowy JWT', signing_keys: 'Klucze do podpisu', organization_template: 'Szablon organizacji', }; diff --git a/packages/phrases/src/locales/pl-pl/translation/admin-console/upsell/index.ts b/packages/phrases/src/locales/pl-pl/translation/admin-console/upsell/index.ts index 8a714035ae5..93bfd827506 100644 --- a/packages/phrases/src/locales/pl-pl/translation/admin-console/upsell/index.ts +++ b/packages/phrases/src/locales/pl-pl/translation/admin-console/upsell/index.ts @@ -8,7 +8,7 @@ const upsell = { create_tenant: { title: 'Wybierz swój plan najemcy', description: - 'Logto oferuje konkurencyjne opcje planów z innowacyjnym i przystępnym cenowo modelu dla rozwijających się firm. Dowiedz się więcej', + 'Logto oferuje konkurencyjne opcje planów z innowacyjnym i przystępnym cenowo modelem dla rozwijających się firm. Dowiedz się więcej', base_price: 'Cena podstawowa', monthly_price: '{{value, number}}/mies.', view_all_features: 'Zobacz wszystkie funkcje', @@ -35,11 +35,10 @@ const upsell = { api_resource: 'Zasób API', machine_to_machine: 'aplikacja od maszyny do maszyny', tokens: '{{limit}}M tokenów', - /** UNTRANSLATED */ - tenant_member: 'tenant member', + tenant_member: 'członek najemcy', }, charge_notification_for_quota_limit: - 'Przekroczyłeś limit kwoty {{item}}. Logto doliczy opłaty za korzystanie poza limitem kwoty. Fakturowanie rozpocznie się w dniu wprowadzenia nowego projektu cenowego dodatku. Dowiedz się więcej', + 'Przekroczyłeś limit kwoty {{item}}. Logto doliczy opłaty za korzystanie poza limitem. Fakturowanie rozpocznie się w dniu wprowadzenia nowego projektu cenowego dodatku. Dowiedz się więcej', paywall, featured_plan_content, }; diff --git a/packages/phrases/src/locales/pl-pl/translation/admin-console/upsell/paywall.ts b/packages/phrases/src/locales/pl-pl/translation/admin-console/upsell/paywall.ts index 1657979cf08..063f82b2a12 100644 --- a/packages/phrases/src/locales/pl-pl/translation/admin-console/upsell/paywall.ts +++ b/packages/phrases/src/locales/pl-pl/translation/admin-console/upsell/paywall.ts @@ -52,24 +52,18 @@ const paywall = { mfa: 'Odblokuj MFA, aby zweryfikować bezpieczeństwo, przechodząc na płatny plan. Nie wahaj się skontaktować z nami, jeśli potrzebujesz pomocy.', organizations: 'Odblokuj organizacje, ulepszając do płatnego planu. Nie wahaj się skontaktować z nami, jeśli potrzebujesz pomocy.', - /** UNTRANSLATED */ third_party_apps: - 'Unlock Logto as IdP for third-party apps by upgrading to a paid plan. For any assistance, feel free to contact us.', - /** UNTRANSLATED */ + 'Odblokuj Logto jako IdP dla aplikacji stron trzecich, ulepszając do płatnego planu. W razie potrzeby pomocy, proszę skontaktuj się z nami.', sso_connectors: - 'Unlock enterprise sso by upgrading to a paid plan. For any assistance, feel free to contact us.', - /** UNTRANSLATED */ + 'Odblokuj logowanie jednokrotne dla przedsiębiorstw, ulepszając do płatnego planu. W razie potrzeby pomocy, proszę skontaktuj się z nami.', tenant_members: - 'Unlock collaboration feature by upgrading to a paid plan. For any assistance, feel free to contact us.', - /** UNTRANSLATED */ + 'Odblokuj funkcję współpracy, ulepszając do płatnego planu. W razie potrzeby pomocy, proszę skontaktuj się z nami.', tenant_members_dev_plan: - "You've reached your {{limit}}-member limit. Release a member or revoke a pending invitation to add someone new. Need more seats? Feel free to contact us.", + 'Osiągnąłeś limit {{limit}} członków. Zwolnij członka lub anuluj oczekiwanie na zaproszenie, aby dodać nowego. Potrzebujesz więcej miejsc? Proszę skontaktować się z nami.', custom_jwt: { - /** UNTRANSLATED */ - title: 'Add custom claims', - /** UNTRANSLATED */ + title: 'Dodaj niestandardowe twierdzenia', description: - "Upgrade to a paid plan for custom JWT functionality and premium benefits. Don't hesitate to contact us if you have any questions.", + 'Ulepsz do płatnego planu, aby uzyskać funkcjonalność niestandardowego JWT i korzyści premium. Jeśli masz jakieś pytania, nie wahaj się skontaktować z nami.', }, }; diff --git a/packages/phrases/src/locales/pt-br/errors/jwt-customizer.ts b/packages/phrases/src/locales/pt-br/errors/jwt-customizer.ts index c7c5c1e2af9..5aca75e70e1 100644 --- a/packages/phrases/src/locales/pt-br/errors/jwt-customizer.ts +++ b/packages/phrases/src/locales/pt-br/errors/jwt-customizer.ts @@ -1,8 +1,7 @@ const jwt_customizer = { - /** UNTRANSLATED */ - general: 'An error occurred while customizing the JWT token. Please try again later.', - /** UNTRANSLATED */ - can_not_create_for_admin_tenant: 'Cannot create a JWT token customizer for the admin tenant.', + general: 'Ocorreu um erro ao personalizar o token JWT. Por favor, tente novamente mais tarde.', + can_not_create_for_admin_tenant: + 'Não é possível criar um personalizador de token JWT para o inquilino admin.', }; export default Object.freeze(jwt_customizer); diff --git a/packages/phrases/src/locales/pt-br/translation/admin-console/errors.ts b/packages/phrases/src/locales/pt-br/translation/admin-console/errors.ts index 276e7441b42..d0be9f5a334 100644 --- a/packages/phrases/src/locales/pt-br/translation/admin-console/errors.ts +++ b/packages/phrases/src/locales/pt-br/translation/admin-console/errors.ts @@ -7,8 +7,7 @@ const errors = { invalid_uri_format: 'Formato de URI inválido', invalid_origin_format: 'Formato de origem de URI inválido', invalid_json_format: 'Formato JSON inválido', - /** UNTRANSLATED */ - invalid_regex: 'Invalid regular expression', + invalid_regex: 'Expressão regular inválida', invalid_error_message_format: 'O formato da mensagem de erro é inválido.', required_field_missing: 'Por favor, insira {{field}}', required_field_missing_plural: 'Você deve inserir pelo menos um {{field}}', diff --git a/packages/phrases/src/locales/pt-br/translation/admin-console/general.ts b/packages/phrases/src/locales/pt-br/translation/admin-console/general.ts index a52e4b2d770..477510c5e26 100644 --- a/packages/phrases/src/locales/pt-br/translation/admin-console/general.ts +++ b/packages/phrases/src/locales/pt-br/translation/admin-console/general.ts @@ -25,11 +25,9 @@ const general = { customize: 'Personalizar', enable: 'Habilitar', reminder: 'Lembrete', - /** UNTRANSLATED */ - edit: 'Edit', + edit: 'Editar', delete: 'Excluir', - /** UNTRANSLATED */ - deleted: 'Deleted', + deleted: 'Excluído', more_options: 'MAIS OPÇÕES', close: 'Fechar', copy: 'Copiar', @@ -59,8 +57,7 @@ const general = { demo: 'Demo', unnamed: 'Sem nome', view: 'Ver', - /** UNTRANSLATED */ - open: 'Open', + open: 'Abrir', hide: 'Ocultar', unknown_error: 'Erro desconhecido, por favor tente novamente mais tarde.', select: 'Selecionar', @@ -72,8 +69,7 @@ const general = { edit_field: 'Editar {{field}}', delete_field: 'Excluir {{field}}', coming_soon: 'Em breve', - /** UNTRANSLATED */ - or: 'Or', + or: 'Ou', }; export default Object.freeze(general); diff --git a/packages/phrases/src/locales/pt-br/translation/admin-console/jwt-claims.ts b/packages/phrases/src/locales/pt-br/translation/admin-console/jwt-claims.ts index f0d189ab412..4df8bf7c977 100644 --- a/packages/phrases/src/locales/pt-br/translation/admin-console/jwt-claims.ts +++ b/packages/phrases/src/locales/pt-br/translation/admin-console/jwt-claims.ts @@ -1,98 +1,62 @@ const jwt_claims = { - /** UNTRANSLATED */ - title: 'Custom JWT', - /** UNTRANSLATED */ + title: 'JWT Personalizado', description: - 'Set up custom JWT claims to include in the access token. These claims can be used to pass additional information to your application.', + 'Configure reivindicações personalizadas no JWT para incluir no token de acesso. Essas reivindicações podem ser usadas para passar informações adicionais para sua aplicação.', user_jwt: { - /** UNTRANSLATED */ - card_title: 'For user', - /** UNTRANSLATED */ - card_field: 'User access token', - /** UNTRANSLATED */ - card_description: 'Add user-specific data during access token issuance.', - /** UNTRANSLATED */ - for: 'for user', + card_title: 'Para usuário', + card_field: 'Token de acesso do usuário', + card_description: 'Adicione dados específicos do usuário durante a emissão do token de acesso.', + for: 'para usuário', }, machine_to_machine_jwt: { - /** UNTRANSLATED */ - card_title: 'For M2M', - /** UNTRANSLATED */ - card_field: 'Machine-to-machine token', - /** UNTRANSLATED */ - card_description: 'Add extra data during machine-to-machine token issuance.', - /** UNTRANSLATED */ - for: 'for M2M', - }, - /** UNTRANSLATED */ - code_editor_title: 'Customize the {{token}} claims', - /** UNTRANSLATED */ - custom_jwt_create_button: 'Add custom claims', - /** UNTRANSLATED */ - custom_jwt_item: 'Custom claims {{for}}', - /** UNTRANSLATED */ - delete_modal_title: 'Delete custom claims', - /** UNTRANSLATED */ - delete_modal_content: 'Are you sure you want to delete the custom claims?', - /** UNTRANSLATED */ - clear: 'Clear', - /** UNTRANSLATED */ - cleared: 'Cleared', - /** UNTRANSLATED */ - restore: 'Restore defaults', - /** UNTRANSLATED */ - restored: 'Restored', - /** UNTRANSLATED */ - data_source_tab: 'Data source', - /** UNTRANSLATED */ - test_tab: 'Test context', - /** UNTRANSLATED */ - jwt_claims_description: 'Default claims are auto-included in the JWT and cannot be overridden.', + card_title: 'Para M2M', + card_field: 'Token de máquina para máquina', + card_description: 'Adicione dados extras durante a emissão do token de máquina para máquina.', + for: 'para M2M', + }, + code_editor_title: 'Personalizar as reivindicações {{token}}', + custom_jwt_create_button: 'Adicionar reivindicações personalizadas', + custom_jwt_item: 'Reivindicações personalizadas {{for}}', + delete_modal_title: 'Excluir reivindicações personalizadas', + delete_modal_content: 'Tem certeza de que deseja excluir as reivindicações personalizadas?', + clear: 'Limpar', + cleared: 'Limpado', + restore: 'Restaurar padrões', + restored: 'Restaurado', + data_source_tab: 'Fonte de dados', + test_tab: 'Contexto de teste', + jwt_claims_description: + 'As reivindicações padrão são automaticamente incluídas no JWT e não podem ser substituídas.', user_data: { - /** UNTRANSLATED */ - title: 'User data', - /** UNTRANSLATED */ - subtitle: 'Use `data.user` input parameter to provide vital user info.', + title: 'Dados do usuário', + subtitle: 'Use o parâmetro de entrada `data.user` para fornecer informações vitais do usuário.', }, token_data: { - /** UNTRANSLATED */ - title: 'Token data', - /** UNTRANSLATED */ - subtitle: 'Use `token` input parameter for current access token payload. ', + title: 'Dados do token', + subtitle: 'Use o parâmetro de entrada `token` para a carga útil do token de acesso atual. ', }, fetch_external_data: { - /** UNTRANSLATED */ - title: 'Fetch external data', - /** UNTRANSLATED */ - subtitle: 'Incorporate data from your external APIs directly into claims.', - /** UNTRANSLATED */ + title: 'Buscar dados externos', + subtitle: 'Incorpore dados de suas APIs externas diretamente nas reivindicações.', description: - 'Use the `fetch` function to call your external APIs and include the data in your custom claims. Example: ', + 'Use a função `fetch` para chamar suas APIs externas e incluir os dados em suas reivindicações personalizadas. Exemplo: ', }, environment_variables: { - /** UNTRANSLATED */ - title: 'Set environment variables', - /** UNTRANSLATED */ - subtitle: 'Use environment variables to store sensitive information.', - /** UNTRANSLATED */ - input_field_title: 'Add environment variables', - /** UNTRANSLATED */ - sample_code: 'Accessing environment variables in your custom JWT claims handler. Example: ', + title: 'Definir variáveis de ambiente', + subtitle: 'Use variáveis de ambiente para armazenar informações confidenciais.', + input_field_title: 'Adicionar variáveis de ambiente', + sample_code: + 'Acessando variáveis de ambiente no manipulador de reivindicações JWT personalizado. Exemplo: ', }, - /** UNTRANSLATED */ jwt_claims_hint: - 'Limit custom claims to under 50KB. Default JWT claims are automatically included in the token and can not be overridden.', + 'Limite as reivindicações personalizadas a menos de 50KB. As reivindicações padrão do JWT são incluídas automaticamente no token e não podem ser substituídas.', tester: { - /** UNTRANSLATED */ - subtitle: 'Adjust mock token and user data for testing.', - /** UNTRANSLATED */ - run_button: 'Run test', - /** UNTRANSLATED */ - result_title: 'Test result', + subtitle: 'Ajuste o token simulado e os dados do usuário para testar.', + run_button: 'Executar teste', + result_title: 'Resultado do teste', }, form_error: { - /** UNTRANSLATED */ - invalid_json: 'Invalid JSON format', + invalid_json: 'Formato JSON inválido', }, }; diff --git a/packages/phrases/src/locales/pt-br/translation/admin-console/subscription/quota-item.ts b/packages/phrases/src/locales/pt-br/translation/admin-console/subscription/quota-item.ts index 3c3383f15d9..ec955a8c9fb 100644 --- a/packages/phrases/src/locales/pt-br/translation/admin-console/subscription/quota-item.ts +++ b/packages/phrases/src/locales/pt-br/translation/admin-console/subscription/quota-item.ts @@ -34,16 +34,11 @@ const quota_item = { not_eligible: 'Remova suas aplicações de máquina a máquina', }, third_party_applications_limit: { - /** UNTRANSLATED */ - name: 'Third-party apps', - /** UNTRANSLATED */ - limited: '{{count, number}} third-party app', - /** UNTRANSLATED */ - limited_other: '{{count, number}} third-party apps', - /** UNTRANSLATED */ - unlimited: 'Unlimited third-party apps', - /** UNTRANSLATED */ - not_eligible: 'Remove your third-party apps', + name: 'Aplicativos de terceiros', + limited: '{{count, number}} aplicativo de terceiros', + limited_other: '{{count, number}} aplicativos de terceiros', + unlimited: 'Aplicativos de terceiros ilimitados', + not_eligible: 'Remova seus aplicativos de terceiros', }, resources_limit: { name: 'Recursos da API', @@ -152,26 +147,17 @@ const quota_item = { not_eligible: 'Remova seu Enterprise SSO', }, tenant_members_limit: { - /** UNTRANSLATED */ - name: 'Tenant members', - /** UNTRANSLATED */ - limited: '{{count, number}} tenant member', - /** UNTRANSLATED */ - limited_other: '{{count, number}} tenant members', - /** UNTRANSLATED */ - unlimited: 'Unlimited tenant members', - /** UNTRANSLATED */ - not_eligible: 'Remove your tenant members', + name: 'Membros do locatário', + limited: '{{count, number}} membro do locatário', + limited_other: '{{count, number}} membros do locatário', + unlimited: 'Membros do locatário ilimitados', + not_eligible: 'Remova seus membros do locatário', }, custom_jwt_enabled: { - /** UNTRANSLATED */ - name: 'Custom JWT', - /** UNTRANSLATED */ - limited: 'Custom JWT', - /** UNTRANSLATED */ - unlimited: 'Custom JWT', - /** UNTRANSLATED */ - not_eligible: 'Remove your JWT claims customizer', + name: 'JWT personalizado', + limited: 'JWT personalizado', + unlimited: 'JWT personalizado', + not_eligible: 'Remova seu personalizador de declarações JWT', }, }; diff --git a/packages/phrases/src/locales/pt-br/translation/admin-console/subscription/quota-table.ts b/packages/phrases/src/locales/pt-br/translation/admin-console/subscription/quota-table.ts index daed49af69f..0de0c318b8b 100644 --- a/packages/phrases/src/locales/pt-br/translation/admin-console/subscription/quota-table.ts +++ b/packages/phrases/src/locales/pt-br/translation/admin-console/subscription/quota-table.ts @@ -9,8 +9,7 @@ const quota_table = { title: 'Aplicações', total: 'Total de aplicações', m2m: 'Aplicação máquina-a-máquina', - /** UNTRANSLATED */ - third_party: 'Third-party apps', + third_party: 'Aplicativos de terceiros', }, resource: { title: 'Recursos de API', @@ -66,16 +65,11 @@ const quota_table = { hipaa_or_baa_report: 'Relatório HIPAA/BAA', }, developers_and_platform: { - /** UNTRANSLATED */ - title: 'Developers and platform', - /** UNTRANSLATED */ + title: 'Desenvolvedores e plataforma', hooks: 'Webhooks', - /** UNTRANSLATED */ - audit_logs_retention: 'Audit logs retention', - /** UNTRANSLATED */ - jwt_claims: 'JWT claims', - /** UNTRANSLATED */ - tenant_members: 'Tenant members', + audit_logs_retention: 'Retenção de logs de auditoria', + jwt_claims: 'Reivindicações JWT', + tenant_members: 'Membros do locatário', }, unlimited: 'Ilimitado', contact: 'Contato', @@ -97,17 +91,15 @@ const quota_table = { 'Todos os tipos de tokens emitidos pelo Logto, incluindo token de acesso, token de atualização, etc.', mao_tip: 'MAO (Organização Ativa Mensal) significa o número de organizações únicas que têm pelo menos um MAU (Usuário Ativo Mensal) em um ciclo de faturamento.', - /** UNTRANSLATED */ third_party_tip: - 'Use Logto as your OIDC identity provider for third-party app sign-ins and permission grants.', + 'Use Logto como seu provedor de identidade OIDC para logins e concessões de permissão de aplicativos de terceiros.', included: 'incluído{{value, number}}', included_mao: '{{value, number}} MAO incluído', extra_quota_price: 'Então ${{value, number}} por mês / cada depois', per_month_each: '${{value, number}} por mês / cada', extra_mao_price: 'Então ${{value, number}} por MAO', per_month: '${{value, number}} por mês', - /** UNTRANSLATED */ - per_member: 'Then ${{value, number}} per member', + per_member: 'Então ${{value, number}} por membro', }; export default Object.freeze(quota_table); diff --git a/packages/phrases/src/locales/pt-br/translation/admin-console/tabs.ts b/packages/phrases/src/locales/pt-br/translation/admin-console/tabs.ts index d566da608e0..9d0bb68302a 100644 --- a/packages/phrases/src/locales/pt-br/translation/admin-console/tabs.ts +++ b/packages/phrases/src/locales/pt-br/translation/admin-console/tabs.ts @@ -14,8 +14,7 @@ const tabs = { docs: 'Documentação', tenant_settings: 'Configurações', mfa: 'Autenticação de multi-fator', - /** UNTRANSLATED */ - customize_jwt: 'Custom JWT', + customize_jwt: 'JWT Personalizado', signing_keys: 'Chaves de assinatura', organization_template: 'Modelo de organização', }; diff --git a/packages/phrases/src/locales/pt-br/translation/admin-console/upsell/index.ts b/packages/phrases/src/locales/pt-br/translation/admin-console/upsell/index.ts index 0a456c196cc..abec4033b92 100644 --- a/packages/phrases/src/locales/pt-br/translation/admin-console/upsell/index.ts +++ b/packages/phrases/src/locales/pt-br/translation/admin-console/upsell/index.ts @@ -35,8 +35,7 @@ const upsell = { api_resource: 'Recurso de API', machine_to_machine: 'aplicação máquina a máquina', tokens: '{{limit}}M tokens', - /** UNTRANSLATED */ - tenant_member: 'tenant member', + tenant_member: 'membro do inquilino', }, charge_notification_for_quota_limit: 'Você ultrapassou o limite de sua cota de {{item}}. O Logto adicionará cobranças pelo uso além do limite da cota. A cobrança começará no dia em que o novo design de preços do complemento for lançado. Saiba mais', diff --git a/packages/phrases/src/locales/pt-br/translation/admin-console/upsell/paywall.ts b/packages/phrases/src/locales/pt-br/translation/admin-console/upsell/paywall.ts index 09cf372a702..498d121a5ea 100644 --- a/packages/phrases/src/locales/pt-br/translation/admin-console/upsell/paywall.ts +++ b/packages/phrases/src/locales/pt-br/translation/admin-console/upsell/paywall.ts @@ -52,24 +52,18 @@ const paywall = { mfa: 'Desbloqueie o MFA para verificar a segurança, fazendo upgrade para um plano pago. Não hesite em nos contatar se precisar de alguma assistência.', organizations: 'Desbloqueie organizações ao fazer upgrade para um plano pago. Não hesite em entrar em contato conosco se precisar de alguma assistência.', - /** UNTRANSLATED */ third_party_apps: - 'Unlock Logto as IdP for third-party apps by upgrading to a paid plan. For any assistance, feel free to contact us.', - /** UNTRANSLATED */ + 'Desbloqueie Logto como provedor de identidade para aplicativos de terceiros, ao fazer upgrade para um plano pago. Para qualquer ajuda, sinta-se à vontade para entrar em contato conosco.', sso_connectors: - 'Unlock enterprise sso by upgrading to a paid plan. For any assistance, feel free to contact us.', - /** UNTRANSLATED */ + 'Desbloqueie SSO corporativo ao fazer upgrade para um plano pago. Para qualquer ajuda, sinta-se à vontade para entrar em contato conosco.', tenant_members: - 'Unlock collaboration feature by upgrading to a paid plan. For any assistance, feel free to contact us.', - /** UNTRANSLATED */ + 'Desbloqueie a funcionalidade de colaboração ao fazer upgrade para um plano pago. Para qualquer ajuda, sinta-se à vontade para entrar em contato conosco.', tenant_members_dev_plan: - "You've reached your {{limit}}-member limit. Release a member or revoke a pending invitation to add someone new. Need more seats? Feel free to contact us.", + 'Você atingiu seu limite de {{limit}} membros. Libere um membro ou revogue um convite pendente para adicionar alguém novo. Precisa de mais vagas? Fale conosco.', custom_jwt: { - /** UNTRANSLATED */ - title: 'Add custom claims', - /** UNTRANSLATED */ + title: 'Adicionar reivindicações personalizadas', description: - "Upgrade to a paid plan for custom JWT functionality and premium benefits. Don't hesitate to contact us if you have any questions.", + 'Atualize para um plano pago para funcionalidades de JWT personalizadas e benefícios premium. Não hesite em entrar em contato conosco se tiver alguma dúvida.', }, }; diff --git a/packages/phrases/src/locales/pt-pt/errors/jwt-customizer.ts b/packages/phrases/src/locales/pt-pt/errors/jwt-customizer.ts index c7c5c1e2af9..7ad726f3c86 100644 --- a/packages/phrases/src/locales/pt-pt/errors/jwt-customizer.ts +++ b/packages/phrases/src/locales/pt-pt/errors/jwt-customizer.ts @@ -1,8 +1,7 @@ const jwt_customizer = { - /** UNTRANSLATED */ - general: 'An error occurred while customizing the JWT token. Please try again later.', - /** UNTRANSLATED */ - can_not_create_for_admin_tenant: 'Cannot create a JWT token customizer for the admin tenant.', + general: 'Ocorreu um erro ao personalizar o token JWT. Por favor, tente novamente mais tarde.', + can_not_create_for_admin_tenant: + 'Não é possível criar um personalizador de token JWT para o inquilino administrativo.', }; export default Object.freeze(jwt_customizer); diff --git a/packages/phrases/src/locales/pt-pt/translation/admin-console/errors.ts b/packages/phrases/src/locales/pt-pt/translation/admin-console/errors.ts index bc91f92d62b..3ee129d4dc5 100644 --- a/packages/phrases/src/locales/pt-pt/translation/admin-console/errors.ts +++ b/packages/phrases/src/locales/pt-pt/translation/admin-console/errors.ts @@ -7,8 +7,7 @@ const errors = { invalid_uri_format: 'Formato de URI inválido', invalid_origin_format: 'Formato de origem de URI inválido', invalid_json_format: 'Formato JSON inválido', - /** UNTRANSLATED */ - invalid_regex: 'Invalid regular expression', + invalid_regex: 'Expressão regular inválida', invalid_error_message_format: 'O formato da mensagem de erro é inválido.', required_field_missing: 'Por favor, introduza {{field}}', required_field_missing_plural: 'Deve inserir pelo menos um {{field}}', @@ -19,7 +18,7 @@ const errors = { phone_pattern_error: 'O número de telefone é inválido.', insecure_contexts: 'Contextos inseguros (não HTTPS) não são compatíveis.', unexpected_error: 'Ocorreu um erro inesperado', - not_found: '404 not found', + not_found: '404 página não encontrada', create_internal_role_violation: 'Está a criar uma nova função interna que é proibida pelo Logto. Tente outro nome que não comece com "#internal:".', should_be_an_integer: 'Deve ser um inteiro.', diff --git a/packages/phrases/src/locales/pt-pt/translation/admin-console/general.ts b/packages/phrases/src/locales/pt-pt/translation/admin-console/general.ts index d2ee6be285b..c3c6a0aa6eb 100644 --- a/packages/phrases/src/locales/pt-pt/translation/admin-console/general.ts +++ b/packages/phrases/src/locales/pt-pt/translation/admin-console/general.ts @@ -25,10 +25,8 @@ const general = { customize: 'Personalizar', enable: 'Ativar', reminder: 'Lembrete', - /** UNTRANSLATED */ - edit: 'Edit', + edit: 'Editar', delete: 'Eliminar', - /** UNTRANSLATED */ deleted: 'Deleted', more_options: 'MAIS OPÇÕES', close: 'Fechar', @@ -58,8 +56,7 @@ const general = { demo: 'Demonstração', unnamed: 'Sem nome', view: 'Ver', - /** UNTRANSLATED */ - open: 'Open', + open: 'Abrir', hide: 'Esconder', unknown_error: 'Erro desconhecido, por favor tente novamente mais tarde.', select: 'Selecionar', @@ -71,8 +68,7 @@ const general = { edit_field: 'Editar {{field}}', delete_field: 'Eliminar {{field}}', coming_soon: 'Em breve', - /** UNTRANSLATED */ - or: 'Or', + or: 'Ou', }; export default Object.freeze(general); diff --git a/packages/phrases/src/locales/pt-pt/translation/admin-console/jwt-claims.ts b/packages/phrases/src/locales/pt-pt/translation/admin-console/jwt-claims.ts index f0d189ab412..3e1d1129e1f 100644 --- a/packages/phrases/src/locales/pt-pt/translation/admin-console/jwt-claims.ts +++ b/packages/phrases/src/locales/pt-pt/translation/admin-console/jwt-claims.ts @@ -1,98 +1,64 @@ const jwt_claims = { - /** UNTRANSLATED */ - title: 'Custom JWT', - /** UNTRANSLATED */ + title: 'JWT Personalizado', description: - 'Set up custom JWT claims to include in the access token. These claims can be used to pass additional information to your application.', + 'Configure reivindicações JWT personalizadas a incluir no token de acesso. Estas reivindicações podem ser usadas para passar informações adicionais para a sua aplicação.', user_jwt: { - /** UNTRANSLATED */ - card_title: 'For user', - /** UNTRANSLATED */ - card_field: 'User access token', - /** UNTRANSLATED */ - card_description: 'Add user-specific data during access token issuance.', - /** UNTRANSLATED */ - for: 'for user', + card_title: 'Para utilizador', + card_field: 'Token de acesso do utilizador', + card_description: + 'Adicione dados específicos do utilizador durante a emissão do token de acesso.', + for: 'para utilizador', }, machine_to_machine_jwt: { - /** UNTRANSLATED */ - card_title: 'For M2M', - /** UNTRANSLATED */ - card_field: 'Machine-to-machine token', - /** UNTRANSLATED */ - card_description: 'Add extra data during machine-to-machine token issuance.', - /** UNTRANSLATED */ - for: 'for M2M', + card_title: 'Para M2M', + card_field: 'Token de máquina a máquina', + card_description: 'Adicione dados extras durante a emissão do token de máquina a máquina.', + for: 'para M2M', }, - /** UNTRANSLATED */ - code_editor_title: 'Customize the {{token}} claims', - /** UNTRANSLATED */ - custom_jwt_create_button: 'Add custom claims', - /** UNTRANSLATED */ - custom_jwt_item: 'Custom claims {{for}}', - /** UNTRANSLATED */ - delete_modal_title: 'Delete custom claims', - /** UNTRANSLATED */ - delete_modal_content: 'Are you sure you want to delete the custom claims?', - /** UNTRANSLATED */ - clear: 'Clear', - /** UNTRANSLATED */ - cleared: 'Cleared', - /** UNTRANSLATED */ - restore: 'Restore defaults', - /** UNTRANSLATED */ - restored: 'Restored', - /** UNTRANSLATED */ - data_source_tab: 'Data source', - /** UNTRANSLATED */ - test_tab: 'Test context', - /** UNTRANSLATED */ - jwt_claims_description: 'Default claims are auto-included in the JWT and cannot be overridden.', + code_editor_title: 'Personalizar as reivindicações {{token}}', + custom_jwt_create_button: 'Adicionar reivindicações personalizadas', + custom_jwt_item: 'Reivindicações personalizadas {{for}}', + delete_modal_title: 'Eliminar reivindicações personalizadas', + delete_modal_content: 'Tens a certeza de que queres eliminar as reivindicações personalizadas?', + clear: 'Limpar', + cleared: 'Limpo', + restore: 'Restaurar predefinições', + restored: 'Restaurado', + data_source_tab: 'Fonte de dados', + test_tab: 'Contexto de teste', + jwt_claims_description: + 'As reivindicações predefinidas são automaticamente incluídas no JWT e não podem ser substituídas.', user_data: { - /** UNTRANSLATED */ - title: 'User data', - /** UNTRANSLATED */ - subtitle: 'Use `data.user` input parameter to provide vital user info.', + title: 'Dados do utilizador', + subtitle: + 'Utilize o parâmetro de entrada `data.user` para fornecer informações vitais do utilizador.', }, token_data: { - /** UNTRANSLATED */ - title: 'Token data', - /** UNTRANSLATED */ - subtitle: 'Use `token` input parameter for current access token payload. ', + title: 'Dados do token', + subtitle: 'Utilize o parâmetro de entrada `token` para a carga util atual do token de acesso.', }, fetch_external_data: { - /** UNTRANSLATED */ - title: 'Fetch external data', - /** UNTRANSLATED */ - subtitle: 'Incorporate data from your external APIs directly into claims.', - /** UNTRANSLATED */ + title: 'Obter dados externos', + subtitle: 'Incorpore dados das suas APIs externas diretamente nas reivindicações.', description: - 'Use the `fetch` function to call your external APIs and include the data in your custom claims. Example: ', + 'Utilize a função `fetch` para chamar as suas APIs externas e incluir os dados nas suas reivindicações personalizadas. Exemplo: ', }, environment_variables: { - /** UNTRANSLATED */ - title: 'Set environment variables', - /** UNTRANSLATED */ - subtitle: 'Use environment variables to store sensitive information.', - /** UNTRANSLATED */ - input_field_title: 'Add environment variables', - /** UNTRANSLATED */ - sample_code: 'Accessing environment variables in your custom JWT claims handler. Example: ', + title: 'Definir variáveis de ambiente', + subtitle: 'Utilize variáveis de ambiente para armazenar informações confidenciais.', + input_field_title: 'Adicionar variáveis de ambiente', + sample_code: + 'Acedendo a variáveis de ambiente no manipulador de reivindicações JWT personalizadas. Exemplo: ', }, - /** UNTRANSLATED */ jwt_claims_hint: - 'Limit custom claims to under 50KB. Default JWT claims are automatically included in the token and can not be overridden.', + 'Limite as reivindicações personalizadas a menos de 50KB. As reivindicações JWT predefinidas são automaticamente incluídas no token e não podem ser substituídas.', tester: { - /** UNTRANSLATED */ - subtitle: 'Adjust mock token and user data for testing.', - /** UNTRANSLATED */ - run_button: 'Run test', - /** UNTRANSLATED */ - result_title: 'Test result', + subtitle: 'Ajustar token falso e dados do utilizador para teste.', + run_button: 'Executar teste', + result_title: 'Resultado do teste', }, form_error: { - /** UNTRANSLATED */ - invalid_json: 'Invalid JSON format', + invalid_json: 'Formato JSON inválido', }, }; diff --git a/packages/phrases/src/locales/pt-pt/translation/admin-console/subscription/quota-item.ts b/packages/phrases/src/locales/pt-pt/translation/admin-console/subscription/quota-item.ts index fd1fe132209..af7361daf4f 100644 --- a/packages/phrases/src/locales/pt-pt/translation/admin-console/subscription/quota-item.ts +++ b/packages/phrases/src/locales/pt-pt/translation/admin-console/subscription/quota-item.ts @@ -34,16 +34,11 @@ const quota_item = { not_eligible: 'Remover as tuas aplicações de máquina para máquina', }, third_party_applications_limit: { - /** UNTRANSLATED */ - name: 'Third-party apps', - /** UNTRANSLATED */ - limited: '{{count, number}} third-party app', - /** UNTRANSLATED */ - limited_other: '{{count, number}} third-party apps', - /** UNTRANSLATED */ - unlimited: 'Unlimited third-party apps', - /** UNTRANSLATED */ - not_eligible: 'Remove your third-party apps', + name: 'Aplicações de terceiros', + limited: '{{count, number}} aplicação de terceiros', + limited_other: '{{count, number}} aplicações de terceiros', + unlimited: 'Aplicações de terceiros ilimitadas', + not_eligible: 'Remover as tuas aplicações de terceiros', }, resources_limit: { name: 'Recursos de API', @@ -152,26 +147,17 @@ const quota_item = { not_eligible: 'Remover o teu SSO Empresarial', }, tenant_members_limit: { - /** UNTRANSLATED */ - name: 'Tenant members', - /** UNTRANSLATED */ - limited: '{{count, number}} tenant member', - /** UNTRANSLATED */ - limited_other: '{{count, number}} tenant members', - /** UNTRANSLATED */ - unlimited: 'Unlimited tenant members', - /** UNTRANSLATED */ - not_eligible: 'Remove your tenant members', + name: 'Membros do inquilino', + limited: '{{count, number}} membro do inquilino', + limited_other: '{{count, number}} membros do inquilino', + unlimited: 'Membros do inquilino ilimitados', + not_eligible: 'Remove os teus membros do inquilino', }, custom_jwt_enabled: { - /** UNTRANSLATED */ - name: 'Custom JWT', - /** UNTRANSLATED */ - limited: 'Custom JWT', - /** UNTRANSLATED */ - unlimited: 'Custom JWT', - /** UNTRANSLATED */ - not_eligible: 'Remove your JWT claims customizer', + name: 'JWT personalizado', + limited: 'JWT personalizado', + unlimited: 'JWT personalizado', + not_eligible: 'Remove o teu personalizador de reivindicações JWT', }, }; diff --git a/packages/phrases/src/locales/pt-pt/translation/admin-console/subscription/quota-table.ts b/packages/phrases/src/locales/pt-pt/translation/admin-console/subscription/quota-table.ts index b5baaeb2395..8e42e27eb38 100644 --- a/packages/phrases/src/locales/pt-pt/translation/admin-console/subscription/quota-table.ts +++ b/packages/phrases/src/locales/pt-pt/translation/admin-console/subscription/quota-table.ts @@ -9,8 +9,7 @@ const quota_table = { title: 'Aplicações', total: 'Total de aplicações', m2m: 'Aplicações de máquina para máquina', - /** UNTRANSLATED */ - third_party: 'Third-party apps', + third_party: 'Aplicações de terceiros', }, resource: { title: 'Recursos da API', @@ -66,16 +65,11 @@ const quota_table = { hipaa_or_baa_report: 'Relatório HIPAA/BAA', }, developers_and_platform: { - /** UNTRANSLATED */ - title: 'Developers and platform', - /** UNTRANSLATED */ + title: 'Programadores e plataforma', hooks: 'Webhooks', - /** UNTRANSLATED */ - audit_logs_retention: 'Audit logs retention', - /** UNTRANSLATED */ - jwt_claims: 'JWT claims', - /** UNTRANSLATED */ - tenant_members: 'Tenant members', + audit_logs_retention: 'Retenção de registos de auditoria', + jwt_claims: 'Reivindicações JWT', + tenant_members: 'Membros do inquilino', }, unlimited: 'Ilimitado', contact: 'Contactar', @@ -97,17 +91,15 @@ const quota_table = { 'Todos os tipos de tokens emitidos pelo Logto, incluindo token de acesso, token de atualização, etc.', mao_tip: 'MAO (Organização Ativa Mensal) significa o número de organizações únicas que têm pelo menos um MAU (Utilizador Ativo Mensal) num ciclo de faturação.', - /** UNTRANSLATED */ third_party_tip: - 'Use Logto as your OIDC identity provider for third-party app sign-ins and permission grants.', + 'Utilize o Logto como o seu fornecedor de identidade OIDC para inícios de sessão de aplicações de terceiros e outorga de permissões.', included: 'incluído{{value, number}}', included_mao: '{{value, number}} MAO incluída', extra_quota_price: 'Depois ${{value, number}} por mês / cada um depois', per_month_each: '${{value, number}} por mês / cada um', extra_mao_price: 'Depois ${{value, number}} por MAO', per_month: '${{value, number}} por mês', - /** UNTRANSLATED */ - per_member: 'Then ${{value, number}} per member', + per_member: 'Depois ${{value, number}} por membro', }; export default Object.freeze(quota_table); diff --git a/packages/phrases/src/locales/pt-pt/translation/admin-console/tabs.ts b/packages/phrases/src/locales/pt-pt/translation/admin-console/tabs.ts index 214f83aa020..2e204428de0 100644 --- a/packages/phrases/src/locales/pt-pt/translation/admin-console/tabs.ts +++ b/packages/phrases/src/locales/pt-pt/translation/admin-console/tabs.ts @@ -14,8 +14,7 @@ const tabs = { docs: 'Documentação', tenant_settings: 'Definições do inquilino', mfa: 'Autenticação multi-fator', - /** UNTRANSLATED */ - customize_jwt: 'Custom JWT', + customize_jwt: 'JWT personalizado', signing_keys: 'Chaves de assinatura', organization_template: 'Modelo de organização', }; diff --git a/packages/phrases/src/locales/pt-pt/translation/admin-console/upsell/index.ts b/packages/phrases/src/locales/pt-pt/translation/admin-console/upsell/index.ts index 0a456c196cc..abec4033b92 100644 --- a/packages/phrases/src/locales/pt-pt/translation/admin-console/upsell/index.ts +++ b/packages/phrases/src/locales/pt-pt/translation/admin-console/upsell/index.ts @@ -35,8 +35,7 @@ const upsell = { api_resource: 'Recurso de API', machine_to_machine: 'aplicação máquina a máquina', tokens: '{{limit}}M tokens', - /** UNTRANSLATED */ - tenant_member: 'tenant member', + tenant_member: 'membro do inquilino', }, charge_notification_for_quota_limit: 'Você ultrapassou o limite de sua cota de {{item}}. O Logto adicionará cobranças pelo uso além do limite da cota. A cobrança começará no dia em que o novo design de preços do complemento for lançado. Saiba mais', diff --git a/packages/phrases/src/locales/pt-pt/translation/admin-console/upsell/paywall.ts b/packages/phrases/src/locales/pt-pt/translation/admin-console/upsell/paywall.ts index 4093bc456d6..d6affc63b3f 100644 --- a/packages/phrases/src/locales/pt-pt/translation/admin-console/upsell/paywall.ts +++ b/packages/phrases/src/locales/pt-pt/translation/admin-console/upsell/paywall.ts @@ -1,75 +1,69 @@ const paywall = { applications: - 'Limite de {{count, number}} aplicação do atingido. Atualize o plano para atender às necessidades da sua equipa. Para obter qualquer ajuda, sinta-se à vontade para entrar em contato conosco.', + 'Limite de {{count, number}} aplicação do plano atingido. Atualize o plano para atender às necessidades da sua equipa. Para obter qualquer ajuda, sinta-se à vontade para entrar em contacto connosco.', applications_other: - 'Limite de {{count, number}} aplicações do atingido. Atualize o plano para atender às necessidades da sua equipa. Para obter qualquer ajuda, sinta-se à vontade para entrar em contato conosco.', + 'Limite de {{count, number}} aplicações do plano atingido. Atualize o plano para atender às necessidades da sua equipa. Para obter qualquer ajuda, sinta-se à vontade para entrar em contacto connosco.', machine_to_machine_feature: - 'Mude para o plano Pro para obter aplicações adicionais de máquina a máquina e aproveitar todos os recursos premium. Entre em contato conosco se tiver dúvidas.', + 'Mude para o plano Pro para obter aplicações adicionais de máquina a máquina e aproveitar todos os recursos premium. Entre em contacto connosco se tiver dúvidas.', machine_to_machine: - 'Limite de {{count, number}} aplicação de máquina a máquina do atingido. Atualize o plano para atender às necessidades da sua equipe. Para obter qualquer ajuda, sinta-se à vontade para entrar em contato conosco.', + 'Limite de {{count, number}} aplicação de máquina a máquina do plano atingido. Atualize o plano para atender às necessidades da sua equipa. Para obter qualquer ajuda, sinta-se à vontade para entrar em contacto connosco.', machine_to_machine_other: - 'Limite de {{count, number}} aplicações de máquina a máquina do atingido. Atualize o plano para atender às necessidades da sua equipe. Para obter qualquer ajuda, sinta-se à vontade para entrar em contato conosco.', + 'Limite de {{count, number}} aplicações de máquina a máquina do plano atingido. Atualize o plano para atender às necessidades da sua equipa. Para obter qualquer ajuda, sinta-se à vontade para entrar em contacto connosco.', resources: - 'Atingiu o limite de {{count, number}} recursos de API de . Atualize o plano para satisfazer as necessidades da sua equipa. Contacte-nos se precisar de assistência.', + 'Atingiu o limite de {{count, number}} recursos de API do plano . Atualize o plano para satisfazer as necessidades da sua equipa. Contacte-nos se precisar de assistência.', resources_other: - 'Atingiu o limite de {{count, number}} recursos de API de . Atualize o plano para satisfazer as necessidades da sua equipa. Contacte-nos se precisar de assistência.', + 'Atingiu o limite de {{count, number}} recursos de API do plano . Atualize o plano para satisfazer as necessidades da sua equipa. Contacte-nos se precisar de assistência.', scopes_per_resource: - 'Atingiu o limite de {{count, number}} permissões por recurso de API de . Atualize agora para expandir. Contacte-nos se precisar de assistência.', + 'Atingiu o limite de {{count, number}} permissões por recurso de API do plano . Atualize agora para expandir. Contacte-nos se precisar de assistência.', scopes_per_resource_other: - 'Atingiu o limite de {{count, number}} permissões por recurso de API de . Atualize agora para expandir. Contacte-nos se precisar de assistência.', + 'Atingiu o limite de {{count, number}} permissões por recurso de API do plano . Atualize agora para expandir. Contacte-nos se precisar de assistência.', custom_domain: - 'Desbloqueie a funcionalidade de domínio personalizado ao atualizar para o plano Hobby ou Pro. Não hesite em entrar em contato conosco se precisar de qualquer assistência.', + 'Desbloqueie a funcionalidade de domínio personalizado ao atualizar para o plano Hobby ou Pro. Não hesite em entrar em contacto connosco se precisar de qualquer assistência.', social_connectors: - 'Atingiu o limite de {{count, number}} conectores sociais de . Atualize o plano para obter conectores sociais adicionais e a capacidade de criar os seus próprios conectores usando os protocolos OIDC, OAuth 2.0 e SAML. Não hesite em Contacte-nos se precisar de ajuda.', + 'Atingiu o limite de {{count, number}} conectores sociais do plano . Atualize o plano para obter conectores sociais adicionais e a capacidade de criar os seus próprios conectores usando os protocolos OIDC, OAuth 2.0 e SAML. Não hesite em Contacte-nos se precisar de ajuda.', social_connectors_other: - 'Atingiu o limite de {{count, number}} conectores sociais de . Atualize o plano para obter conectores sociais adicionais e a capacidade de criar os seus próprios conectores usando os protocolos OIDC, OAuth 2.0 e SAML. Não hesite em Contacte-nos se precisar de ajuda.', + 'Atingiu o limite de {{count, number}} conectores sociais do plano . Atualize o plano para obter conectores sociais adicionais e a capacidade de criar os seus próprios conectores usando os protocolos OIDC, OAuth 2.0 e SAML. Não hesite em Contacte-nos se precisar de ajuda.', standard_connectors_feature: - 'Upgrade para os planos Hobby ou Pro para criar os seus próprios conectores usando os protocolos OIDC, OAuth 2.0 e SAML, além de conectores sociais ilimitados e todos os recursos premium. Sinta-se à vontade para entrar em contato conosco se precisar de qualquer assistência.', + 'Upgrade para os planos Hobby ou Pro para criar os seus próprios conectores usando os protocolos OIDC, OAuth 2.0 e SAML, além de conectores sociais ilimitados e todos os recursos premium. Sinta-se à vontade para entrar em contacto connosco se precisar de qualquer assistência.', standard_connectors: - 'Atingiu o limite de {{count, number}} conectores sociais de . Atualize o plano para obter conectores sociais adicionais e a capacidade de criar os seus próprios conectores usando os protocolos OIDC, OAuth 2.0 e SAML. Não hesite em Contacte-nos se precisar de ajuda.', + 'Atingiu o limite de {{count, number}} conectores sociais do plano . Atualize o plano para obter conectores sociais adicionais e a capacidade de criar os seus próprios conectores usando os protocolos OIDC, OAuth 2.0 e SAML. Não hesite em Contacte-nos se precisar de ajuda.', standard_connectors_other: - 'Atingiu o limite de {{count, number}} conectores sociais de . Atualize o plano para obter conectores sociais adicionais e a capacidade de criar os seus próprios conectores usando os protocolos OIDC, OAuth 2.0 e SAML. Não hesite em Contacte-nos se precisar de ajuda.', + 'Atingiu o limite de {{count, number}} conectores sociais do plano . Atualize o plano para obter conectores sociais adicionais e a capacidade de criar os seus próprios conectores usando os protocolos OIDC, OAuth 2.0 e SAML. Não hesite em Contacte-nos se precisar de ajuda.', standard_connectors_pro: - 'Atingiu o limite de {{count, number}} conectores padrão de . Atualize para o plano Empresarial para obter conectores sociais adicionais e a capacidade de criar os seus próprios conectores usando os protocolos OIDC, OAuth 2.0 e SAML. Não hesite em Contacte-nos se precisar de ajuda.', + 'Atingiu o limite de {{count, number}} conectores padrão do plano . Atualize para o plano Empresarial para obter conectores sociais adicionais e a capacidade de criar os seus próprios conectores usando os protocolos OIDC, OAuth 2.0 e SAML. Não hesite em Contacte-nos se precisar de ajuda.', standard_connectors_pro_other: - 'Atingiu o limite de {{count, number}} conectores padrão de . Atualize para o plano Empresarial para obter conectores sociais adicionais e a capacidade de criar os seus próprios conectores usando os protocolos OIDC, OAuth 2.0 e SAML. Não hesite em Contacte-nos se precisar de ajuda.', + 'Atingiu o limite de {{count, number}} conectores padrão do plano . Atualize para o plano Empresarial para obter conectores sociais adicionais e a capacidade de criar os seus próprios conectores usando os protocolos OIDC, OAuth 2.0 e SAML. Não hesite em Contacte-nos se precisar de ajuda.', roles: - 'Atingiu o limite de {{count, number}} funções de . Atualize o plano para adicionar funções e permissões adicionais. Não hesite em Contacte-nos se precisar de ajuda.', + 'Atingiu o limite de {{count, number}} funções do plano . Atualize o plano para adicionar funções e permissões adicionais. Não hesite em Contacte-nos se precisar de ajuda.', roles_other: - 'Atingiu o limite de {{count, number}} funções de . Atualize o plano para adicionar funções e permissões adicionais. Não hesite em Contacte-nos se precisar de ajuda.', + 'Atingiu o limite de {{count, number}} funções do plano . Atualize o plano para adicionar funções e permissões adicionais. Não hesite em Contacte-nos se precisar de ajuda.', machine_to_machine_roles: - '{{count, number}} papel de máquina a máquina de atingido. Atualize o plano para adicionar papéis e permissões adicionais. Sinta-se à vontade para entrar em contato conosco se precisar de ajuda.', + '{{count, number}} papel de máquina a máquina do plano atingido. Atualize o plano para adicionar papéis e permissões adicionais. Sinta-se à vontade para entrar em contacto connosco se precisar de ajuda.', machine_to_machine_roles_other: - '{{count, number}} papéis de máquina a máquina de atingidos. Atualize o plano para adicionar papéis e permissões adicionais. Sinta-se à vontade para entrar em contato conosco se precisar de ajuda.', + '{{count, number}} papéis de máquina a máquina do plano atingidos. Atualize o plano para adicionar papéis e permissões adicionais. Sinta-se à vontade para entrar em contacto connosco se precisar de ajuda.', scopes_per_role: - 'Atingiu o limite de {{count, number}} permissões por função de . Atualize o plano para adicionar funções e permissões adicionais. Não hesite em Contacte-nos se precisar de ajuda.', + 'Atingiu o limite de {{count, number}} permissões por função do plano . Atualize o plano para adicionar funções e permissões adicionais. Não hesite em Contacte-nos se precisar de ajuda.', scopes_per_role_other: - 'Atingiu o limite de {{count, number}} permissões por função de . Atualize o plano para adicionar funções e permissões adicionais. Não hesite em Contacte-nos se precisar de ajuda.', + 'Atingiu o limite de {{count, number}} permissões por função do plano . Atualize o plano para adicionar funções e permissões adicionais. Não hesite em Contacte-nos se precisar de ajuda.', hooks: - 'Atingiu o limite de {{count, number}} webhooks de . Atualize o plano para criar mais webhooks. Não hesite em Contacte-nos se precisar de ajuda.', + 'Atingiu o limite de {{count, number}} webhooks do plano . Atualize o plano para criar mais webhooks. Não hesite em Contacte-nos se precisar de ajuda.', hooks_other: - 'Atingiu o limite de {{count, number}} webhooks de . Atualize o plano para criar mais webhooks. Não hesite em Contacte-nos se precisar de ajuda.', - mfa: 'Desbloqueie o MFA para a verificação de segurança ao atualizar para um plano pago. Não hesite em entrar em contato conosco se precisar de assistência.', + 'Atingiu o limite de {{count, number}} webhooks do plano . Atualize o plano para criar mais webhooks. Não hesite em Contacte-nos se precisar de ajuda.', + mfa: 'Desbloqueie o MFA para a verificação de segurança ao atualizar para um plano pago. Não hesite em entrar em contacto connosco se precisar de assistência.', organizations: - 'Desbloquear organizações ao atualizar para um plano pago. Não hesite em entrar em contato conosco se precisar de assistência.', - /** UNTRANSLATED */ + 'Desbloquear organizações ao atualizar para um plano pago. Não hesite em entrar em contacto connosco se precisar de assistência.', third_party_apps: - 'Unlock Logto as IdP for third-party apps by upgrading to a paid plan. For any assistance, feel free to contact us.', - /** UNTRANSLATED */ + 'Desbloqueie o Logto como IdP para aplicações de terceiros ao atualizar para um plano pago. Para qualquer assistência, sinta-se à vontade para contactar-nos.', sso_connectors: - 'Unlock enterprise sso by upgrading to a paid plan. For any assistance, feel free to contact us.', - /** UNTRANSLATED */ + 'Desbloqueie o SSO empresarial ao atualizar para um plano pago. Para qualquer assistência, sinta-se à vontade para contactar-nos.', tenant_members: - 'Unlock collaboration feature by upgrading to a paid plan. For any assistance, feel free to contact us.', - /** UNTRANSLATED */ + 'Desbloqueie a funcionalidade de colaboração ao atualizar para um plano pago. Para qualquer assistência, sinta-se à vontade para contactar-nos.', tenant_members_dev_plan: - "You've reached your {{limit}}-member limit. Release a member or revoke a pending invitation to add someone new. Need more seats? Feel free to contact us.", + 'Chegou ao seu limite de {{limit}} membros. Liberte um membro ou revoque um convite pendente para adicionar alguém novo. Precisa de mais lugares? Sinta-se à vontade para contactar-nos.', custom_jwt: { - /** UNTRANSLATED */ - title: 'Add custom claims', - /** UNTRANSLATED */ + title: 'Adicionar alegações personalizadas', description: - "Upgrade to a paid plan for custom JWT functionality and premium benefits. Don't hesitate to contact us if you have any questions.", + 'Atualize para um plano pago para funcionalidade personalizada JWT e benefícios premium. Não hesite em contactar-nos se tiver alguma dúvida.', }, }; diff --git a/packages/phrases/src/locales/ru/errors/jwt-customizer.ts b/packages/phrases/src/locales/ru/errors/jwt-customizer.ts index c7c5c1e2af9..d6f1bbccc2a 100644 --- a/packages/phrases/src/locales/ru/errors/jwt-customizer.ts +++ b/packages/phrases/src/locales/ru/errors/jwt-customizer.ts @@ -1,8 +1,7 @@ const jwt_customizer = { - /** UNTRANSLATED */ - general: 'An error occurred while customizing the JWT token. Please try again later.', - /** UNTRANSLATED */ - can_not_create_for_admin_tenant: 'Cannot create a JWT token customizer for the admin tenant.', + general: 'Произошла ошибка при настройке JWT-токена. Пожалуйста, попробуйте снова позже.', + can_not_create_for_admin_tenant: + 'Невозможно создать настраиваемый JWT-токен для административного арендатора.', }; export default Object.freeze(jwt_customizer); diff --git a/packages/phrases/src/locales/ru/translation/admin-console/errors.ts b/packages/phrases/src/locales/ru/translation/admin-console/errors.ts index 470ef760dcc..41e1d30d537 100644 --- a/packages/phrases/src/locales/ru/translation/admin-console/errors.ts +++ b/packages/phrases/src/locales/ru/translation/admin-console/errors.ts @@ -7,8 +7,7 @@ const errors = { invalid_uri_format: 'Неверный формат URI', invalid_origin_format: 'Неверный формат URI-оригинала', invalid_json_format: 'Неверный формат JSON', - /** UNTRANSLATED */ - invalid_regex: 'Invalid regular expression', + invalid_regex: 'Неверное регулярное выражение', invalid_error_message_format: 'Неверный формат сообщения об ошибке.', required_field_missing: 'Пожалуйста, введите {{field}}', required_field_missing_plural: 'Вы должны ввести хотя бы одно {{field}}', diff --git a/packages/phrases/src/locales/ru/translation/admin-console/general.ts b/packages/phrases/src/locales/ru/translation/admin-console/general.ts index 00b62d2d9d3..c4dcd3993d5 100644 --- a/packages/phrases/src/locales/ru/translation/admin-console/general.ts +++ b/packages/phrases/src/locales/ru/translation/admin-console/general.ts @@ -25,11 +25,9 @@ const general = { customize: 'Настроить', enable: 'Включить', reminder: 'Напоминание', - /** UNTRANSLATED */ - edit: 'Edit', + edit: 'Редактировать', delete: 'Удалить', - /** UNTRANSLATED */ - deleted: 'Deleted', + deleted: 'Удалено', more_options: 'Дополнительные опции', close: 'Закрыть', copy: 'Копировать', @@ -58,8 +56,7 @@ const general = { demo: 'Демо', unnamed: 'Без названия', view: 'Просмотр', - /** UNTRANSLATED */ - open: 'Open', + open: 'Открыть', hide: 'Скрыть', unknown_error: 'Неизвестная ошибка, пожалуйста, попробуйте позже.', select: 'Выбрать', @@ -71,8 +68,7 @@ const general = { edit_field: 'Изменить {{field}}', delete_field: 'Удалить {{field}}', coming_soon: 'Скоро', - /** UNTRANSLATED */ - or: 'Or', + or: 'Или', }; export default Object.freeze(general); diff --git a/packages/phrases/src/locales/ru/translation/admin-console/jwt-claims.ts b/packages/phrases/src/locales/ru/translation/admin-console/jwt-claims.ts index f0d189ab412..2bcaa2e38f8 100644 --- a/packages/phrases/src/locales/ru/translation/admin-console/jwt-claims.ts +++ b/packages/phrases/src/locales/ru/translation/admin-console/jwt-claims.ts @@ -1,98 +1,63 @@ const jwt_claims = { - /** UNTRANSLATED */ - title: 'Custom JWT', - /** UNTRANSLATED */ + title: 'Пользовательский JWT', description: - 'Set up custom JWT claims to include in the access token. These claims can be used to pass additional information to your application.', + 'Настройте пользовательские утверждения JWT для включения в токен доступа. Эти утверждения могут использоваться для передачи дополнительной информации в ваше приложение.', user_jwt: { - /** UNTRANSLATED */ - card_title: 'For user', - /** UNTRANSLATED */ - card_field: 'User access token', - /** UNTRANSLATED */ - card_description: 'Add user-specific data during access token issuance.', - /** UNTRANSLATED */ - for: 'for user', + card_title: 'Для пользователя', + card_field: 'Токен доступа пользователя', + card_description: + 'Добавление специфичных для пользователя данных во время выдачи токена доступа.', + for: 'для пользователя', }, machine_to_machine_jwt: { - /** UNTRANSLATED */ - card_title: 'For M2M', - /** UNTRANSLATED */ - card_field: 'Machine-to-machine token', - /** UNTRANSLATED */ - card_description: 'Add extra data during machine-to-machine token issuance.', - /** UNTRANSLATED */ - for: 'for M2M', + card_title: 'Для М2М', + card_field: 'Токен от машины к машине', + card_description: 'Добавление дополнительных данных во время выдачи токена от машины к машине.', + for: 'для М2М', }, - /** UNTRANSLATED */ - code_editor_title: 'Customize the {{token}} claims', - /** UNTRANSLATED */ - custom_jwt_create_button: 'Add custom claims', - /** UNTRANSLATED */ - custom_jwt_item: 'Custom claims {{for}}', - /** UNTRANSLATED */ - delete_modal_title: 'Delete custom claims', - /** UNTRANSLATED */ - delete_modal_content: 'Are you sure you want to delete the custom claims?', - /** UNTRANSLATED */ - clear: 'Clear', - /** UNTRANSLATED */ - cleared: 'Cleared', - /** UNTRANSLATED */ - restore: 'Restore defaults', - /** UNTRANSLATED */ - restored: 'Restored', - /** UNTRANSLATED */ - data_source_tab: 'Data source', - /** UNTRANSLATED */ - test_tab: 'Test context', - /** UNTRANSLATED */ - jwt_claims_description: 'Default claims are auto-included in the JWT and cannot be overridden.', + code_editor_title: 'Настройка своих утверждений {{token}}', + custom_jwt_create_button: 'Добавить пользовательские утверждения', + custom_jwt_item: 'Пользовательские утверждения {{for}}', + delete_modal_title: 'Удалить пользовательские утверждения', + delete_modal_content: 'Вы уверены, что хотите удалить пользовательские утверждения?', + clear: 'Очистить', + cleared: 'Очищено', + restore: 'Восстановить по умолчанию', + restored: 'Восстановлено', + data_source_tab: 'Источник данных', + test_tab: 'Тестовый контекст', + jwt_claims_description: + 'Утверждения по умолчанию автоматически включаются в JWT и не могут быть переопределены.', user_data: { - /** UNTRANSLATED */ - title: 'User data', - /** UNTRANSLATED */ - subtitle: 'Use `data.user` input parameter to provide vital user info.', + title: 'Данные пользователя', + subtitle: + 'Используйте параметр ввода `data.user` для предоставления важной информации о пользователе.', }, token_data: { - /** UNTRANSLATED */ - title: 'Token data', - /** UNTRANSLATED */ - subtitle: 'Use `token` input parameter for current access token payload. ', + title: 'Данные токена', + subtitle: 'Используйте параметр ввода `token` для полезной нагрузки текущего токена доступа. ', }, fetch_external_data: { - /** UNTRANSLATED */ - title: 'Fetch external data', - /** UNTRANSLATED */ - subtitle: 'Incorporate data from your external APIs directly into claims.', - /** UNTRANSLATED */ + title: 'Получение внешних данных', + subtitle: 'Интегрирование данных непосредственно из ваших внешних API в утверждения.', description: - 'Use the `fetch` function to call your external APIs and include the data in your custom claims. Example: ', + 'Используйте функцию `fetch` для вызова ваших внешних API и включения данных в ваши пользовательские утверждения. Пример: ', }, environment_variables: { - /** UNTRANSLATED */ - title: 'Set environment variables', - /** UNTRANSLATED */ - subtitle: 'Use environment variables to store sensitive information.', - /** UNTRANSLATED */ - input_field_title: 'Add environment variables', - /** UNTRANSLATED */ - sample_code: 'Accessing environment variables in your custom JWT claims handler. Example: ', + title: 'Установка переменных среды', + subtitle: 'Используйте переменные среды для хранения конфиденциальной информации.', + input_field_title: 'Добавить переменные среды', + sample_code: 'Доступ к переменным среды в вашем обработчике утверждений JWT. Пример: ', }, - /** UNTRANSLATED */ jwt_claims_hint: - 'Limit custom claims to under 50KB. Default JWT claims are automatically included in the token and can not be overridden.', + 'Ограничьте пользовательские утверждения до 50 КБ. Утверждения по умолчанию JWT автоматически включаются в токен и не могут быть переопределены.', tester: { - /** UNTRANSLATED */ - subtitle: 'Adjust mock token and user data for testing.', - /** UNTRANSLATED */ - run_button: 'Run test', - /** UNTRANSLATED */ - result_title: 'Test result', + subtitle: 'Настройте макетный токен и данные пользователя для тестирования.', + run_button: 'Запустить тест', + result_title: 'Результат теста', }, form_error: { - /** UNTRANSLATED */ - invalid_json: 'Invalid JSON format', + invalid_json: 'Недопустимый формат JSON', }, }; diff --git a/packages/phrases/src/locales/ru/translation/admin-console/subscription/quota-item.ts b/packages/phrases/src/locales/ru/translation/admin-console/subscription/quota-item.ts index 4c03b46aad3..1ca3349c7b7 100644 --- a/packages/phrases/src/locales/ru/translation/admin-console/subscription/quota-item.ts +++ b/packages/phrases/src/locales/ru/translation/admin-console/subscription/quota-item.ts @@ -34,16 +34,11 @@ const quota_item = { not_eligible: 'Удалите свои приложения для машин ко машине', }, third_party_applications_limit: { - /** UNTRANSLATED */ - name: 'Third-party apps', - /** UNTRANSLATED */ - limited: '{{count, number}} third-party app', - /** UNTRANSLATED */ - limited_other: '{{count, number}} third-party apps', - /** UNTRANSLATED */ - unlimited: 'Unlimited third-party apps', - /** UNTRANSLATED */ - not_eligible: 'Remove your third-party apps', + name: 'Приложения сторонних разработчиков', + limited: '{{count, number}} приложение сторонних разработчиков', + limited_other: '{{count, number}} приложения сторонних разработчиков', + unlimited: 'Неограниченное количество приложений сторонних разработчиков', + not_eligible: 'Удалите свои приложения сторонних разработчиков', }, resources_limit: { name: 'API ресурсы', @@ -152,26 +147,17 @@ const quota_item = { not_eligible: 'Удалите свой Единый вход для предприятий', }, tenant_members_limit: { - /** UNTRANSLATED */ - name: 'Tenant members', - /** UNTRANSLATED */ - limited: '{{count, number}} tenant member', - /** UNTRANSLATED */ - limited_other: '{{count, number}} tenant members', - /** UNTRANSLATED */ - unlimited: 'Unlimited tenant members', - /** UNTRANSLATED */ - not_eligible: 'Remove your tenant members', + name: 'Участники арендаторов', + limited: '{{count, number}} участник арендатора', + limited_other: '{{count, number}} участников арендатора', + unlimited: 'Неограниченное количество участников арендатора', + not_eligible: 'Удалите своих участников арендатора', }, custom_jwt_enabled: { - /** UNTRANSLATED */ - name: 'Custom JWT', - /** UNTRANSLATED */ - limited: 'Custom JWT', - /** UNTRANSLATED */ - unlimited: 'Custom JWT', - /** UNTRANSLATED */ - not_eligible: 'Remove your JWT claims customizer', + name: 'Пользовательский JWT', + limited: 'Пользовательский JWT', + unlimited: 'Пользовательский JWT', + not_eligible: 'Удалите свой настраиваемый создатель токенов JWT', }, }; diff --git a/packages/phrases/src/locales/ru/translation/admin-console/subscription/quota-table.ts b/packages/phrases/src/locales/ru/translation/admin-console/subscription/quota-table.ts index 9310d0f284a..d2003510c7a 100644 --- a/packages/phrases/src/locales/ru/translation/admin-console/subscription/quota-table.ts +++ b/packages/phrases/src/locales/ru/translation/admin-console/subscription/quota-table.ts @@ -9,8 +9,7 @@ const quota_table = { title: 'Приложения', total: 'Всего приложений', m2m: 'Приложения "машина-машина"', - /** UNTRANSLATED */ - third_party: 'Third-party apps', + third_party: 'Приложения третьих сторон', }, resource: { title: 'Ресурсы API', @@ -66,24 +65,19 @@ const quota_table = { hipaa_or_baa_report: 'Отчет HIPAA/BAA', }, developers_and_platform: { - /** UNTRANSLATED */ - title: 'Developers and platform', - /** UNTRANSLATED */ + title: 'Разработчики и платформа', hooks: 'Webhooks', - /** UNTRANSLATED */ - audit_logs_retention: 'Audit logs retention', - /** UNTRANSLATED */ - jwt_claims: 'JWT claims', - /** UNTRANSLATED */ - tenant_members: 'Tenant members', + audit_logs_retention: 'Сохранение журналов аудита', + jwt_claims: 'JWT утверждения', + tenant_members: 'Члены арендаторов', }, unlimited: 'Неограниченно', contact: 'Связаться', - monthly_price: '${{value, number}}/мес.', + monthly_price: '$ {{value, number}} /мес.', days_one: '{{count, number}} день', days_other: '{{count, number}} дней', add_on: 'Дополнительно', - tier: 'Уровень{{value, number}}: ', + tier: 'Уровень {{value, number}}: ', paid_token_limit_tip: 'Logto будет взимать плату за функции, выходящие за пределы вашего квоты. Вы можете использовать его бесплатно до начала начисления сборов, примерно со второго квартала 2024 года. Если вам нужны дополнительные токены, свяжитесь с нами. По умолчанию мы выставляем счет в $80 в месяц за каждый миллион токенов.', paid_quota_limit_tip: @@ -97,17 +91,15 @@ const quota_table = { 'Все виды токенов, выпущенных Logto, включая токены доступа, токены обновления и т. д.', mao_tip: 'MAO (ежемесячно активная организация) означает количество уникальных организаций, у которых есть хотя бы один MAU (ежемесячно активный пользователь) в биллинговом цикле.', - /** UNTRANSLATED */ third_party_tip: - 'Use Logto as your OIDC identity provider for third-party app sign-ins and permission grants.', - included: 'включено{{value, number}}', + 'Используйте Logto в качестве поставщика идентификации OIDC для входа в сторонние приложения и предоставления разрешений.', + included: 'включено {{value, number}}', included_mao: '{{value, number}} MAO включено', - extra_quota_price: 'Затем ${{value, number}} в месяц / за каждый после', - per_month_each: '${{value, number}} в месяц / за каждый', - extra_mao_price: 'Затем ${{value, number}} за MAO', - per_month: '${{value, number}} в месяц', - /** UNTRANSLATED */ - per_member: 'Then ${{value, number}} per member', + extra_quota_price: 'Затем $ {{value, number}} в месяц / за каждый после', + per_month_each: '$ {{value, number}} в месяц / за каждый', + extra_mao_price: 'Затем $ {{value, number}} за MAO', + per_month: '$ {{value, number}} в месяц', + per_member: 'Затем $ {{value, number}} за участника', }; export default Object.freeze(quota_table); diff --git a/packages/phrases/src/locales/ru/translation/admin-console/tabs.ts b/packages/phrases/src/locales/ru/translation/admin-console/tabs.ts index 8a12cf4f2c9..20280de3e2e 100644 --- a/packages/phrases/src/locales/ru/translation/admin-console/tabs.ts +++ b/packages/phrases/src/locales/ru/translation/admin-console/tabs.ts @@ -14,8 +14,7 @@ const tabs = { docs: 'Документация', tenant_settings: 'Настройки', mfa: 'Multi-factor auth', - /** UNTRANSLATED */ - customize_jwt: 'Custom JWT', + customize_jwt: 'Пользовательский JWT', signing_keys: 'Ключи подписи', organization_template: 'Шаблон организации', }; diff --git a/packages/phrases/src/locales/ru/translation/admin-console/upsell/index.ts b/packages/phrases/src/locales/ru/translation/admin-console/upsell/index.ts index 629fa809ebe..0331d9aae0a 100644 --- a/packages/phrases/src/locales/ru/translation/admin-console/upsell/index.ts +++ b/packages/phrases/src/locales/ru/translation/admin-console/upsell/index.ts @@ -35,8 +35,7 @@ const upsell = { api_resource: 'API-ресурс', machine_to_machine: 'приложение "машина-машина"', tokens: '{{limit}}M токенов', - /** UNTRANSLATED */ - tenant_member: 'tenant member', + tenant_member: 'член арендатора', }, charge_notification_for_quota_limit: 'Вы превысили лимит вашей квоты по {{item}}. Logto начнет взимать плату за использование сверх вашей квоты. Начисление начнется в день выпуска нового дизайна цен на дополнение. Узнать больше', diff --git a/packages/phrases/src/locales/ru/translation/admin-console/upsell/paywall.ts b/packages/phrases/src/locales/ru/translation/admin-console/upsell/paywall.ts index 693504f5138..91ab3a9c3b8 100644 --- a/packages/phrases/src/locales/ru/translation/admin-console/upsell/paywall.ts +++ b/packages/phrases/src/locales/ru/translation/admin-console/upsell/paywall.ts @@ -52,24 +52,18 @@ const paywall = { mfa: 'Разблокируйте MFA для повышения безопасности с помощью перехода на платный план. Не стесняйтесь связаться с нами, если вам нужна помощь.', organizations: 'Разблокируйте организации, перейдя на платный план. Не стесняйтесь связаться с нами, если вам нужна помощь.', - /** UNTRANSLATED */ third_party_apps: - 'Unlock Logto as IdP for third-party apps by upgrading to a paid plan. For any assistance, feel free to contact us.', - /** UNTRANSLATED */ + 'Разблокируйте Logto как IdP для сторонних приложений, обновив план до платного. Для получения помощи не стесняйтесь связаться с нами.', sso_connectors: - 'Unlock enterprise sso by upgrading to a paid plan. For any assistance, feel free to contact us.', - /** UNTRANSLATED */ + 'Разблокируйте единые серверы аутентификации для предприятия, перейдя на платный план. Для получения помощи не стесняйтесь связаться с нами.', tenant_members: - 'Unlock collaboration feature by upgrading to a paid plan. For any assistance, feel free to contact us.', - /** UNTRANSLATED */ + 'Разблокируйте функцию сотрудничества, перейдя на платный план. Для получения помощи не стесняйтесь связаться с нами.', tenant_members_dev_plan: - "You've reached your {{limit}}-member limit. Release a member or revoke a pending invitation to add someone new. Need more seats? Feel free to contact us.", + 'Вы достигли лимита {{limit}} участников. Освободите место для новых участников или отмените ожидающее приглашение. Нужны дополнительные места? Не стесняйтесь связаться с нами.', custom_jwt: { - /** UNTRANSLATED */ - title: 'Add custom claims', - /** UNTRANSLATED */ + title: 'Добавить пользовательские претензии', description: - "Upgrade to a paid plan for custom JWT functionality and premium benefits. Don't hesitate to contact us if you have any questions.", + 'Обновите платный план для функциональности пользовательского JWT и дополнительных премиальных возможностей. Если у вас есть вопросы, не стесняйтесь связаться с нами.', }, }; diff --git a/packages/phrases/src/locales/tr-tr/errors/jwt-customizer.ts b/packages/phrases/src/locales/tr-tr/errors/jwt-customizer.ts index c7c5c1e2af9..4b7d79dba24 100644 --- a/packages/phrases/src/locales/tr-tr/errors/jwt-customizer.ts +++ b/packages/phrases/src/locales/tr-tr/errors/jwt-customizer.ts @@ -1,8 +1,6 @@ const jwt_customizer = { - /** UNTRANSLATED */ - general: 'An error occurred while customizing the JWT token. Please try again later.', - /** UNTRANSLATED */ - can_not_create_for_admin_tenant: 'Cannot create a JWT token customizer for the admin tenant.', + general: 'JWT belirteci özelleştirilirken bir hata oluştu. Lütfen daha sonra tekrar deneyin.', + can_not_create_for_admin_tenant: 'Yönetici kiracı için bir JWT belirteci özelleştirelemez.', }; export default Object.freeze(jwt_customizer); diff --git a/packages/phrases/src/locales/tr-tr/translation/admin-console/errors.ts b/packages/phrases/src/locales/tr-tr/translation/admin-console/errors.ts index 6d6fb3713e3..ade7fe8c2de 100644 --- a/packages/phrases/src/locales/tr-tr/translation/admin-console/errors.ts +++ b/packages/phrases/src/locales/tr-tr/translation/admin-console/errors.ts @@ -7,8 +7,7 @@ const errors = { invalid_uri_format: 'Geçersiz URI biçimi', invalid_origin_format: 'Geçersiz URI kaynak biçimi', invalid_json_format: 'Geçersiz JSON biçimi', - /** UNTRANSLATED */ - invalid_regex: 'Invalid regular expression', + invalid_regex: 'Geçersiz düzenli ifade', invalid_error_message_format: 'Hata mesajı biçimi geçersiz.', required_field_missing: 'Lütfen {{field}} giriniz', required_field_missing_plural: 'En az bir {{field}} girmek zorundasınız.', diff --git a/packages/phrases/src/locales/tr-tr/translation/admin-console/general.ts b/packages/phrases/src/locales/tr-tr/translation/admin-console/general.ts index f1bb0d53db0..db6ab408365 100644 --- a/packages/phrases/src/locales/tr-tr/translation/admin-console/general.ts +++ b/packages/phrases/src/locales/tr-tr/translation/admin-console/general.ts @@ -25,11 +25,9 @@ const general = { customize: 'Özelleştir', enable: 'Etkinleştir', reminder: 'Hatırlatıcı', - /** UNTRANSLATED */ - edit: 'Edit', + edit: 'Düzenle', delete: 'Sil', - /** UNTRANSLATED */ - deleted: 'Deleted', + deleted: 'Silindi', more_options: 'DAHA FAZLA SEÇENEK', close: 'Kapat', copy: 'Kopyala', @@ -59,8 +57,7 @@ const general = { demo: 'Demo', unnamed: 'İsimsiz', view: 'Görünüm', - /** UNTRANSLATED */ - open: 'Open', + open: 'Aç', hide: 'Gizle', unknown_error: 'Bilinmeyen hata, lütfen daha sonra tekrar deneyin.', select: 'Seç', @@ -72,8 +69,7 @@ const general = { edit_field: '{{field}} Düzenle', delete_field: '{{field}} Sil', coming_soon: 'Yakında', - /** UNTRANSLATED */ - or: 'Or', + or: 'Veya', }; export default Object.freeze(general); diff --git a/packages/phrases/src/locales/tr-tr/translation/admin-console/jwt-claims.ts b/packages/phrases/src/locales/tr-tr/translation/admin-console/jwt-claims.ts index f0d189ab412..23b6faf2895 100644 --- a/packages/phrases/src/locales/tr-tr/translation/admin-console/jwt-claims.ts +++ b/packages/phrases/src/locales/tr-tr/translation/admin-console/jwt-claims.ts @@ -1,98 +1,62 @@ const jwt_claims = { - /** UNTRANSLATED */ - title: 'Custom JWT', - /** UNTRANSLATED */ + title: 'Özel JWT', description: - 'Set up custom JWT claims to include in the access token. These claims can be used to pass additional information to your application.', + 'Erişim belgesine dahil edilecek özel JWT iddialarını ayarlayın. Bu iddialar, uygulamanıza ek bilgi iletmek için kullanılabilir.', user_jwt: { - /** UNTRANSLATED */ - card_title: 'For user', - /** UNTRANSLATED */ - card_field: 'User access token', - /** UNTRANSLATED */ - card_description: 'Add user-specific data during access token issuance.', - /** UNTRANSLATED */ - for: 'for user', + card_title: 'Kullanıcı İçin', + card_field: 'Kullanıcı erişim belgesi', + card_description: 'Erişim belgesi verilirken kullanıcıya özgü veri ekleyin.', + for: 'kullanıcı için', }, machine_to_machine_jwt: { - /** UNTRANSLATED */ - card_title: 'For M2M', - /** UNTRANSLATED */ - card_field: 'Machine-to-machine token', - /** UNTRANSLATED */ - card_description: 'Add extra data during machine-to-machine token issuance.', - /** UNTRANSLATED */ - for: 'for M2M', - }, - /** UNTRANSLATED */ - code_editor_title: 'Customize the {{token}} claims', - /** UNTRANSLATED */ - custom_jwt_create_button: 'Add custom claims', - /** UNTRANSLATED */ - custom_jwt_item: 'Custom claims {{for}}', - /** UNTRANSLATED */ - delete_modal_title: 'Delete custom claims', - /** UNTRANSLATED */ - delete_modal_content: 'Are you sure you want to delete the custom claims?', - /** UNTRANSLATED */ - clear: 'Clear', - /** UNTRANSLATED */ - cleared: 'Cleared', - /** UNTRANSLATED */ - restore: 'Restore defaults', - /** UNTRANSLATED */ - restored: 'Restored', - /** UNTRANSLATED */ - data_source_tab: 'Data source', - /** UNTRANSLATED */ - test_tab: 'Test context', - /** UNTRANSLATED */ - jwt_claims_description: 'Default claims are auto-included in the JWT and cannot be overridden.', + card_title: 'Makine için', + card_field: 'Makine-makine belgesi', + card_description: 'Makine-makine belgesi verilirken ek veri ekleyin.', + for: 'M2M için', + }, + code_editor_title: 'Özel {{token}} iddialarını özelleştirin', + custom_jwt_create_button: 'Özel iddialar ekle', + custom_jwt_item: 'Özel iddialar {{for}}', + delete_modal_title: 'Özel iddiaları sil', + delete_modal_content: 'Özel iddiaları silmek istediğinizden emin misiniz?', + clear: 'Temizle', + cleared: 'Temizlendi', + restore: 'Varsayılanları geri yükle', + restored: 'Geri yüklendi', + data_source_tab: 'Veri kaynağı', + test_tab: 'Test bağlamı', + jwt_claims_description: + "Varsayılan iddialar JWT'de otomatik olarak dahil edilir ve geçersiz kılınabilir.", user_data: { - /** UNTRANSLATED */ - title: 'User data', - /** UNTRANSLATED */ - subtitle: 'Use `data.user` input parameter to provide vital user info.', + title: 'Kullanıcı verisi', + subtitle: + '`veri.kullanıcı` giriş parametresini kullanarak önemli kullanıcı bilgilerini sağlayın.', }, token_data: { - /** UNTRANSLATED */ - title: 'Token data', - /** UNTRANSLATED */ - subtitle: 'Use `token` input parameter for current access token payload. ', + title: 'Belge verisi', + subtitle: '`belge` giriş parametresini mevcut erişim belgesi yükü için kullanın. ', }, fetch_external_data: { - /** UNTRANSLATED */ - title: 'Fetch external data', - /** UNTRANSLATED */ - subtitle: 'Incorporate data from your external APIs directly into claims.', - /** UNTRANSLATED */ + title: 'Harici veri al', + subtitle: "Harici API'larınızdan verileri doğrudan iddialara dahil edin.", description: - 'Use the `fetch` function to call your external APIs and include the data in your custom claims. Example: ', + "`fetch` işlevini kullanarak harici API'larınızı çağırın ve verileri özel iddialarınıza dahil edin. Örnek: ", }, environment_variables: { - /** UNTRANSLATED */ - title: 'Set environment variables', - /** UNTRANSLATED */ - subtitle: 'Use environment variables to store sensitive information.', - /** UNTRANSLATED */ - input_field_title: 'Add environment variables', - /** UNTRANSLATED */ - sample_code: 'Accessing environment variables in your custom JWT claims handler. Example: ', + title: 'Ortam değişkenlerini ayarla', + subtitle: 'Hassas bilgileri depolamak için ortam değişkenlerini kullanın.', + input_field_title: 'Ortam değişkenleri ekle', + sample_code: 'Özel JWT iddialarınızı ele alan ortam değişkenlerine erişim. Örnek: ', }, - /** UNTRANSLATED */ jwt_claims_hint: - 'Limit custom claims to under 50KB. Default JWT claims are automatically included in the token and can not be overridden.', + "Özel iddiaları 50KB'ın altında tutun. Varsayılan JWT iddiaları otomatik olarak belgeye dahil edilir ve geçersiz kılınamazlar.", tester: { - /** UNTRANSLATED */ - subtitle: 'Adjust mock token and user data for testing.', - /** UNTRANSLATED */ - run_button: 'Run test', - /** UNTRANSLATED */ - result_title: 'Test result', + subtitle: 'Test için sahte belge ve kullanıcı verilerini ayarlayın.', + run_button: 'Testi Çalıştır', + result_title: 'Test sonucu', }, form_error: { - /** UNTRANSLATED */ - invalid_json: 'Invalid JSON format', + invalid_json: 'Geçersiz JSON biçimi', }, }; diff --git a/packages/phrases/src/locales/tr-tr/translation/admin-console/subscription/quota-item.ts b/packages/phrases/src/locales/tr-tr/translation/admin-console/subscription/quota-item.ts index b8228ce4ee7..e5c77bee9ec 100644 --- a/packages/phrases/src/locales/tr-tr/translation/admin-console/subscription/quota-item.ts +++ b/packages/phrases/src/locales/tr-tr/translation/admin-console/subscription/quota-item.ts @@ -34,16 +34,11 @@ const quota_item = { not_eligible: 'Makineye makine uygulamalarınızı kaldırın', }, third_party_applications_limit: { - /** UNTRANSLATED */ - name: 'Third-party apps', - /** UNTRANSLATED */ - limited: '{{count, number}} third-party app', - /** UNTRANSLATED */ - limited_other: '{{count, number}} third-party apps', - /** UNTRANSLATED */ - unlimited: 'Unlimited third-party apps', - /** UNTRANSLATED */ - not_eligible: 'Remove your third-party apps', + name: 'Üçüncü taraf uygulamalar', + limited: '{{count, number}} üçüncü taraf uygulama', + limited_other: '{{count, number}} üçüncü taraf uygulamalar', + unlimited: 'Sınırsız üçüncü taraf uygulamalar', + not_eligible: 'Üçüncü taraf uygulamalarınızı kaldırın', }, resources_limit: { name: 'API kaynakları', @@ -152,26 +147,17 @@ const quota_item = { not_eligible: "Kurumsal SSO'nuzu kaldırın", }, tenant_members_limit: { - /** UNTRANSLATED */ - name: 'Tenant members', - /** UNTRANSLATED */ - limited: '{{count, number}} tenant member', - /** UNTRANSLATED */ - limited_other: '{{count, number}} tenant members', - /** UNTRANSLATED */ - unlimited: 'Unlimited tenant members', - /** UNTRANSLATED */ - not_eligible: 'Remove your tenant members', + name: 'Kiracı üyeleri', + limited: '{{count, number}} kiracı üyesi', + limited_other: '{{count, number}} kiracı üyeleri', + unlimited: 'Sınırsız kiracı üyeleri', + not_eligible: 'Kiracı üyelerinizi kaldırın', }, custom_jwt_enabled: { - /** UNTRANSLATED */ - name: 'Custom JWT', - /** UNTRANSLATED */ - limited: 'Custom JWT', - /** UNTRANSLATED */ - unlimited: 'Custom JWT', - /** UNTRANSLATED */ - not_eligible: 'Remove your JWT claims customizer', + name: 'Özel JWT', + limited: 'Özel JWT', + unlimited: 'Özel JWT', + not_eligible: 'JWT taleplerinizin özelleştiricisini kaldırın', }, }; diff --git a/packages/phrases/src/locales/tr-tr/translation/admin-console/subscription/quota-table.ts b/packages/phrases/src/locales/tr-tr/translation/admin-console/subscription/quota-table.ts index 432a4696fa7..dbaf748099a 100644 --- a/packages/phrases/src/locales/tr-tr/translation/admin-console/subscription/quota-table.ts +++ b/packages/phrases/src/locales/tr-tr/translation/admin-console/subscription/quota-table.ts @@ -9,8 +9,7 @@ const quota_table = { title: 'Uygulamalar', total: 'Toplam uygulama sayısı', m2m: 'Makine-makine uygulamaları', - /** UNTRANSLATED */ - third_party: 'Third-party apps', + third_party: 'Üçüncü taraf uygulamalar', }, resource: { title: 'API Kaynakları', @@ -66,20 +65,15 @@ const quota_table = { hipaa_or_baa_report: 'HIPAA/BAA raporu', }, developers_and_platform: { - /** UNTRANSLATED */ - title: 'Developers and platform', - /** UNTRANSLATED */ + title: 'Geliştiriciler ve platform', hooks: 'Webhooks', - /** UNTRANSLATED */ - audit_logs_retention: 'Audit logs retention', - /** UNTRANSLATED */ - jwt_claims: 'JWT claims', - /** UNTRANSLATED */ - tenant_members: 'Tenant members', + audit_logs_retention: 'Denetim kayıtları saklama', + jwt_claims: 'JWT iddiaları', + tenant_members: 'Kiracı üyeleri', }, unlimited: 'Sınırsız', contact: 'İletişim', - monthly_price: '${{value, number}}/ay', + monthly_price: '${{value, number}} / ay', days_one: '{{count, number}} gün', days_other: '{{count, number}} gün', add_on: 'Ek Hizmet', @@ -97,17 +91,15 @@ const quota_table = { 'Logto tarafından ihraç edilen erişim tokeni, yenileme tokeni vb. dahil olmak üzere tüm token türleri.', mao_tip: "MAO (aylık aktif kuruluş) bir fatura döngüsünde en az bir MAU'ya (aylık aktif kullanıcı) sahip olan benzersiz kuruluşların sayısını ifade eder.", - /** UNTRANSLATED */ third_party_tip: - 'Use Logto as your OIDC identity provider for third-party app sign-ins and permission grants.', + "Logto'yu üçüncü taraf uygulama oturum açma ve izin verme için OIDC kimlik sağlayıcısı olarak kullanın.", included: '{{value, number}} dahil', included_mao: '{{value, number}} MAO dahil', extra_quota_price: 'Sonra aylık ${{value, number}} / sonrasında her biri', per_month_each: 'Aylık ${{value, number}} / her biri', extra_mao_price: 'Sonra MAO başına ${{value, number}}', per_month: 'Aylık ${{value, number}}', - /** UNTRANSLATED */ - per_member: 'Then ${{value, number}} per member', + per_member: 'Sonra ${{value, number}} her üye', }; export default Object.freeze(quota_table); diff --git a/packages/phrases/src/locales/tr-tr/translation/admin-console/tabs.ts b/packages/phrases/src/locales/tr-tr/translation/admin-console/tabs.ts index 8599fbf7552..d93e1a2f0a2 100644 --- a/packages/phrases/src/locales/tr-tr/translation/admin-console/tabs.ts +++ b/packages/phrases/src/locales/tr-tr/translation/admin-console/tabs.ts @@ -14,8 +14,7 @@ const tabs = { docs: 'Dökümanlar', tenant_settings: 'Ayarlar', mfa: 'Çoklu faktörlü kimlik doğrulama', - /** UNTRANSLATED */ - customize_jwt: 'Custom JWT', + customize_jwt: 'Özel JWT', signing_keys: 'İmza anahtarları', organization_template: 'Kuruluş şablonu', }; diff --git a/packages/phrases/src/locales/tr-tr/translation/admin-console/upsell/index.ts b/packages/phrases/src/locales/tr-tr/translation/admin-console/upsell/index.ts index df747747fc2..d7b04c2bff0 100644 --- a/packages/phrases/src/locales/tr-tr/translation/admin-console/upsell/index.ts +++ b/packages/phrases/src/locales/tr-tr/translation/admin-console/upsell/index.ts @@ -35,8 +35,7 @@ const upsell = { api_resource: 'API kaynağı', machine_to_machine: 'makine-makine uygulaması', tokens: '{{limit}}M jeton', - /** UNTRANSLATED */ - tenant_member: 'tenant member', + tenant_member: 'kiracı üyesi', }, charge_notification_for_quota_limit: '{{item}} kota sınırını aştınız. Logto, kota sınırınızın ötesindeki kullanım için ücret ekleyecektir. Yeni ek paket fiyatlandırma tasarımı gününüzde başlayacaktır. Daha fazla bilgi', diff --git a/packages/phrases/src/locales/tr-tr/translation/admin-console/upsell/paywall.ts b/packages/phrases/src/locales/tr-tr/translation/admin-console/upsell/paywall.ts index a6ce1b6d119..a9c3696c038 100644 --- a/packages/phrases/src/locales/tr-tr/translation/admin-console/upsell/paywall.ts +++ b/packages/phrases/src/locales/tr-tr/translation/admin-console/upsell/paywall.ts @@ -18,58 +18,52 @@ const paywall = { scopes_per_resource_other: '{{count, number}} API kaynağı başına izin sınırına ulaşıldı. Genişletmek için şimdi yükseltin. Yardıma ihtiyacınız olursa, iletişime geçin.', custom_domain: - 'Unlock custom domain functionality by upgrading to Hobby or Pro plan. Don’t hesitate to contact us if you need any assistance.', + 'Özel alan işlevselliğini kilidini açmak için Hobiyi veya Pro’yu yükseltin. Yardım için bizimle iletişime geçin ihtiyacınız varsa.', social_connectors: - '{{count, number}} sosyal bağlayıcı sınırına ulaşıldı. Ekibinizin ihtiyaçlarını karşılamak için planı yükseltin ve OIDC, OAuth 2.0 ve SAML protokolleri kullanarak kendi bağlayıcılarınızı oluşturma yeteneğine sahip olun. Yardıma ihtiyacınız olursa, iletişime geçin.', + '{{count, number}} sosyal bağlayıcı sınırına ulaşıldı. Ekibinizin ihtiyaçlarını karşılamak için planı yükseltin ve OIDC, OAuth 2.0 ve SAML protokolleri kullanarak kendi bağlayıcılarınızı oluşturma yeteneğine sahip olun. Yardım için ihtiyacınız olursa, iletişime geçin.', social_connectors_other: - '{{count, number}} sosyal bağlayıcı sınırına ulaşıldı. Ekibinizin ihtiyaçlarını karşılamak için planı yükseltin ve OIDC, OAuth 2.0 ve SAML protokolleri kullanarak kendi bağlayıcılarınızı oluşturma yeteneğine sahip olun. Yardıma ihtiyacınız olursa, iletişime geçin.', + '{{count, number}} sosyal bağlayıcı sınırına ulaşıldı. Ekibinizin ihtiyaçlarını karşılamak için planı yükseltin ve OIDC, OAuth 2.0 ve SAML protokolleri kullanarak kendi bağlayıcılarınızı oluşturma yeteneğine sahip olun. Yardım için ihtiyacınız olursa, iletişime geçin.', standard_connectors_feature: - 'Upgrade to the Hobby or Pro plan to create your own connectors using OIDC, OAuth 2.0, and SAML protocols, plus unlimited social connectors and all the premium features. Feel free to contact us if you need any assistance.', + 'Hobi veya Pro planına yükselerek OIDC, OAuth 2.0 ve SAML protokollerini kullanarak kendi bağlayıcılarınızı oluşturun, sınırsız sosyal bağlayıcılara ve tüm özelliklere sahip olun. Yardım için ihtiyacınız olursa, iletişime geçin.', standard_connectors: - '{{count, number}} sosyal bağlayıcı sınırına ulaşıldı. Ekibinizin ihtiyaçlarını karşılamak için planı yükseltin ve OIDC, OAuth 2.0 ve SAML protokolleri kullanarak kendi bağlayıcılarınızı oluşturma yeteneğine sahip olun. Yardıma ihtiyacınız olursa, iletişime geçin.', + '{{count, number}} sosyal bağlayıcı sınırına ulaşıldı. Ekibinizin ihtiyaçlarını karşılamak için planı yükseltin ve OIDC, OAuth 2.0 ve SAML protokolleri kullanarak kendi bağlayıcılarınızı oluşturma yeteneğine sahip olun. Yardım için ihtiyacınız olursa, iletişime geçin.', standard_connectors_other: - '{{count, number}} sosyal bağlayıcı sınırına ulaşıldı. Ekibinizin ihtiyaçlarını karşılamak için planı yükseltin ve OIDC, OAuth 2.0 ve SAML protokolleri kullanarak kendi bağlayıcılarınızı oluşturma yeteneğine sahip olun. Yardıma ihtiyacınız olursa, iletişime geçin.', + '{{count, number}} sosyal bağlayıcı sınırına ulaşıldı. Ekibinizin ihtiyaçlarını karşılamak için planı yükseltin ve OIDC, OAuth 2.0 ve SAML protokolleri kullanarak kendi bağlayıcılarınızı oluşturma yeteneğine sahip olun. Yardım için ihtiyacınız olursa, iletişime geçin.', standard_connectors_pro: - '{{count, number}} standart bağlayıcı sınırına ulaşıldı. Ekibinizin ihtiyaçlarını karşılamak için Kurumsal plana yükseltin ve OIDC, OAuth 2.0 ve SAML protokolleri kullanarak kendi bağlayıcılarınızı oluşturma yeteneğine sahip olun. Yardıma ihtiyacınız olursa, iletişime geçin.', + '{{count, number}} standart bağlayıcı sınırına ulaşıldı. Ekibinizin ihtiyaçlarını karşılamak için Kurumsal plana yükseltin ve OIDC, OAuth 2.0 ve SAML protokolleri kullanarak kendi bağlayıcılarınızı oluşturma yeteneğine sahip olun. Yardım için ihtiyacınız olursa, iletişime geçin.', standard_connectors_pro_other: - '{{count, number}} standart bağlayıcı sınırına ulaşıldı. Ekibinizin ihtiyaçlarını karşılamak için Kurumsal plana yükseltin ve OIDC, OAuth 2.0 ve SAML protokolleri kullanarak kendi bağlayıcılarınızı oluşturma yeteneğine sahip olun. Yardıma ihtiyacınız olursa, iletişime geçin.', + '{{count, number}} standart bağlayıcı sınırına ulaşıldı. Ekibinizin ihtiyaçlarını karşılamak için Kurumsal plana yükseltin ve OIDC, OAuth 2.0 ve SAML protokolleri kullanarak kendi bağlayıcılarınızı oluşturma yeteneğine sahip olun. Yardım için ihtiyacınız olursa, iletişime geçin.', roles: - '{{count, number}} rol sınırına ulaşıldı. İlave roller ve izinler eklemek için planı yükseltin. Yardıma ihtiyacınız olursa, iletişime geçin.', + '{{count, number}} rol sınırına ulaşıldı. İlave roller ve izinler eklemek için planı yükseltin. Yardım için ihtiyacınız olursa, iletişime geçin.', roles_other: - '{{count, number}} rol sınırına ulaşıldı. İlave roller ve izinler eklemek için planı yükseltin. Yardıma ihtiyacınız olursa, iletişime geçin.', + '{{count, number}} rol sınırına ulaşıldı. İlave roller ve izinler eklemek için planı yükseltin. Yardım için ihtiyacınız olursa, iletişime geçin.', machine_to_machine_roles: '{{count, number}} machine-to-machine role of limit reached. Upgrade plan to add additional roles and permissions. Feel free to contact us if you need any assistance.', machine_to_machine_roles_other: '{{count, number}} machine-to-machine roles of limit reached. Upgrade plan to add additional roles and permissions. Feel free to contact us if you need any assistance.', scopes_per_role: - '{{count, number}} rol başına izin sınırına ulaşıldı. İlave roller ve izinler eklemek için planı yükseltin. Yardıma ihtiyacınız olursa, iletişime geçin.', + '{{count, number}} rol başına izin sınırına ulaşıldı. İlave roller ve izinler eklemek için planı yükseltin. Yardım için ihtiyacınız olursa, iletişime geçin.', scopes_per_role_other: - '{{count, number}} rol başına izin sınırına ulaşıldı. İlave roller ve izinler eklemek için planı yükseltin. Yardıma ihtiyacınız olursa, iletişime geçin.', + '{{count, number}} rol başına izin sınırına ulaşıldı. İlave roller ve izinler eklemek için planı yükseltin. Yardım için ihtiyacınız olursa, iletişime geçin.', hooks: - '{{count, number}} webhook sınırına ulaşıldı. Daha fazla webhook oluşturmak için planı yükseltin. Yardıma ihtiyacınız olursa, iletişime geçin.', + '{{count, number}} webhook sınırına ulaşıldı. Daha fazla webhook oluşturmak için planı yükseltin. Yardım için ihtiyacınız olursa, iletişime geçin.', hooks_other: - '{{count, number}} webhook sınırına ulaşıldı. Daha fazla webhook oluşturmak için planı yükseltin. Yardıma ihtiyacınız olursa, iletişime geçin.', - mfa: "Güvenliği kontrol etmek için MFA'yı bir ücretli plana geçerek kilidini açın. Yardıma ihtiyacınız olursa bize iletişim kurmaktan çekinmeyin.", + '{{count, number}} webhook sınırına ulaşıldı. Daha fazla webhook oluşturmak için planı yükseltin. Yardım için ihtiyacınız olursa, iletişime geçin.', + mfa: "Güvenliği kontrol etmek için MFA'yı bir ücretli plana geçerek kilidini açın. Yardım için bize iletişim kurmaktan çekinmeyin.", organizations: - 'Upgrade to a paid plan to unlock organizations. Don’t hesitate to contact us if you need any assistance.', - /** UNTRANSLATED */ + 'Unlock organizations özelliğini açmak için ücretli bir plana yükseltin. Yardım için iletişime geçin ihtiyacınız olursa.', third_party_apps: - 'Unlock Logto as IdP for third-party apps by upgrading to a paid plan. For any assistance, feel free to contact us.', - /** UNTRANSLATED */ + "Üçüncü taraf uygulamalar için Logto'yu IdP olarak kilidini açmak için ücretli bir plana yükseltin. Yardım için iletişime geçin ihtiyacınız olursa.", sso_connectors: - 'Unlock enterprise sso by upgrading to a paid plan. For any assistance, feel free to contact us.', - /** UNTRANSLATED */ + "İşletme SSO'yu kilidini açmak için ücretli bir plana yükseltin. Yardım için iletişime geçin ihtiyacınız olursa.", tenant_members: - 'Unlock collaboration feature by upgrading to a paid plan. For any assistance, feel free to contact us.', - /** UNTRANSLATED */ + 'İşbirliği özelliğini kilidini açmak için ücretli bir plana yükseltin. Yardım için iletişime geçin ihtiyacınız olursa.', tenant_members_dev_plan: - "You've reached your {{limit}}-member limit. Release a member or revoke a pending invitation to add someone new. Need more seats? Feel free to contact us.", + 'Sınırınıza ulaştınız {{limit}}-üye limit. Yeni birini eklemek için bir üyeyi serbest bırakın veya reddedilen bir daveti geri çekin. Daha fazla kontenjana mı ihtiyacınız var? İletişim kurmaktan çekinmeyin.', custom_jwt: { - /** UNTRANSLATED */ - title: 'Add custom claims', - /** UNTRANSLATED */ + title: 'Özel iddialar ekle', description: - "Upgrade to a paid plan for custom JWT functionality and premium benefits. Don't hesitate to contact us if you have any questions.", + 'Özel JWT işlevselliği ve prim avantajları için ücretli bir plana yükseltin. Sorularınız varsa, çekinmeden iletişime geçin.', }, }; diff --git a/packages/phrases/src/locales/zh-cn/errors/jwt-customizer.ts b/packages/phrases/src/locales/zh-cn/errors/jwt-customizer.ts index c7c5c1e2af9..4490b3f52f4 100644 --- a/packages/phrases/src/locales/zh-cn/errors/jwt-customizer.ts +++ b/packages/phrases/src/locales/zh-cn/errors/jwt-customizer.ts @@ -1,8 +1,6 @@ const jwt_customizer = { - /** UNTRANSLATED */ - general: 'An error occurred while customizing the JWT token. Please try again later.', - /** UNTRANSLATED */ - can_not_create_for_admin_tenant: 'Cannot create a JWT token customizer for the admin tenant.', + general: '定制JWT令牌时出错。请稍后再试。', + can_not_create_for_admin_tenant: '无法为管理员租户创建JWT令牌定制器。', }; export default Object.freeze(jwt_customizer); diff --git a/packages/phrases/src/locales/zh-cn/translation/admin-console/errors.ts b/packages/phrases/src/locales/zh-cn/translation/admin-console/errors.ts index 1c06a9f4f79..6a4567db49f 100644 --- a/packages/phrases/src/locales/zh-cn/translation/admin-console/errors.ts +++ b/packages/phrases/src/locales/zh-cn/translation/admin-console/errors.ts @@ -7,8 +7,7 @@ const errors = { invalid_uri_format: '无效的 URI 格式', invalid_origin_format: '无效的 URI origin 格式', invalid_json_format: '无效的 JSON 格式', - /** UNTRANSLATED */ - invalid_regex: 'Invalid regular expression', + invalid_regex: '无效的正则表达式', invalid_error_message_format: '非法的错误信息格式', required_field_missing: '请输入{{field}}', required_field_missing_plural: '至少需要输入一个{{field}}', diff --git a/packages/phrases/src/locales/zh-cn/translation/admin-console/general.ts b/packages/phrases/src/locales/zh-cn/translation/admin-console/general.ts index f4e5787a1d8..ba58a7e80a8 100644 --- a/packages/phrases/src/locales/zh-cn/translation/admin-console/general.ts +++ b/packages/phrases/src/locales/zh-cn/translation/admin-console/general.ts @@ -25,11 +25,9 @@ const general = { customize: '自定义', enable: '启用', reminder: '提示', - /** UNTRANSLATED */ - edit: 'Edit', + edit: '编辑', delete: '删除', - /** UNTRANSLATED */ - deleted: 'Deleted', + deleted: '已删除', more_options: '更多选项', close: '关闭', copy: '复制', @@ -58,8 +56,7 @@ const general = { demo: '演示', unnamed: '未命名', view: '查看', - /** UNTRANSLATED */ - open: 'Open', + open: '打开', hide: '隐藏', unknown_error: '未知错误,请稍后重试。', select: '选择', @@ -71,8 +68,7 @@ const general = { edit_field: '编辑{{field}}', delete_field: '删除{{field}}', coming_soon: '即将上线', - /** UNTRANSLATED */ - or: 'Or', + or: '或', }; export default Object.freeze(general); diff --git a/packages/phrases/src/locales/zh-cn/translation/admin-console/jwt-claims.ts b/packages/phrases/src/locales/zh-cn/translation/admin-console/jwt-claims.ts index f0d189ab412..32722a3ab3a 100644 --- a/packages/phrases/src/locales/zh-cn/translation/admin-console/jwt-claims.ts +++ b/packages/phrases/src/locales/zh-cn/translation/admin-console/jwt-claims.ts @@ -1,98 +1,57 @@ const jwt_claims = { - /** UNTRANSLATED */ - title: 'Custom JWT', - /** UNTRANSLATED */ - description: - 'Set up custom JWT claims to include in the access token. These claims can be used to pass additional information to your application.', + title: '自定义JWT', + description: '设置自定义JWT声明以包含在访问令牌中。这些声明可以用于向应用程序传递附加信息。', user_jwt: { - /** UNTRANSLATED */ - card_title: 'For user', - /** UNTRANSLATED */ - card_field: 'User access token', - /** UNTRANSLATED */ - card_description: 'Add user-specific data during access token issuance.', - /** UNTRANSLATED */ - for: 'for user', + card_title: '对于用户', + card_field: '用户访问令牌', + card_description: '在访问令牌发放期间添加用户特定数据。', + for: '给用户', }, machine_to_machine_jwt: { - /** UNTRANSLATED */ - card_title: 'For M2M', - /** UNTRANSLATED */ - card_field: 'Machine-to-machine token', - /** UNTRANSLATED */ - card_description: 'Add extra data during machine-to-machine token issuance.', - /** UNTRANSLATED */ - for: 'for M2M', - }, - /** UNTRANSLATED */ - code_editor_title: 'Customize the {{token}} claims', - /** UNTRANSLATED */ - custom_jwt_create_button: 'Add custom claims', - /** UNTRANSLATED */ - custom_jwt_item: 'Custom claims {{for}}', - /** UNTRANSLATED */ - delete_modal_title: 'Delete custom claims', - /** UNTRANSLATED */ - delete_modal_content: 'Are you sure you want to delete the custom claims?', - /** UNTRANSLATED */ - clear: 'Clear', - /** UNTRANSLATED */ - cleared: 'Cleared', - /** UNTRANSLATED */ - restore: 'Restore defaults', - /** UNTRANSLATED */ - restored: 'Restored', - /** UNTRANSLATED */ - data_source_tab: 'Data source', - /** UNTRANSLATED */ - test_tab: 'Test context', - /** UNTRANSLATED */ - jwt_claims_description: 'Default claims are auto-included in the JWT and cannot be overridden.', + card_title: '对于M2M', + card_field: '机器间令牌', + card_description: '在机器间令牌发放期间添加额外数据。', + for: '给M2M', + }, + code_editor_title: '自定义{{token}}声明', + custom_jwt_create_button: '添加自定义声明', + custom_jwt_item: '自定义声明{{for}}', + delete_modal_title: '删除自定义声明', + delete_modal_content: '您确定要删除自定义声明吗?', + clear: '清除', + cleared: '已清除', + restore: '恢复默认', + restored: '已恢复', + data_source_tab: '数据来源', + test_tab: '测试上下文', + jwt_claims_description: '默认声明会自动包含在JWT中,不能被覆盖。', user_data: { - /** UNTRANSLATED */ - title: 'User data', - /** UNTRANSLATED */ - subtitle: 'Use `data.user` input parameter to provide vital user info.', + title: '用户数据', + subtitle: '使用`data.user`输入参数提供重要用户信息。', }, token_data: { - /** UNTRANSLATED */ - title: 'Token data', - /** UNTRANSLATED */ - subtitle: 'Use `token` input parameter for current access token payload. ', + title: '令牌数据', + subtitle: '使用`token`输入参数查看当前访问令牌负载。', }, fetch_external_data: { - /** UNTRANSLATED */ - title: 'Fetch external data', - /** UNTRANSLATED */ - subtitle: 'Incorporate data from your external APIs directly into claims.', - /** UNTRANSLATED */ - description: - 'Use the `fetch` function to call your external APIs and include the data in your custom claims. Example: ', + title: '获取外部数据', + subtitle: '直接将外部API中的数据纳入声明。', + description: '使用`fetch`函数调用外部API并将数据包含在自定义声明中。示例:', }, environment_variables: { - /** UNTRANSLATED */ - title: 'Set environment variables', - /** UNTRANSLATED */ - subtitle: 'Use environment variables to store sensitive information.', - /** UNTRANSLATED */ - input_field_title: 'Add environment variables', - /** UNTRANSLATED */ - sample_code: 'Accessing environment variables in your custom JWT claims handler. Example: ', + title: '设置环境变量', + subtitle: '使用环境变量存储敏感信息。', + input_field_title: '添加环境变量', + sample_code: '在自定义JWT声明处理程序中访问环境变量。示例:', }, - /** UNTRANSLATED */ - jwt_claims_hint: - 'Limit custom claims to under 50KB. Default JWT claims are automatically included in the token and can not be overridden.', + jwt_claims_hint: '将自定义声明限制在50KB以下。默认JWT声明会自动包含在令牌中,无法覆盖。', tester: { - /** UNTRANSLATED */ - subtitle: 'Adjust mock token and user data for testing.', - /** UNTRANSLATED */ - run_button: 'Run test', - /** UNTRANSLATED */ - result_title: 'Test result', + subtitle: '调整模拟令牌和用户数据进行测试。', + run_button: '运行测试', + result_title: '测试结果', }, form_error: { - /** UNTRANSLATED */ - invalid_json: 'Invalid JSON format', + invalid_json: 'JSON格式无效', }, }; diff --git a/packages/phrases/src/locales/zh-cn/translation/admin-console/subscription/quota-item.ts b/packages/phrases/src/locales/zh-cn/translation/admin-console/subscription/quota-item.ts index f4460e4a4c5..6cdcde05588 100644 --- a/packages/phrases/src/locales/zh-cn/translation/admin-console/subscription/quota-item.ts +++ b/packages/phrases/src/locales/zh-cn/translation/admin-console/subscription/quota-item.ts @@ -34,16 +34,11 @@ const quota_item = { not_eligible: '移除你的机器到机器应用', }, third_party_applications_limit: { - /** UNTRANSLATED */ - name: 'Third-party apps', - /** UNTRANSLATED */ - limited: '{{count, number}} third-party app', - /** UNTRANSLATED */ - limited_other: '{{count, number}} third-party apps', - /** UNTRANSLATED */ - unlimited: 'Unlimited third-party apps', - /** UNTRANSLATED */ - not_eligible: 'Remove your third-party apps', + name: '第三方应用', + limited: '{{count, number}} 第三方应用', + limited_other: '{{count, number}} 第三方应用', + unlimited: '无限制第三方应用', + not_eligible: '移除你的第三方应用', }, resources_limit: { name: 'API 资源', @@ -115,9 +110,9 @@ const quota_item = { hooks_limit: { name: 'Webhooks', limited: '{{count, number}} 个 Webhook', - limited_other: '{{count, number}} 个 Webhooks', - unlimited: '无限制的 Webhooks', - not_eligible: '移除你的 Webhooks', + limited_other: '{{count, number}} 个 Webhook', + unlimited: '无限制的 Webhook', + not_eligible: '移除你的 Webhook', }, organizations_enabled: { name: '组织', @@ -152,26 +147,17 @@ const quota_item = { not_eligible: '移除你的 企业SSO', }, tenant_members_limit: { - /** UNTRANSLATED */ - name: 'Tenant members', - /** UNTRANSLATED */ - limited: '{{count, number}} tenant member', - /** UNTRANSLATED */ - limited_other: '{{count, number}} tenant members', - /** UNTRANSLATED */ - unlimited: 'Unlimited tenant members', - /** UNTRANSLATED */ - not_eligible: 'Remove your tenant members', + name: '租户成员', + limited: '{{count, number}} 个租户成员', + limited_other: '{{count, number}} 个租户成员', + unlimited: '无限制租户成员', + not_eligible: '移除你的租户成员', }, custom_jwt_enabled: { - /** UNTRANSLATED */ - name: 'Custom JWT', - /** UNTRANSLATED */ - limited: 'Custom JWT', - /** UNTRANSLATED */ - unlimited: 'Custom JWT', - /** UNTRANSLATED */ - not_eligible: 'Remove your JWT claims customizer', + name: '自定义 JWT', + limited: '自定义 JWT', + unlimited: '自定义 JWT', + not_eligible: '移除你的 JWT 声明自定义器', }, }; diff --git a/packages/phrases/src/locales/zh-cn/translation/admin-console/subscription/quota-table.ts b/packages/phrases/src/locales/zh-cn/translation/admin-console/subscription/quota-table.ts index dce9ea073ac..c3a60adc82a 100644 --- a/packages/phrases/src/locales/zh-cn/translation/admin-console/subscription/quota-table.ts +++ b/packages/phrases/src/locales/zh-cn/translation/admin-console/subscription/quota-table.ts @@ -9,8 +9,7 @@ const quota_table = { title: '应用', total: '总应用数', m2m: '机器对机器', - /** UNTRANSLATED */ - third_party: 'Third-party apps', + third_party: '第三方应用', }, resource: { title: 'API 资源', @@ -66,16 +65,11 @@ const quota_table = { hipaa_or_baa_report: 'HIPAA/BAA报告', }, developers_and_platform: { - /** UNTRANSLATED */ - title: 'Developers and platform', - /** UNTRANSLATED */ + title: '开发者与平台', hooks: 'Webhooks', - /** UNTRANSLATED */ - audit_logs_retention: 'Audit logs retention', - /** UNTRANSLATED */ - jwt_claims: 'JWT claims', - /** UNTRANSLATED */ - tenant_members: 'Tenant members', + audit_logs_retention: '审计日志保留', + jwt_claims: 'JWT声明', + tenant_members: '租户成员', }, unlimited: '无限制', contact: '联系', @@ -94,17 +88,14 @@ const quota_table = { mau_tip: 'MAU(月活跃用户)是指在计费周期内与Logto交换过至少一个令牌的独立用户数量。', tokens_tip: 'Logto 发行的所有类型令牌,包括访问令牌、刷新令牌等。', mao_tip: 'MAO(月度活跃组织)是指在计费周期内至少有一个MAU(月度活跃用户)的独特组织数量。', - /** UNTRANSLATED */ - third_party_tip: - 'Use Logto as your OIDC identity provider for third-party app sign-ins and permission grants.', + third_party_tip: '将Logto用作您的OIDC身份提供程序,用于第三方应用的登录和权限授予。', included: '已包含{{value, number}}', included_mao: '已包含 {{value, number}} MAO', extra_quota_price: '然后每月 ${{value, number}} / 每个之后', per_month_each: '每月 ${{value, number}} / 每个', extra_mao_price: '然后每 MAO ${{value, number}}', per_month: '每月 ${{value, number}}', - /** UNTRANSLATED */ - per_member: 'Then ${{value, number}} per member', + per_member: '然后每成员 ${{value, number}}', }; export default Object.freeze(quota_table); diff --git a/packages/phrases/src/locales/zh-cn/translation/admin-console/tabs.ts b/packages/phrases/src/locales/zh-cn/translation/admin-console/tabs.ts index 6a01344a385..abcf8d3d3c2 100644 --- a/packages/phrases/src/locales/zh-cn/translation/admin-console/tabs.ts +++ b/packages/phrases/src/locales/zh-cn/translation/admin-console/tabs.ts @@ -14,8 +14,7 @@ const tabs = { docs: '文档', tenant_settings: '租户设置', mfa: '多因素认证', - /** UNTRANSLATED */ - customize_jwt: 'Custom JWT', + customize_jwt: '自定义 JWT', signing_keys: '签名密钥', organization_template: '组织模板', }; diff --git a/packages/phrases/src/locales/zh-cn/translation/admin-console/upsell/index.ts b/packages/phrases/src/locales/zh-cn/translation/admin-console/upsell/index.ts index 6a02d5a1397..10c98ed6ab3 100644 --- a/packages/phrases/src/locales/zh-cn/translation/admin-console/upsell/index.ts +++ b/packages/phrases/src/locales/zh-cn/translation/admin-console/upsell/index.ts @@ -35,8 +35,7 @@ const upsell = { api_resource: 'API 资源', machine_to_machine: '机器对机器应用', tokens: '{{limit}}M 令牌', - /** UNTRANSLATED */ - tenant_member: 'tenant member', + tenant_member: '租户成员', }, charge_notification_for_quota_limit: '您已超过{{item}}配额限制。Logto将为超出配额限制的使用添加费用。计费将从新的附加定价设计发布当天开始。 了解更多', diff --git a/packages/phrases/src/locales/zh-cn/translation/admin-console/upsell/paywall.ts b/packages/phrases/src/locales/zh-cn/translation/admin-console/upsell/paywall.ts index 0bb8169d0b1..061018cd3c8 100644 --- a/packages/phrases/src/locales/zh-cn/translation/admin-console/upsell/paywall.ts +++ b/packages/phrases/src/locales/zh-cn/translation/admin-console/upsell/paywall.ts @@ -1,74 +1,66 @@ const paywall = { applications: - '已达到 的{{count, number}}个应用限制。升级计划以满足团队需求。如需帮助,请随时联系我们。', + '已达到 的{{count, number}}个应用限制。升级计划以满足团队需求。如需帮助,请随时 联系我们。', applications_other: - '已达到 的{{count, number}}个应用限制。升级计划以满足团队需求。如需帮助,请随时联系我们。', + '已达到 的{{count, number}}个应用限制。升级计划以满足团队需求。如需帮助,请随时 联系我们。', machine_to_machine_feature: - '升级至Pro套餐,解锁额外机器对机器应用,享受所有高级功能。如果有疑问,请联系我们。', + '升级至 Pro 套餐,解锁额外机器对机器应用,享受所有高级功能。 如果有疑问,请联系我们。', machine_to_machine: - '已达到 的{{count, number}}个机器对机器应用限制。升级计划以满足团队需求。如需帮助,请随时联系我们。', + '已达到 的{{count, number}}个机器对机器应用限制。升级计划以满足团队需求。如需帮助,请随时 联系我们。', machine_to_machine_other: - '已达到 的{{count, number}}个机器对机器应用限制。升级计划以满足团队需求。如需帮助,请随时联系我们。', + '已达到 的{{count, number}}个机器对机器应用限制。升级计划以满足团队需求。如需帮助,请随时 联系我们。', resources: - '已达到的{{count, number}}个 API 资源限制。升级计划以满足您团队的需求。联系我们寻求帮助。', + '已达到 的{{count, number}}个 API 资源限制。升级计划以满足您团队的需求。 联系我们 寻求帮助。', resources_other: - '已达到的{{count, number}}个 API 资源限制。升级计划以满足您团队的需求。联系我们寻求帮助。', + '已达到 的{{count, number}}个 API 资源限制。升级计划以满足您团队的需求。 联系我们 寻求帮助。', scopes_per_resource: - '已达到的{{count, number}}个 API 资源每个权限限制。立即升级以扩展。如需任何帮助,请联系我们。', + '已达到 的{{count, number}}个 API 资源每个权限限制。立即升级以扩展。如需任何帮助,请 联系我们。', scopes_per_resource_other: - '已达到的{{count, number}}个 API 资源每个权限限制。立即升级以扩展。如需任何帮助,请联系我们。', + '已达到 的{{count, number}}个 API 资源每个权限限制。立即升级以扩展。如需任何帮助,请 联系我们。', custom_domain: - '升级至HobbyPro套餐,解锁自定义域功能。如有任何需要,不要犹豫联系我们。', + '升级至 HobbyPro 套餐,解锁自定义域功能。如有任何需要,请不要犹豫 联系我们。', social_connectors: - '已达到的{{count, number}}个社交连接器限制。为满足您团队的需求,请升级计划以获取额外的社交连接器,并可以使用 OIDC、OAuth 2.0 和 SAML 协议创建您自己的连接器。如需任何帮助,请联系我们。', + '已达到 的{{count, number}}个社交连接器限制。为满足您团队的需求,请升级计划以获取额外的社交连接器,并可以使用 OIDC、OAuth 2.0 和 SAML 协议创建您自己的连接器。如需任何帮助,请 联系我们。', social_connectors_other: - '已达到的{{count, number}}个社交连接器限制。为满足您团队的需求,请升级计划以获取额外的社交连接器,并可以使用 OIDC、OAuth 2.0 和 SAML 协议创建您自己的连接器。如需任何帮助,请联系我们。', + '已达到 的{{count, number}}个社交连接器限制。为满足您团队的需求,请升级计划以获取额外的社交连接器,并可以使用 OIDC、OAuth 2.0 和 SAML 协议创建您自己的连接器。如需任何帮助,请 联系我们。', standard_connectors_feature: - '升级至HobbyPro套餐,创建自己的连接器,可使用OIDC、OAuth 2.0和SAML协议,还可以享受无限社交连接器和所有高级功能。需要任何帮助,请随时联系我们。', + '升级至 HobbyPro 套餐,创建自己的连接器,可使用 OIDC、OAuth 2.0 和 SAML 协议,还可以享受无限社交连接器和所有高级功能。需要任何帮助,请随时 联系我们。', standard_connectors: - '已达到的{{count, number}}个社交连接器限制。为满足您团队的需求,请升级计划以获取额外的社交连接器,并可以使用 OIDC、OAuth 2.0 和 SAML 协议创建您自己的连接器。如需任何帮助,请联系我们。', + '已达到 的{{count, number}}个社交连接器限制。为满足您团队的需求,请升级计划以获取额外的社交连接器,并可以使用 OIDC、OAuth 2.0 和 SAML 协议创建您自己的连接器。如需任何帮助,请 联系我们。', standard_connectors_other: - '已达到的{{count, number}}个社交连接器限制。为满足您团队的需求,请升级计划以获取额外的社交连接器,并可以使用 OIDC、OAuth 2.0 和 SAML 协议创建您自己的连接器。如需任何帮助,请联系我们。', + '已达到 的{{count, number}}个社交连接器限制。为满足您团队的需求,请升级计划以获取额外的社交连接器,并可以使用 OIDC、OAuth 2.0 和 SAML 协议创建您自己的连接器。如需任何帮助,请 联系我们。', standard_connectors_pro: - '已达到的{{count, number}}个标准连接器限制。为满足您团队的需求,请升级至企业版计划以获取额外的社交连接器,并可以使用 OIDC、OAuth 2.0 和 SAML 协议创建您自己的连接器。如需任何帮助,请联系我们。', + '已达到 的{{count, number}}个标准连接器限制。为满足您团队的需求,请升级至企业版计划以获取额外的社交连接器,并可以使用 OIDC、OAuth 2.0 和 SAML 协议创建您自己的连接器。如需任何帮助,请 联系我们。', standard_connectors_pro_other: - '已达到的{{count, number}}个标准连接器限制。为满足您团队的需求,请升级至企业版计划以获取额外的社交连接器,并可以使用 OIDC、OAuth 2.0 和 SAML 协议创建您自己的连接器。如需任何帮助,请联系我们。', + '已达到 的{{count, number}}个标准连接器限制。为满足您团队的需求,请升级至企业版计划以获取额外的社交连接器,并可以使用 OIDC、OAuth 2.0 和 SAML 协议创建您自己的连接器。如需任何帮助,请 联系我们。', roles: - '已达到的{{count, number}}个角色限制。升级计划以添加额外的角色和权限。如需任何帮助,请联系我们。', + '已达到 的{{count, number}}个角色限制。升级计划以添加额外的角色和权限。如需任何帮助,请 联系我们。', roles_other: - '已达到的{{count, number}}个角色限制。升级计划以添加额外的角色和权限。如需任何帮助,请联系我们。', + '已达到 的{{count, number}}个角色限制。升级计划以添加额外的角色和权限。如需任何帮助,请 联系我们。', machine_to_machine_roles: - '{{count, number}} machine-to-machine role of limit reached. Upgrade plan to add additional roles and permissions. Feel free to contact us if you need any assistance.', + '{{count, number}} 个机器对机器角色已达到 的限制。升级计划以添加额外的角色和权限。如需任何帮助,请 联系我们。', machine_to_machine_roles_other: - '{{count, number}} machine-to-machine roles of limit reached. Upgrade plan to add additional roles and permissions. Feel free to contact us if you need any assistance.', + '{{count, number}} 个机器对机器角色已达到 的限制。升级计划以添加额外的角色和权限。如需任何帮助,请 联系我们。', scopes_per_role: - '已达到的{{count, number}}个角色每个权限限制。升级计划以添加额外的角色和权限。如需任何帮助,请联系我们。', + '已达到 的{{count, number}}个角色每个权限限制。升级计划以添加额外的角色和权限。如需任何帮助,请 联系我们。', scopes_per_role_other: - '已达到的{{count, number}}个角色每个权限限制。升级计划以添加额外的角色和权限。如需任何帮助,请联系我们。', + '已达到 的{{count, number}}个角色每个权限限制。升级计划以添加额外的角色和权限。如需任何帮助,请 联系我们。', hooks: - '已达到的{{count, number}}个 Webhook 限制。升级计划以创建更多 Webhook。如需任何帮助,请联系我们。', + '已达到 的{{count, number}}个 Webhook 限制。升级计划以创建更多 Webhook。如需任何帮助,请 联系我们。', hooks_other: - '已达到的{{count, number}}个 Webhook 限制。升级计划以创建更多 Webhook。如需任何帮助,请联系我们。', - mfa: '升级到付费计划以解锁MFA进行安全验证。如果需要任何帮助,请随时联系我们。', - organizations: '升级到付费计划以解锁组织功能。如有任何需要,请不要犹豫联系我们。', - /** UNTRANSLATED */ + '已达到 的{{count, number}}个 Webhook 限制。升级计划以创建更多 Webhook。如需任何帮助,请 联系我们。', + mfa: '升级到付费计划以解锁 MFA 进行安全验证。如果需要任何帮助,请随时 联系我们。', + organizations: '升级到付费计划以解锁组织功能。如有任何需要,请不要犹豫 联系我们。', third_party_apps: - 'Unlock Logto as IdP for third-party apps by upgrading to a paid plan. For any assistance, feel free to contact us.', - /** UNTRANSLATED */ - sso_connectors: - 'Unlock enterprise sso by upgrading to a paid plan. For any assistance, feel free to contact us.', - /** UNTRANSLATED */ - tenant_members: - 'Unlock collaboration feature by upgrading to a paid plan. For any assistance, feel free to contact us.', - /** UNTRANSLATED */ + '通过升级到付费计划,可将 Logto 解锁为第三方应用的 IdP。如需任何帮助,请随时 联系我们。', + sso_connectors: '通过升级到付费计划,可解锁企业 SSO 功能。如需任何帮助,请随时 联系我们。', + tenant_members: '通过升级到付费计划,可解锁协作功能。如需任何帮助,请随时 联系我们。', tenant_members_dev_plan: - "You've reached your {{limit}}-member limit. Release a member or revoke a pending invitation to add someone new. Need more seats? Feel free to contact us.", + '您已达到 {{limit}}-成员限制。释放一个成员或撤销待定邀请以添加新成员。需要更多名额?请随时联系我们。', custom_jwt: { - /** UNTRANSLATED */ - title: 'Add custom claims', - /** UNTRANSLATED */ + title: '添加自定义声明', description: - "Upgrade to a paid plan for custom JWT functionality and premium benefits. Don't hesitate to contact us if you have any questions.", + '升级到付费计划以获取自定义 JWT 功能和高级福利。如有任何问题,请不要犹豫 联系我们。', }, }; diff --git a/packages/phrases/src/locales/zh-hk/errors/jwt-customizer.ts b/packages/phrases/src/locales/zh-hk/errors/jwt-customizer.ts index c7c5c1e2af9..efe01a2c8e5 100644 --- a/packages/phrases/src/locales/zh-hk/errors/jwt-customizer.ts +++ b/packages/phrases/src/locales/zh-hk/errors/jwt-customizer.ts @@ -1,8 +1,6 @@ const jwt_customizer = { - /** UNTRANSLATED */ - general: 'An error occurred while customizing the JWT token. Please try again later.', - /** UNTRANSLATED */ - can_not_create_for_admin_tenant: 'Cannot create a JWT token customizer for the admin tenant.', + general: '自定義 JWT 標記時發生錯誤。請稍後再試。', + can_not_create_for_admin_tenant: '無法為管理租戶創建 JWT 標記自定義器。', }; export default Object.freeze(jwt_customizer); diff --git a/packages/phrases/src/locales/zh-hk/translation/admin-console/errors.ts b/packages/phrases/src/locales/zh-hk/translation/admin-console/errors.ts index 9f3682d830b..d932aecc4b4 100644 --- a/packages/phrases/src/locales/zh-hk/translation/admin-console/errors.ts +++ b/packages/phrases/src/locales/zh-hk/translation/admin-console/errors.ts @@ -7,8 +7,7 @@ const errors = { invalid_uri_format: '無效的 URI 格式', invalid_origin_format: '無效的 URI origin 格式', invalid_json_format: '無效的 JSON 格式', - /** UNTRANSLATED */ - invalid_regex: 'Invalid regular expression', + invalid_regex: '無效的正則表達式', invalid_error_message_format: '非法的錯誤信息格式', required_field_missing: '請輸入{{field}}', required_field_missing_plural: '至少需要輸入一個{{field}}', @@ -21,8 +20,8 @@ const errors = { not_found: '404 找不到資源', create_internal_role_violation: '你正在創建一個被 Logto 禁止內部角色。嘗試使用不以 "#internal:" 開頭的其他名稱。', - should_be_an_integer: '必须为整数。', - number_should_be_between_inclusive: '数值必须在{{min}}和{{max}}之间(包括{{min}}和{{max}})。', + should_be_an_integer: '必須為整數。', + number_should_be_between_inclusive: '數值必須在{{min}}和{{max}}之間(包括{{min}}和{{max}})', }; export default Object.freeze(errors); diff --git a/packages/phrases/src/locales/zh-hk/translation/admin-console/general.ts b/packages/phrases/src/locales/zh-hk/translation/admin-console/general.ts index 4fc26c9d013..73fd38b1bd5 100644 --- a/packages/phrases/src/locales/zh-hk/translation/admin-console/general.ts +++ b/packages/phrases/src/locales/zh-hk/translation/admin-console/general.ts @@ -25,11 +25,9 @@ const general = { customize: '自定義', enable: '啟用', reminder: '提示', - /** UNTRANSLATED */ - edit: 'Edit', + edit: '編輯', delete: '刪除', - /** UNTRANSLATED */ - deleted: 'Deleted', + deleted: '已刪除', more_options: '更多選項', close: '關閉', copy: '複製', @@ -58,8 +56,7 @@ const general = { demo: '演示', unnamed: '未命名', view: '查看', - /** UNTRANSLATED */ - open: 'Open', + open: '打開', hide: '隱藏', unknown_error: '未知錯誤,請稍後重試。', select: '選擇', @@ -71,8 +68,7 @@ const general = { edit_field: '編輯{{field}}', delete_field: '刪除{{field}}', coming_soon: '即將推出', - /** UNTRANSLATED */ - or: 'Or', + or: '或', }; export default Object.freeze(general); diff --git a/packages/phrases/src/locales/zh-hk/translation/admin-console/jwt-claims.ts b/packages/phrases/src/locales/zh-hk/translation/admin-console/jwt-claims.ts index f0d189ab412..7cd4f1c74b0 100644 --- a/packages/phrases/src/locales/zh-hk/translation/admin-console/jwt-claims.ts +++ b/packages/phrases/src/locales/zh-hk/translation/admin-console/jwt-claims.ts @@ -1,98 +1,57 @@ const jwt_claims = { - /** UNTRANSLATED */ - title: 'Custom JWT', - /** UNTRANSLATED */ - description: - 'Set up custom JWT claims to include in the access token. These claims can be used to pass additional information to your application.', + title: '自訂 JWT', + description: '設定自訂 JWT 声明以包含在存取權杖中。這些声明可用於將額外信息傳遞給您的應用程式。', user_jwt: { - /** UNTRANSLATED */ - card_title: 'For user', - /** UNTRANSLATED */ - card_field: 'User access token', - /** UNTRANSLATED */ - card_description: 'Add user-specific data during access token issuance.', - /** UNTRANSLATED */ - for: 'for user', + card_title: '用於用戶', + card_field: '用戶存取權杖', + card_description: '在發行存取權杖期間添加用戶特定數據。', + for: '用於用戶', }, machine_to_machine_jwt: { - /** UNTRANSLATED */ - card_title: 'For M2M', - /** UNTRANSLATED */ - card_field: 'Machine-to-machine token', - /** UNTRANSLATED */ - card_description: 'Add extra data during machine-to-machine token issuance.', - /** UNTRANSLATED */ - for: 'for M2M', - }, - /** UNTRANSLATED */ - code_editor_title: 'Customize the {{token}} claims', - /** UNTRANSLATED */ - custom_jwt_create_button: 'Add custom claims', - /** UNTRANSLATED */ - custom_jwt_item: 'Custom claims {{for}}', - /** UNTRANSLATED */ - delete_modal_title: 'Delete custom claims', - /** UNTRANSLATED */ - delete_modal_content: 'Are you sure you want to delete the custom claims?', - /** UNTRANSLATED */ - clear: 'Clear', - /** UNTRANSLATED */ - cleared: 'Cleared', - /** UNTRANSLATED */ - restore: 'Restore defaults', - /** UNTRANSLATED */ - restored: 'Restored', - /** UNTRANSLATED */ - data_source_tab: 'Data source', - /** UNTRANSLATED */ - test_tab: 'Test context', - /** UNTRANSLATED */ - jwt_claims_description: 'Default claims are auto-included in the JWT and cannot be overridden.', + card_title: '用於 M2M', + card_field: '機器對機器權杖', + card_description: '在發行機器對機器權杖期間添加額外數據。', + for: '用於 M2M', + }, + code_editor_title: '自訂 {{token}} 声明', + custom_jwt_create_button: '添加自訂声明', + custom_jwt_item: '自訂声明 {{for}}', + delete_modal_title: '刪除自訂声明', + delete_modal_content: '您確定要刪除自訂声明嗎?', + clear: '清空', + cleared: '已清空', + restore: '恢復預設值', + restored: '已恢復', + data_source_tab: '數據來源', + test_tab: '測試上下文', + jwt_claims_description: '默認声明會自動包含在 JWT 中,無法覆蓋。', user_data: { - /** UNTRANSLATED */ - title: 'User data', - /** UNTRANSLATED */ - subtitle: 'Use `data.user` input parameter to provide vital user info.', + title: '用戶數據', + subtitle: '使用 `data.user` 輸入參數提供重要用戶信息。', }, token_data: { - /** UNTRANSLATED */ - title: 'Token data', - /** UNTRANSLATED */ - subtitle: 'Use `token` input parameter for current access token payload. ', + title: '權杖數據', + subtitle: '使用 `token` 輸入參數查看當前存取權杖有效負載。', }, fetch_external_data: { - /** UNTRANSLATED */ - title: 'Fetch external data', - /** UNTRANSLATED */ - subtitle: 'Incorporate data from your external APIs directly into claims.', - /** UNTRANSLATED */ - description: - 'Use the `fetch` function to call your external APIs and include the data in your custom claims. Example: ', + title: '提取外部數據', + subtitle: '將來自外部 API 的數據直接導入声明。', + description: '使用 `fetch` 函數調用您的外部 API 並將數據包含在自訂声明中。例如:', }, environment_variables: { - /** UNTRANSLATED */ - title: 'Set environment variables', - /** UNTRANSLATED */ - subtitle: 'Use environment variables to store sensitive information.', - /** UNTRANSLATED */ - input_field_title: 'Add environment variables', - /** UNTRANSLATED */ - sample_code: 'Accessing environment variables in your custom JWT claims handler. Example: ', + title: '設置環境變數', + subtitle: '使用環境變數存儲敏感信息。', + input_field_title: '添加環境變數', + sample_code: '在您的自訂 JWT 声明處理程序中訪問環境變數。例如:', }, - /** UNTRANSLATED */ - jwt_claims_hint: - 'Limit custom claims to under 50KB. Default JWT claims are automatically included in the token and can not be overridden.', + jwt_claims_hint: '將自訂声明限制在 50KB 以下。默認 JWT 声明會自動包含在權杖中,不能被覆蓋。', tester: { - /** UNTRANSLATED */ - subtitle: 'Adjust mock token and user data for testing.', - /** UNTRANSLATED */ - run_button: 'Run test', - /** UNTRANSLATED */ - result_title: 'Test result', + subtitle: '調整模擬權杖和用戶數據以進行測試。', + run_button: '運行測試', + result_title: '測試結果', }, form_error: { - /** UNTRANSLATED */ - invalid_json: 'Invalid JSON format', + invalid_json: '無效的 JSON 格式', }, }; diff --git a/packages/phrases/src/locales/zh-hk/translation/admin-console/subscription/quota-item.ts b/packages/phrases/src/locales/zh-hk/translation/admin-console/subscription/quota-item.ts index 171163b4a4f..266bd3f6f96 100644 --- a/packages/phrases/src/locales/zh-hk/translation/admin-console/subscription/quota-item.ts +++ b/packages/phrases/src/locales/zh-hk/translation/admin-console/subscription/quota-item.ts @@ -34,23 +34,18 @@ const quota_item = { not_eligible: '刪除您的機器對機器應用程式', }, third_party_applications_limit: { - /** UNTRANSLATED */ - name: 'Third-party apps', - /** UNTRANSLATED */ - limited: '{{count, number}} third-party app', - /** UNTRANSLATED */ - limited_other: '{{count, number}} third-party apps', - /** UNTRANSLATED */ - unlimited: 'Unlimited third-party apps', - /** UNTRANSLATED */ - not_eligible: 'Remove your third-party apps', + name: '第三方應用程式', + limited: '{{count, number}} 第三方應用程式', + limited_other: '{{count, number}} 第三方應用程式', + unlimited: '無限第三方應用程式', + not_eligible: '刪除您的第三方應用程式', }, resources_limit: { name: 'API 資源', - limited: '{{count, number}} 個API 資源', - limited_other: '{{count, number}} 個API 資源', - unlimited: '無限API 資源', - not_eligible: '刪除您的API 資源', + limited: '{{count, number}} 個 API 資源', + limited_other: '{{count, number}} 個 API 資源', + unlimited: '無限 API 資源', + not_eligible: '刪除您的 API 資源', }, scopes_per_resource_limit: { name: '資源範圍', @@ -72,10 +67,10 @@ const quota_item = { not_eligible: '停用統一登入', }, built_in_email_connector_enabled: { - name: '內置電子郵件連接器', - limited: '內置電子郵件連接器', - unlimited: '內置電子郵件連接器', - not_eligible: '刪除您的內置電子郵件連接器', + name: '內建電子郵件連接器', + limited: '內建電子郵件連接器', + unlimited: '內建電子郵件連接器', + not_eligible: '刪除您的內建電子郵件連接器', }, social_connectors_limit: { name: '社交連接器', @@ -152,26 +147,17 @@ const quota_item = { not_eligible: '移除您的企業單一登入', }, tenant_members_limit: { - /** UNTRANSLATED */ - name: 'Tenant members', - /** UNTRANSLATED */ - limited: '{{count, number}} tenant member', - /** UNTRANSLATED */ - limited_other: '{{count, number}} tenant members', - /** UNTRANSLATED */ - unlimited: 'Unlimited tenant members', - /** UNTRANSLATED */ - not_eligible: 'Remove your tenant members', + name: '租戶成員', + limited: '{{count, number}} 租戶成員', + limited_other: '{{count, number}} 租戶成員', + unlimited: '無限租戶成員', + not_eligible: '刪除您的租戶成員', }, custom_jwt_enabled: { - /** UNTRANSLATED */ - name: 'Custom JWT', - /** UNTRANSLATED */ - limited: 'Custom JWT', - /** UNTRANSLATED */ - unlimited: 'Custom JWT', - /** UNTRANSLATED */ - not_eligible: 'Remove your JWT claims customizer', + name: '自定義JWT', + limited: '自定義JWT', + unlimited: '自定義JWT', + not_eligible: '刪除您的JWT聲明自訂程式', }, }; diff --git a/packages/phrases/src/locales/zh-hk/translation/admin-console/subscription/quota-table.ts b/packages/phrases/src/locales/zh-hk/translation/admin-console/subscription/quota-table.ts index 33cfa75f20e..1fac44b58b4 100644 --- a/packages/phrases/src/locales/zh-hk/translation/admin-console/subscription/quota-table.ts +++ b/packages/phrases/src/locales/zh-hk/translation/admin-console/subscription/quota-table.ts @@ -9,8 +9,7 @@ const quota_table = { title: '應用程式', total: '應用程式總數', m2m: '機器到機器', - /** UNTRANSLATED */ - third_party: 'Third-party apps', + third_party: '第三方應用程式', }, resource: { title: 'API 資源', @@ -61,25 +60,20 @@ const quota_table = { community: '社群', customer_ticket: '客戶支援票據', premium: '高級版', - email_ticket_support: 'Email ticket support', + email_ticket_support: '電子郵件票務支援', soc2_report: 'SOC2報告', hipaa_or_baa_report: 'HIPAA/BAA報告', }, developers_and_platform: { - /** UNTRANSLATED */ - title: 'Developers and platform', - /** UNTRANSLATED */ + title: '開發者和平台', hooks: 'Webhooks', - /** UNTRANSLATED */ - audit_logs_retention: 'Audit logs retention', - /** UNTRANSLATED */ - jwt_claims: 'JWT claims', - /** UNTRANSLATED */ - tenant_members: 'Tenant members', + audit_logs_retention: '審計日誌保留', + jwt_claims: 'JWT聲明', + tenant_members: '租戶成員', }, unlimited: '無限制', contact: '聯絡', - monthly_price: '${{value, number}}/月', + monthly_price: '${{value, number}} /月', days_one: '{{count, number}} 天', days_other: '{{count, number}} 天', add_on: '附加功能', @@ -94,17 +88,14 @@ const quota_table = { mau_tip: 'MAU(每月活躍用戶)是指在計費週期內與Logto交換過至少一個令牌的獨立用戶數量。', tokens_tip: 'Logto 發行的所有類型令牌,包括訪問令牌、刷新令牌等。', mao_tip: 'MAO(月度活躍組織)指的是在計費週期內至少有一個MAU(月度活躍用戶)的獨特組織數量。', - /** UNTRANSLATED */ - third_party_tip: - 'Use Logto as your OIDC identity provider for third-party app sign-ins and permission grants.', + third_party_tip: '使用Logto作為您的OIDC身份提供者,用於第三方應用程式的登錄和權限授予。', included: '已包含 {{value, number}}', included_mao: '已包含 {{value, number}} MAO', extra_quota_price: '然後每月 ${{value, number}} / 每個之後', per_month_each: '每月 ${{value, number}} / 每個', extra_mao_price: '然後每 MAO ${{value, number}}', per_month: '每月 ${{value, number}}', - /** UNTRANSLATED */ - per_member: 'Then ${{value, number}} per member', + per_member: '然後 ${{value, number}} 每個成員', }; export default Object.freeze(quota_table); diff --git a/packages/phrases/src/locales/zh-hk/translation/admin-console/tabs.ts b/packages/phrases/src/locales/zh-hk/translation/admin-console/tabs.ts index 15d546ddca3..30d58e36670 100644 --- a/packages/phrases/src/locales/zh-hk/translation/admin-console/tabs.ts +++ b/packages/phrases/src/locales/zh-hk/translation/admin-console/tabs.ts @@ -14,8 +14,7 @@ const tabs = { docs: '文檔', tenant_settings: '租戶設置', mfa: '多重認證', - /** UNTRANSLATED */ - customize_jwt: 'Custom JWT', + customize_jwt: '自定義 JWT', signing_keys: '簽署密鑰', organization_template: '組織模板', }; diff --git a/packages/phrases/src/locales/zh-hk/translation/admin-console/upsell/index.ts b/packages/phrases/src/locales/zh-hk/translation/admin-console/upsell/index.ts index 5120cc4db1f..be2544c7f2d 100644 --- a/packages/phrases/src/locales/zh-hk/translation/admin-console/upsell/index.ts +++ b/packages/phrases/src/locales/zh-hk/translation/admin-console/upsell/index.ts @@ -19,7 +19,7 @@ const upsell = { upgrade_success: '成功升級至', }, mau_exceeded_modal: { - title: 'MAU 超過限制,請升級您的計劃。', + title: 'MAU 超出限制,請升級您的計劃。', notification: '您當前的 MAU 已超過的限制。請立即升級到高級計劃,以避免 Logto 服務的暫停。', update_plan: '更新計劃', @@ -35,8 +35,7 @@ const upsell = { api_resource: 'API 資源', machine_to_machine: '機器對機器應用', tokens: '{{limit}}M 令牌', - /** UNTRANSLATED */ - tenant_member: 'tenant member', + tenant_member: '租戶成員', }, charge_notification_for_quota_limit: '您已超出{{item}}配額限制。Logto將為超出配額限制的使用添加費用。計費將從新的附加定價設計發布當天開始。 了解更多', diff --git a/packages/phrases/src/locales/zh-hk/translation/admin-console/upsell/paywall.ts b/packages/phrases/src/locales/zh-hk/translation/admin-console/upsell/paywall.ts index ffb45e09d13..5761615e60f 100644 --- a/packages/phrases/src/locales/zh-hk/translation/admin-console/upsell/paywall.ts +++ b/packages/phrases/src/locales/zh-hk/translation/admin-console/upsell/paywall.ts @@ -18,57 +18,49 @@ const paywall = { scopes_per_resource_other: '已達到的{{count, number}}個 API 資源每個權限限制。立即升級以擴展。如需任何幫助,請聯繫我們。', custom_domain: - '升級至HobbyPro方案以解鎖自定義域功能。如需要任何協助,歡迎聯繫我們。', + '升級至HobbyPro方案以解鎖自定義域功能。如需要任何協助,歡迎聯絡我們。', social_connectors: '已達到的{{count, number}}個社交連接器限制。為滿足您團隊的需求,請升級計劃以獲取額外的社交連接器,並可以使用 OIDC、OAuth 2.0 和 SAML 協議創建您自己的連接器。如需任何幫助,請聯繫我們。', social_connectors_other: '已達到的{{count, number}}個社交連接器限制。為滿足您團隊的需求,請升級計劃以獲取額外的社交連接器,並可以使用 OIDC、OAuth 2.0 和 SAML 協議創建您自己的連接器。如需任何幫助,請聯繫我們。', standard_connectors_feature: - '升級至HobbyPro計劃,使用 OIDC、OAuth 2.0 和 SAML 協議創建您自己的連接器,無限制的社交連接器以及所有高級功能。如需任何協助,歡迎聯繫我們。', + '升級至HobbyPro計劃,使用 OIDC、OAuth 2.0 和 SAML 協議創建您自己的連接器,無限制的社交連接器以及所有高級功能。如需任何協助,歡迎聯絡我們。', standard_connectors: - '已達到的{{count, number}}個社交連接器限制。為滿足您團隊的需求,請升級計劃以獲取額外的社交連接器,並可以使用 OIDC、OAuth 2.0 和 SAML 協議創建您自己的連接器。如需任何幫助,請聯繫我們。', + '已達到的{{count, number}}個社交連接器限制。為滿足您團隊的需求,請升級計劃以獲取額外的社交連接器,並可以使用 OIDC、OAuth 2.0 和 SAML 協議創建您自己的連接器。如需任何協助,請聯絡我們。', standard_connectors_other: - '已達到的{{count, number}}個社交連接器限制。為滿足您團隊的需求,請升級計劃以獲取額外的社交連接器,並可以使用 OIDC、OAuth 2.0 和 SAML 協議創建您自己的連接器。如需任何幫助,請聯繫我們。', + '已達到的{{count, number}}個社交連接器限制。為滿足您團隊的需求,請升級計劃以獲取額外的社交連接器,並可以使用 OIDC、OAuth 2.0 和 SAML 協議創建您自己的連接器。如需任何協助,請聯繫我們。', standard_connectors_pro: - '已達到的{{count, number}}個標準連接器限制。為滿足您團隊的需求,請升級至企業版計劃以獲取額外的社交連接器,並可以使用 OIDC、OAuth 2.0 和 SAML 協議創建您自己的連接器。如需任何協助,歡迎聯繫我們。', + '已達到的{{count, number}}個標準連接器限制。為滿足您團隊的需求,請升級至企業版計劃以獲取額外的社交連接器,並可以使用 OIDC、OAuth 2.0 和 SAML 協議創建您自己的連接器。如需任何協助,歡迎聯絡我們。', standard_connectors_pro_other: '已達到的{{count, number}}個標準連接器限制。為滿足您團隊的需求,請升級至企業版計劃以獲取額外的社交連接器,並可以使用 OIDC、OAuth 2.0 和 SAML 協議創建您自己的連接器。如需任何協助,歡迎聯繫我們。', roles: - '已達到的{{count, number}}個角色限制。升級計劃以添加額外的角色和權限。如需任何協助,歡迎聯繫我們。', + '已達到的{{count, number}}個角色限制。升級計劃以添加額外的角色和權限。如需任何協助,歡迎聯絡我們。', roles_other: - '已達到的{{count, number}}個角色限制。升級計劃以添加額外的角色和權限。如需任何協助,歡迎聯繫我們。', + '已達到的{{count, number}}個角色限制。升級計劃以添加額外的角色和權限。如需任何協助,歡迎聯絡我們。', machine_to_machine_roles: - '{{count, number}}個機器對機器角色達到了的限制。升級計劃以添加額外的角色和權限。如需要任何協助,請隨時聯繫我們。', + '{{count, number}}個機器對機器角色達到了的限制。升級計劃以添加額外的角色和權限。如需要任何協助,請隨時聯絡我們。', machine_to_machine_roles_other: - '{{count, number}}個機器對機器角色達到了的限制。升級計劃以添加額外的角色和權限。如需要任何協助,請隨時聯繫我們。', + '{{count, number}}個機器對機器角色達到了的限制。升級計劃以添加額外的角色和權限。如需要任何協助,請隨時聯絡我們。', scopes_per_role: - '已達到的{{count, number}}個角色每個權限限制。升級計劃以添加額外的角色和權限。如需任何協助,歡迎聯繫我們。', + '已達到的{{count, number}}個角色每個權限限制。升級計劃以添加額外的角色和權限。如需任何協助,歡迎聯絡我們。', scopes_per_role_other: - '已達到的{{count, number}}個角色每個權限限制。升級計劃以添加額外的角色和權限。如需任何協助,歡迎聯繫我們。', + '已達到的{{count, number}}個角色每個權限限制。升級計劃以添加額外的角色和權限。如需任何協助,歡迎聯絡我們。', hooks: - '已達到的{{count, number}}個 Webhook 限制。升級計劃以創建更多 Webhook。如需任何協助,歡迎聯繫我們。', + '已達到的{{count, number}}個 Webhook 限制。升級計劃以創建更多 Webhook。如需任何協助,歡迎聯絡我們。', hooks_other: - '已達到的{{count, number}}個 Webhook 限制。升級計劃以創建更多 Webhook。如需任何幫助,請聯繫我們。', - mfa: '升級到付費計劃以解鎖MFA以提高安全性。如果需要任何協助,請隨時聯繫我們。', - organizations: '升級至付費計劃以解鎖組織。如需要任何協助,請隨時聯繫我們。', - /** UNTRANSLATED */ + '已達到的{{count, number}}個 Webhook 限制。升級計劃以創建更多 Webhook。如需任何幫助,請聯絡我們。', + mfa: '升級到付費計劃以解鎖MFA以提高安全性。如果需要任何協助,請隨時聯絡我們。', + organizations: '升級至付費計劃以解鎖組織。如需要任何協助,請隨時聯絡我們。', third_party_apps: - 'Unlock Logto as IdP for third-party apps by upgrading to a paid plan. For any assistance, feel free to contact us.', - /** UNTRANSLATED */ - sso_connectors: - 'Unlock enterprise sso by upgrading to a paid plan. For any assistance, feel free to contact us.', - /** UNTRANSLATED */ - tenant_members: - 'Unlock collaboration feature by upgrading to a paid plan. For any assistance, feel free to contact us.', - /** UNTRANSLATED */ + '藉由升級至付費計劃,將 Logto 解鎖為第三方應用程式的 IdP。如需任何協助,歡迎聯絡我們。', + sso_connectors: '升級至付費計劃以解鎖企業單一登錄(SSO)。如需要任何協助,歡迎聯絡我們。', + tenant_members: '透過升級至付費計劃,解鎖協作功能。如需要任何協助,歡迎聯絡我們。', tenant_members_dev_plan: - "You've reached your {{limit}}-member limit. Release a member or revoke a pending invitation to add someone new. Need more seats? Feel free to contact us.", + '您已達到 {{limit}} 的成員限制。釋放一位成員或撤回待定邀請以新增新成員。需要更多席位?歡迎隨時聯絡我們。', custom_jwt: { - /** UNTRANSLATED */ - title: 'Add custom claims', - /** UNTRANSLATED */ + title: '新增自訂聲索', description: - "Upgrade to a paid plan for custom JWT functionality and premium benefits. Don't hesitate to contact us if you have any questions.", + '升級至付費計劃以獲得自訂 JWT 功能和專業服務。如有任何問題,歡迎隨時聯絡我們。', }, }; diff --git a/packages/phrases/src/locales/zh-tw/errors/jwt-customizer.ts b/packages/phrases/src/locales/zh-tw/errors/jwt-customizer.ts index c7c5c1e2af9..5ea2f0875c8 100644 --- a/packages/phrases/src/locales/zh-tw/errors/jwt-customizer.ts +++ b/packages/phrases/src/locales/zh-tw/errors/jwt-customizer.ts @@ -1,8 +1,6 @@ const jwt_customizer = { - /** UNTRANSLATED */ - general: 'An error occurred while customizing the JWT token. Please try again later.', - /** UNTRANSLATED */ - can_not_create_for_admin_tenant: 'Cannot create a JWT token customizer for the admin tenant.', + general: '在自訂 JWT 權杖時發生錯誤。請稍後再試。', + can_not_create_for_admin_tenant: '無法為管理員租戶建立 JWT 權杖自訂程式。', }; export default Object.freeze(jwt_customizer); diff --git a/packages/phrases/src/locales/zh-tw/translation/admin-console/errors.ts b/packages/phrases/src/locales/zh-tw/translation/admin-console/errors.ts index 47ca3924fab..3d5c7c90d51 100644 --- a/packages/phrases/src/locales/zh-tw/translation/admin-console/errors.ts +++ b/packages/phrases/src/locales/zh-tw/translation/admin-console/errors.ts @@ -7,8 +7,7 @@ const errors = { invalid_uri_format: '無效的 URI 格式', invalid_origin_format: '無效的 URI origin 格式', invalid_json_format: '無效的 JSON 格式', - /** UNTRANSLATED */ - invalid_regex: 'Invalid regular expression', + invalid_regex: '非法的正則表達式', invalid_error_message_format: '非法的錯誤訊息格式', required_field_missing: '請輸入{{field}}', required_field_missing_plural: '至少需要輸入一個{{field}}', diff --git a/packages/phrases/src/locales/zh-tw/translation/admin-console/general.ts b/packages/phrases/src/locales/zh-tw/translation/admin-console/general.ts index 699d4832c5d..2b7ad3d8f63 100644 --- a/packages/phrases/src/locales/zh-tw/translation/admin-console/general.ts +++ b/packages/phrases/src/locales/zh-tw/translation/admin-console/general.ts @@ -25,11 +25,9 @@ const general = { customize: '自定義', enable: '啟用', reminder: '提示', - /** UNTRANSLATED */ - edit: 'Edit', + edit: '編輯', delete: '刪除', - /** UNTRANSLATED */ - deleted: 'Deleted', + deleted: '已刪除', more_options: '更多選項', close: '關閉', copy: '複製', @@ -58,8 +56,7 @@ const general = { demo: '演示', unnamed: '未命名', view: '查看', - /** UNTRANSLATED */ - open: 'Open', + open: '打開', hide: '隱藏', unknown_error: '未知錯誤,請稍後重試。', select: '選擇', @@ -71,8 +68,7 @@ const general = { edit_field: '編輯{{field}}', delete_field: '刪除{{field}}', coming_soon: '即將上線', - /** UNTRANSLATED */ - or: 'Or', + or: '或', }; export default Object.freeze(general); diff --git a/packages/phrases/src/locales/zh-tw/translation/admin-console/jwt-claims.ts b/packages/phrases/src/locales/zh-tw/translation/admin-console/jwt-claims.ts index f0d189ab412..656757247e6 100644 --- a/packages/phrases/src/locales/zh-tw/translation/admin-console/jwt-claims.ts +++ b/packages/phrases/src/locales/zh-tw/translation/admin-console/jwt-claims.ts @@ -1,98 +1,57 @@ const jwt_claims = { - /** UNTRANSLATED */ - title: 'Custom JWT', - /** UNTRANSLATED */ - description: - 'Set up custom JWT claims to include in the access token. These claims can be used to pass additional information to your application.', + title: '自定義 JWT', + description: '設置自定義 JWT 声明以包含在訪問令牌中。這些聲明可用於向應用程序傳遞附加信息。', user_jwt: { - /** UNTRANSLATED */ - card_title: 'For user', - /** UNTRANSLATED */ - card_field: 'User access token', - /** UNTRANSLATED */ - card_description: 'Add user-specific data during access token issuance.', - /** UNTRANSLATED */ - for: 'for user', + card_title: '針對用戶', + card_field: '用戶訪問令牌', + card_description: '在發出訪問令牌時添加用戶特定數據。', + for: '針對用戶', }, machine_to_machine_jwt: { - /** UNTRANSLATED */ - card_title: 'For M2M', - /** UNTRANSLATED */ - card_field: 'Machine-to-machine token', - /** UNTRANSLATED */ - card_description: 'Add extra data during machine-to-machine token issuance.', - /** UNTRANSLATED */ - for: 'for M2M', - }, - /** UNTRANSLATED */ - code_editor_title: 'Customize the {{token}} claims', - /** UNTRANSLATED */ - custom_jwt_create_button: 'Add custom claims', - /** UNTRANSLATED */ - custom_jwt_item: 'Custom claims {{for}}', - /** UNTRANSLATED */ - delete_modal_title: 'Delete custom claims', - /** UNTRANSLATED */ - delete_modal_content: 'Are you sure you want to delete the custom claims?', - /** UNTRANSLATED */ - clear: 'Clear', - /** UNTRANSLATED */ - cleared: 'Cleared', - /** UNTRANSLATED */ - restore: 'Restore defaults', - /** UNTRANSLATED */ - restored: 'Restored', - /** UNTRANSLATED */ - data_source_tab: 'Data source', - /** UNTRANSLATED */ - test_tab: 'Test context', - /** UNTRANSLATED */ - jwt_claims_description: 'Default claims are auto-included in the JWT and cannot be overridden.', + card_title: '針對 M2M', + card_field: '機器對機器令牌', + card_description: '在發出機器對機器令牌時添加額外數據。', + for: '針對 M2M', + }, + code_editor_title: '自定義 {{token}} 声明', + custom_jwt_create_button: '添加自定義声明', + custom_jwt_item: '自定義声明 {{for}}', + delete_modal_title: '刪除自定義声明', + delete_modal_content: '您確定要刪除自定義声明嗎?', + clear: '清除', + cleared: '已清除', + restore: '恢復默認值', + restored: '已恢復', + data_source_tab: '數據源', + test_tab: '測試上下文', + jwt_claims_description: '默認声明自動包含在 JWT 中,無法覆蓋。', user_data: { - /** UNTRANSLATED */ - title: 'User data', - /** UNTRANSLATED */ - subtitle: 'Use `data.user` input parameter to provide vital user info.', + title: '用戶數據', + subtitle: '使用 `data.user` 輸入參數提供重要用戶信息。', }, token_data: { - /** UNTRANSLATED */ - title: 'Token data', - /** UNTRANSLATED */ - subtitle: 'Use `token` input parameter for current access token payload. ', + title: '令牌數據', + subtitle: '使用 `token` 輸入參數獲取當前訪問令牌有效載荷。', }, fetch_external_data: { - /** UNTRANSLATED */ - title: 'Fetch external data', - /** UNTRANSLATED */ - subtitle: 'Incorporate data from your external APIs directly into claims.', - /** UNTRANSLATED */ - description: - 'Use the `fetch` function to call your external APIs and include the data in your custom claims. Example: ', + title: '提取外部數據', + subtitle: '直接將來自外部 APIs 的數據合併到声明中。', + description: '使用 `fetch` 函數調用外部 APIs 並將數據包含在您的自定義声明中。示例:', }, environment_variables: { - /** UNTRANSLATED */ - title: 'Set environment variables', - /** UNTRANSLATED */ - subtitle: 'Use environment variables to store sensitive information.', - /** UNTRANSLATED */ - input_field_title: 'Add environment variables', - /** UNTRANSLATED */ - sample_code: 'Accessing environment variables in your custom JWT claims handler. Example: ', + title: '設置環境變量', + subtitle: '使用環境變量存儲敏感信息。', + input_field_title: '添加環境變量', + sample_code: '在自定義 JWT 声明處理程序中訪問環境變量。示例:', }, - /** UNTRANSLATED */ - jwt_claims_hint: - 'Limit custom claims to under 50KB. Default JWT claims are automatically included in the token and can not be overridden.', + jwt_claims_hint: '將自定義声明限制在 50KB 以下。默認 JWT 声明將自動包含在令牌中,無法覆蓋。', tester: { - /** UNTRANSLATED */ - subtitle: 'Adjust mock token and user data for testing.', - /** UNTRANSLATED */ - run_button: 'Run test', - /** UNTRANSLATED */ - result_title: 'Test result', + subtitle: '調整測試用的模擬令牌和用戶數據。', + run_button: '運行測試', + result_title: '測試結果', }, form_error: { - /** UNTRANSLATED */ - invalid_json: 'Invalid JSON format', + invalid_json: '無效的 JSON 格式', }, }; diff --git a/packages/phrases/src/locales/zh-tw/translation/admin-console/subscription/quota-item.ts b/packages/phrases/src/locales/zh-tw/translation/admin-console/subscription/quota-item.ts index 725b2c2c8f0..70232ea0b94 100644 --- a/packages/phrases/src/locales/zh-tw/translation/admin-console/subscription/quota-item.ts +++ b/packages/phrases/src/locales/zh-tw/translation/admin-console/subscription/quota-item.ts @@ -34,16 +34,11 @@ const quota_item = { not_eligible: '移除你的機器對機器應用程式', }, third_party_applications_limit: { - /** UNTRANSLATED */ - name: 'Third-party apps', - /** UNTRANSLATED */ - limited: '{{count, number}} third-party app', - /** UNTRANSLATED */ - limited_other: '{{count, number}} third-party apps', - /** UNTRANSLATED */ - unlimited: 'Unlimited third-party apps', - /** UNTRANSLATED */ - not_eligible: 'Remove your third-party apps', + name: '第三方應用程式', + limited: '{{count, number}} 第三方應用程式', + limited_other: '{{count, number}} 第三方應用程式', + unlimited: '不限第三方應用程式數', + not_eligible: '移除你的第三方應用程式', }, resources_limit: { name: 'API 資源', @@ -143,7 +138,7 @@ const quota_item = { name: '多因素認證', limited: '多因素認證', unlimited: '多因素認證', - not_eligible: '移除您的多因素認證', + not_eligible: '移除你的多因素認證', }, sso_enabled: { name: '企業單一登錄', @@ -152,26 +147,17 @@ const quota_item = { not_eligible: '移除你的 企業單一登錄', }, tenant_members_limit: { - /** UNTRANSLATED */ - name: 'Tenant members', - /** UNTRANSLATED */ - limited: '{{count, number}} tenant member', - /** UNTRANSLATED */ - limited_other: '{{count, number}} tenant members', - /** UNTRANSLATED */ - unlimited: 'Unlimited tenant members', - /** UNTRANSLATED */ - not_eligible: 'Remove your tenant members', + name: '租戶成員', + limited: '{{count, number}} 租戶成員', + limited_other: '{{count, number}} 租戶成員', + unlimited: '不限租戶成員數', + not_eligible: '移除你的租戶成員', }, custom_jwt_enabled: { - /** UNTRANSLATED */ - name: 'Custom JWT', - /** UNTRANSLATED */ - limited: 'Custom JWT', - /** UNTRANSLATED */ - unlimited: 'Custom JWT', - /** UNTRANSLATED */ - not_eligible: 'Remove your JWT claims customizer', + name: '自訂 JWT', + limited: '自訂 JWT', + unlimited: '自訂 JWT', + not_eligible: '移除你的 JWT 声明自訂器', }, }; diff --git a/packages/phrases/src/locales/zh-tw/translation/admin-console/subscription/quota-table.ts b/packages/phrases/src/locales/zh-tw/translation/admin-console/subscription/quota-table.ts index 0a5b55b8ddd..8809ef7021a 100644 --- a/packages/phrases/src/locales/zh-tw/translation/admin-console/subscription/quota-table.ts +++ b/packages/phrases/src/locales/zh-tw/translation/admin-console/subscription/quota-table.ts @@ -9,8 +9,7 @@ const quota_table = { title: '應用程式', total: '總應用程式數', m2m: '機器對機器', - /** UNTRANSLATED */ - third_party: 'Third-party apps', + third_party: '第三方應用程式', }, resource: { title: 'API 資源', @@ -66,20 +65,15 @@ const quota_table = { hipaa_or_baa_report: 'HIPAA/BAA 報告', }, developers_and_platform: { - /** UNTRANSLATED */ - title: 'Developers and platform', - /** UNTRANSLATED */ + title: '開發人員與平台', hooks: 'Webhooks', - /** UNTRANSLATED */ - audit_logs_retention: 'Audit logs retention', - /** UNTRANSLATED */ - jwt_claims: 'JWT claims', - /** UNTRANSLATED */ - tenant_members: 'Tenant members', + audit_logs_retention: '審計日誌保留', + jwt_claims: 'JWT 声明', + tenant_members: '租戶成員', }, unlimited: '無限制', contact: '聯絡', - monthly_price: '${{value, number}}/月', + monthly_price: '${{value, number}} / 月', days_one: '{{count, number}} 天', days_other: '{{count, number}} 天', add_on: '附加功能', @@ -94,17 +88,14 @@ const quota_table = { mau_tip: 'MAU(每月活躍用戶)是指在計費週期內與Logto交換過至少一個令牌的獨立用戶數量。', tokens_tip: 'Logto 發行的所有類型令牌,包括訪問令牌、刷新令牌等。', mao_tip: 'MAO(月度活躍組織)指的是在計費週期內至少有一個MAU(月度活躍用戶)的獨特組織數量。', - /** UNTRANSLATED */ - third_party_tip: - 'Use Logto as your OIDC identity provider for third-party app sign-ins and permission grants.', + third_party_tip: '使用Logto作為您的OIDC身份提供程序,以便第三方應用程式進行登錄和權限授予。', included: '已包含{{value, number}}', included_mao: '已包含 {{value, number}} MAO', extra_quota_price: '然後每月 ${{value, number}} / 每個之後', per_month_each: '每月 ${{value, number}} / 每個', extra_mao_price: '然後每 MAO ${{value, number}}', per_month: '每月 ${{value, number}}', - /** UNTRANSLATED */ - per_member: 'Then ${{value, number}} per member', + per_member: '然後每位會員 ${{value, number}}', }; export default Object.freeze(quota_table); diff --git a/packages/phrases/src/locales/zh-tw/translation/admin-console/tabs.ts b/packages/phrases/src/locales/zh-tw/translation/admin-console/tabs.ts index af7d44d984d..2f46d6042e2 100644 --- a/packages/phrases/src/locales/zh-tw/translation/admin-console/tabs.ts +++ b/packages/phrases/src/locales/zh-tw/translation/admin-console/tabs.ts @@ -14,8 +14,7 @@ const tabs = { docs: '文件', tenant_settings: '租戶設定', mfa: '多重認證', - /** UNTRANSLATED */ - customize_jwt: 'Custom JWT', + customize_jwt: '自訂 JWT', signing_keys: '簽署密鑰', organization_template: '組織模板', }; diff --git a/packages/phrases/src/locales/zh-tw/translation/admin-console/upsell/index.ts b/packages/phrases/src/locales/zh-tw/translation/admin-console/upsell/index.ts index 71a7b5fe07b..0258d603ee6 100644 --- a/packages/phrases/src/locales/zh-tw/translation/admin-console/upsell/index.ts +++ b/packages/phrases/src/locales/zh-tw/translation/admin-console/upsell/index.ts @@ -35,8 +35,7 @@ const upsell = { api_resource: 'API 資源', machine_to_machine: '機器對機器應用', tokens: '{{limit}}M 令牌', - /** UNTRANSLATED */ - tenant_member: 'tenant member', + tenant_member: '租戶成員', }, charge_notification_for_quota_limit: '您已超出{{item}}額度限制。Logto將為超出額度限制的使用添加費用。計費將從新的附加價格設計發布當天開始。 了解更多', diff --git a/packages/phrases/src/locales/zh-tw/translation/admin-console/upsell/paywall.ts b/packages/phrases/src/locales/zh-tw/translation/admin-console/upsell/paywall.ts index afbdf7d6c2c..5a78bf82c70 100644 --- a/packages/phrases/src/locales/zh-tw/translation/admin-console/upsell/paywall.ts +++ b/packages/phrases/src/locales/zh-tw/translation/admin-console/upsell/paywall.ts @@ -30,7 +30,7 @@ const paywall = { standard_connectors_other: '已達到的{{count, number}}個社交連接器限制。為滿足您團隊的需求,請升級計劃以獲取額外的社交連接器,並可以使用 OIDC、OAuth 2.0 和 SAML 協議創建您自己的連接器。如需任何幫助,請聯繫我們。', standard_connectors_pro: - '已達到的{{count, number}}個標準連接器限制。為滿足您團隊的需求,請升級至企業版計劃以獲取額外的社交連接器,並可以使用 OIDC、OAuth 2.0 和 SAML 協議創建您自己的連接器。如需任何幫助,請聯繫我們。', + '已達到的{{count, number}}個標準連接器限制。為滿足您團隊的需求,請升級至企業版計劃以獲取額外的社交連接器,並可以使用 OIDC、OAuth 2.0 和 SAML 協議創建您自己的連接器。如需任何幫助,請聯絡我們。', standard_connectors_pro_other: '已達到的{{count, number}}個標準連接器限制。為滿足您團隊的需求,請升級至企業版計劃以獲取額外的社交連接器,並可以使用 OIDC、OAuth 2.0 和 SAML 協議創建您自己的連接器。如需任何幫助,請聯繫我們。', roles: @@ -38,37 +38,29 @@ const paywall = { roles_other: '已達到的{{count, number}}個角色限制。升級計劃以添加額外的角色和權限。如需任何幫助,請聯繫我們。', machine_to_machine_roles: - '{{count, number}} machine-to-machine角色已達到的限制。升級計劃以添加額外的角色和權限。如果需要任何幫助,請隨時聯繫我們。', + '{{count, number}} machine-to-machine角色已達到的限制。升級計劃以添加額外的角色和權限。如果需要任何幫助,請隨時聯絡我們。', machine_to_machine_roles_other: - '{{count, number}} machine-to-machine角色已達到的限制。升級計劃以添加額外的角色和權限。如果需要任何幫助,請隨時聯繫我們。', + '{{count, number}} machine-to-machine角色已達到的限制。升級計劃以添加額外的角色和權限。如果需要任何幫助,請隨時聯絡我們。', scopes_per_role: '已達到的{{count, number}}個角色每個權限限制。升級計劃以添加額外的角色和權限。如需任何幫助,請聯繫我們。', scopes_per_role_other: '已達到的{{count, number}}個角色每個權限限制。升級計劃以添加額外的角色和權限。如需任何幫助,請聯繫我們。', hooks: - '已達到的{{count, number}}個 Webhook 限制。升級計劃以創建更多 Webhook。如需任何幫助,請聯繫我們。', + '已達到的{{count, number}}個 Webhook 限制。升級計劃以創建更多 Webhook。如需任何幫助,請聯繹我們。', hooks_other: - '已達到的{{count, number}}個 Webhook 限制。升級計劃以創建更多 Webhook。如需任何幫助,請聯繫我們。', - mfa: '升級到付費計劃以解鎖MFA以提高安全性。如果需要任何協助,請隨時聯繫我們。', - organizations: '升級到付費計劃以解鎖組織。如果需要任何協助,請隨時聯繫我們。', - /** UNTRANSLATED */ + '已達到的{{count, number}}個 Webhook 限制。升級計劃以創建更多 Webhook。如需任何幫助,請聯繹我們。', + mfa: '升級到付費計劃以解鎖MFA以提高安全性。如果需要任何協助,請隨時聯絡我們。', + organizations: '升級到付費計劃以解鎖組織。如果需要任何協助,請隨時聯繹我們。', third_party_apps: - 'Unlock Logto as IdP for third-party apps by upgrading to a paid plan. For any assistance, feel free to contact us.', - /** UNTRANSLATED */ - sso_connectors: - 'Unlock enterprise sso by upgrading to a paid plan. For any assistance, feel free to contact us.', - /** UNTRANSLATED */ - tenant_members: - 'Unlock collaboration feature by upgrading to a paid plan. For any assistance, feel free to contact us.', - /** UNTRANSLATED */ + '透過升級到付費計劃將Logto解鎖為第三方應用程式的IdP。如需任何協助,歡迎聯繹我們。', + sso_connectors: '通過升級到付費計劃來解鎖企業SSO。如需任何協助,歡迎聯繹我們。', + tenant_members: '通過升級到付費計劃來解鎖合作功能。如需任何協助,歡迎聯繹我們。', tenant_members_dev_plan: - "You've reached your {{limit}}-member limit. Release a member or revoke a pending invitation to add someone new. Need more seats? Feel free to contact us.", + '您已達到{{limit}}成員限制。釋放一個成員,或撤銷一個待處理的邀請以添加新成員。需要更多名額?歡迎隨時聯繹我們。', custom_jwt: { - /** UNTRANSLATED */ - title: 'Add custom claims', - /** UNTRANSLATED */ + title: '新增自訂claim', description: - "Upgrade to a paid plan for custom JWT functionality and premium benefits. Don't hesitate to contact us if you have any questions.", + '升級至付費計劃以解鎖自訂JWT功能和高級福利。如果有任何問題,請隨時聯繹我們。', }, }; From eb8d0f3aa619b98db639fbb1d00e205f87fd3efa Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 23 Apr 2024 13:26:40 +0000 Subject: [PATCH 316/687] chore(deps): update ataylorme/eslint-annotate-action action to v3 (#5756) * chore(deps): update ataylorme/eslint-annotate-action action to v3 * ci: update upload-annotations.yml --------- Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> Co-authored-by: Gao Sun --- .github/workflows/upload-annotations.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/upload-annotations.yml b/.github/workflows/upload-annotations.yml index a7d48c5ce80..c4954111bd5 100644 --- a/.github/workflows/upload-annotations.yml +++ b/.github/workflows/upload-annotations.yml @@ -31,9 +31,9 @@ jobs: run: pnpm -r --parallel lint:report && node .scripts/merge-eslint-reports.js - name: Annotate Code Linting Results - uses: ataylorme/eslint-annotate-action@2.2.0 + uses: ataylorme/eslint-annotate-action@3.0.0 with: - repo-token: ${{ secrets.GITHUB_TOKEN }} + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - name: Upload ESLint report uses: actions/upload-artifact@v4 From ead2abde65ee857e82c38ce8e906aaa96260ff18 Mon Sep 17 00:00:00 2001 From: Charles Zhao Date: Wed, 24 Apr 2024 09:51:56 +0800 Subject: [PATCH 317/687] fix(core): bump oidc-provider to fix resource indicator check (#5782) * fix(core): bump oidc-provider to fix resource indicator check * chore: add changeset --- .changeset/thick-carrots-tickle.md | 7 +++++++ packages/core/package.json | 2 +- pnpm-lock.yaml | 31 +++++++++++++++++++++--------- 3 files changed, 30 insertions(+), 10 deletions(-) create mode 100644 .changeset/thick-carrots-tickle.md diff --git a/.changeset/thick-carrots-tickle.md b/.changeset/thick-carrots-tickle.md new file mode 100644 index 00000000000..a3811d8cfe7 --- /dev/null +++ b/.changeset/thick-carrots-tickle.md @@ -0,0 +1,7 @@ +--- +"@logto/core": patch +--- + +fix a bug that API resource indicator does not work if the indicator is not followed by a trailing slash or a pathname + +- Bump `oidc-provider@8.4.6` to fix the above issue diff --git a/packages/core/package.json b/packages/core/package.json index 377e40a62ce..312040d0b83 100644 --- a/packages/core/package.json +++ b/packages/core/package.json @@ -76,7 +76,7 @@ "ky": "^1.2.3", "lru-cache": "^10.0.0", "nanoid": "^5.0.1", - "oidc-provider": "^8.4.5", + "oidc-provider": "^8.4.6", "openapi-types": "^12.1.3", "otplib": "^12.0.1", "p-retry": "^6.0.0", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index b8fd3bcfc17..d43265d287e 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -3141,8 +3141,8 @@ importers: specifier: ^5.0.1 version: 5.0.1 oidc-provider: - specifier: ^8.4.5 - version: 8.4.5 + specifier: ^8.4.6 + version: 8.4.6 openapi-types: specifier: ^12.1.3 version: 12.1.3 @@ -11368,6 +11368,14 @@ packages: depd: 2.0.0 keygrip: 1.1.0 + /cookies@0.9.1: + resolution: {integrity: sha512-TG2hpqe4ELx54QER/S3HQ9SRVnQnGBtKUz5bLQWtYAQ+o6GpgMs6sYUvaiJjVxb+UXwhRhAEP3m7LbsIZ77Hmw==} + engines: {node: '>= 0.8'} + dependencies: + depd: 2.0.0 + keygrip: 1.1.0 + dev: false + /core-js-compat@3.37.0: resolution: {integrity: sha512-vYq4L+T8aS5UuFg4UwDhc7YNRWVeVZwltad9C/jV3R2LgVOpS9BDr7l/WL6BN0dbV3k1XejPTHqqEzJgsa0frA==} dependencies: @@ -15631,6 +15639,11 @@ packages: /jose@5.2.2: resolution: {integrity: sha512-/WByRr4jDcsKlvMd1dRJnPfS1GVO3WuKyaurJ/vvXcOaUQO8rnNObCQMlv/5uCceVQIq5Q4WLF44ohsdiTohdg==} + dev: true + + /jose@5.2.4: + resolution: {integrity: sha512-6ScbIk2WWCeXkmzF6bRPmEuaqy1m8SbsRFMa/FLrSCkGIhj8OLVG/IH+XHVmNMx/KUo8cVWEE6oKR4dJ+S0Rkg==} + dev: false /js-base64@3.7.5: resolution: {integrity: sha512-3MEt5DTINKqfScXKfJFrRbxkrnk2AxPWGBL/ycjz4dK8iqiSJ06UxD8jh8xuh6p10TX4t2+7FsBYVxxQbMg+qA==} @@ -16001,15 +16014,15 @@ packages: transitivePeerDependencies: - supports-color - /koa@2.14.2: - resolution: {integrity: sha512-VFI2bpJaodz6P7x2uyLiX6RLYpZmOJqNmoCst/Yyd7hQlszyPwG/I9CQJ63nOtKSxpt5M7NH67V6nJL2BwCl7g==} + /koa@2.15.3: + resolution: {integrity: sha512-j/8tY9j5t+GVMLeioLaxweJiKUayFhlGqNTzf2ZGwL0ZCQijd2RLHK0SLW5Tsko8YyyqCZC2cojIb0/s62qTAg==} engines: {node: ^4.8.4 || ^6.10.1 || ^7.10.1 || >= 8.1.4} dependencies: accepts: 1.3.8 cache-content-type: 1.0.1 content-disposition: 0.5.4 content-type: 1.0.5 - cookies: 0.8.0 + cookies: 0.9.1 debug: 4.3.4 delegates: 1.0.0 depd: 2.0.0 @@ -17524,17 +17537,17 @@ packages: /obuf@1.1.2: resolution: {integrity: sha512-PX1wu0AmAdPqOL1mWhqmlOd8kOIZQwGZw6rh7uby9fTc5lhaOWFLX3I6R1hrF9k3zUY40e6igsLGkDXK92LJNg==} - /oidc-provider@8.4.5: - resolution: {integrity: sha512-2NsPrvIAX1W4ZR41cGbz2Lt2Ci8iXvECh+x+LcKcM115s/h8iB1pwnNlCdIrvAA2iBGM4/TkO75Xg7xb2FCzWA==} + /oidc-provider@8.4.6: + resolution: {integrity: sha512-liuHBXRaIjer6nPGWagrl5UjPhIZqahqLVPoYlc2WXsRR7XddwNCBUl1ks5r3Q3uCUfMdQTv1VsjmlaObdff8w==} dependencies: '@koa/cors': 5.0.0 '@koa/router': 12.0.1 debug: 4.3.4 eta: 3.4.0 got: 13.0.0 - jose: 5.2.2 + jose: 5.2.4 jsesc: 3.0.2 - koa: 2.14.2 + koa: 2.15.3 nanoid: 5.0.7 object-hash: 3.0.0 oidc-token-hash: 5.0.3 From 2414e52effe18dda6f5d74086618c5ad59ee7fb9 Mon Sep 17 00:00:00 2001 From: Gao Sun Date: Wed, 24 Apr 2024 10:18:06 +0800 Subject: [PATCH 318/687] chore(deps): upgrade formidable (#5780) --- package.json | 3 +++ pnpm-lock.yaml | 12 +++++++----- 2 files changed, 10 insertions(+), 5 deletions(-) diff --git a/package.json b/package.json index 18dd65f2c13..55ff5b2b3bd 100644 --- a/package.json +++ b/package.json @@ -38,6 +38,9 @@ "pnpm": "^8.10.0" }, "pnpm": { + "overrides": { + "formidable@<3.2.4": "^3.2.4" + }, "peerDependencyRules": { "allowedVersions": { "react": "^18.0.0", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index d43265d287e..43d3d51dbba 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -4,6 +4,9 @@ settings: autoInstallPeers: true excludeLinksFromLockfile: false +overrides: + formidable@<3.2.4: ^3.2.4 + importers: .: @@ -13339,13 +13342,12 @@ packages: engines: {node: '>=0.4.x'} dev: true - /formidable@2.1.2: - resolution: {integrity: sha512-CM3GuJ57US06mlpQ47YcunuUZ9jpm8Vx+P2CGt2j7HpgkKZO/DJYQ0Bobim8G6PFQmK5lOqOOdUXboU+h73A4g==} + /formidable@3.5.1: + resolution: {integrity: sha512-WJWKelbRHN41m5dumb0/k8TeAx7Id/y3a+Z7QfhxP/htI9Js5zYaEDtG8uMgG0vM0lOlqnmjE99/kfpOYi/0Og==} dependencies: dezalgo: 1.0.4 hexoid: 1.0.0 once: 1.4.0 - qs: 6.12.1 /fresh@0.5.2: resolution: {integrity: sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac=} @@ -15901,7 +15903,7 @@ packages: '@types/formidable': 2.0.6 '@types/koa': 2.15.0 co-body: 6.1.0 - formidable: 2.1.2 + formidable: 3.5.1 zod: 3.22.4 dev: false @@ -20332,7 +20334,7 @@ packages: debug: 4.3.4 fast-safe-stringify: 2.1.1 form-data: 4.0.0 - formidable: 2.1.2 + formidable: 3.5.1 methods: 1.1.2 mime: 2.6.0 qs: 6.12.1 From f923a8e0cdcdc7a2d1ddca268d365fcf9979080e Mon Sep 17 00:00:00 2001 From: simeng-li Date: Wed, 24 Apr 2024 10:51:25 +0800 Subject: [PATCH 319/687] feat: add the new dockerize-edge job (#5777) * feat: add the new dockerize-edge-image job add the new dockerize-edge-image job * chore: rename the job rename the job * chore: fix the layout of docker-edge ci job fix the layout of docker-edge ci job --- .github/workflows/release.yml | 52 ++++++++++++++++++++++++++++++++++- 1 file changed, 51 insertions(+), 1 deletion(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index b4f6eb2b88b..1c0ba29b6fc 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -12,7 +12,7 @@ concurrency: jobs: dockerize: if: startsWith(github.ref, 'refs/tags/') - environment: ${{ startsWith(github.ref, 'refs/tags/') && 'release' || '' }} + environment: release runs-on: ubuntu-latest permissions: contents: read @@ -63,6 +63,56 @@ jobs: tags: ${{ steps.meta.outputs.tags }} labels: ${{ steps.meta.outputs.labels }} + # Build and push the edge image on every master push + # Use official docker workflows since we only need to build amd64 images. + dockerize-edge: + if: ${{ !startsWith(github.ref, 'refs/tags/')}} + runs-on: ubuntu-latest + permissions: + contents: read + id-token: write + + steps: + - uses: actions/checkout@v4 + with: + fetch-depth: 0 + + - name: Docker meta + id: meta + uses: docker/metadata-action@v5 + with: + images: | + ghcr.io/logto-io/logto + svhd/logto + tags: | + type=edge + + - name: Login to DockerHub + uses: docker/login-action@v3 + with: + username: ${{ secrets.DOCKERHUB_USERNAME }} + password: ${{ secrets.DOCKERHUB_TOKEN }} + + - name: Login to GitHub Container Registry + uses: docker/login-action@v3 + with: + registry: | + ghcr.io + username: silverhand-bot + password: ${{ secrets.BOT_PAT }} + + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v3 + + - name: Build and push docker image + uses: docker/build-push-action@v5 + with: + platforms: linux/amd64 + context: . + push: true + tags: ${{ steps.meta.outputs.tags }} + labels: ${{ steps.meta.outputs.labels }} + # Publish packages and create git tags if needed publish-and-tag: runs-on: ubuntu-latest From f0a01a73be37242085d09214b0424baa51b96da6 Mon Sep 17 00:00:00 2001 From: Gao Sun Date: Wed, 24 Apr 2024 12:41:34 +0800 Subject: [PATCH 320/687] refactor(core): update `AuthedRouter` -> `ManagementApiRouter` --- packages/core/src/routes/admin-user/basics.ts | 8 +++++--- packages/core/src/routes/admin-user/index.ts | 4 ++-- packages/core/src/routes/admin-user/mfa-verifications.ts | 4 ++-- packages/core/src/routes/admin-user/organization.ts | 4 ++-- packages/core/src/routes/admin-user/role.ts | 4 ++-- packages/core/src/routes/admin-user/search.ts | 4 ++-- packages/core/src/routes/admin-user/social.ts | 4 ++-- .../applications/application-protected-app-metadata.ts | 4 ++-- packages/core/src/routes/applications/application-role.ts | 4 ++-- .../routes/applications/application-sign-in-experience.ts | 4 ++-- .../applications/application-user-consent-organization.ts | 4 ++-- .../routes/applications/application-user-consent-scope.ts | 4 ++-- packages/core/src/routes/applications/application.ts | 4 ++-- packages/core/src/routes/connector/authorization-uri.ts | 4 ++-- packages/core/src/routes/connector/config-testing.ts | 4 ++-- packages/core/src/routes/connector/factory.ts | 4 ++-- packages/core/src/routes/connector/index.ts | 4 ++-- packages/core/src/routes/custom-phrase.ts | 4 ++-- packages/core/src/routes/dashboard.ts | 4 ++-- packages/core/src/routes/domain.ts | 4 ++-- packages/core/src/routes/hook.ts | 4 ++-- packages/core/src/routes/init.ts | 4 ++-- packages/core/src/routes/log.ts | 4 ++-- packages/core/src/routes/logto-config/index.ts | 4 ++-- packages/core/src/routes/logto-config/jwt-customizer.ts | 4 ++-- packages/core/src/routes/organization/index.ts | 6 ++++-- packages/core/src/routes/organization/invitations.ts | 4 ++-- packages/core/src/routes/organization/roles.ts | 4 ++-- packages/core/src/routes/organization/scopes.ts | 4 ++-- packages/core/src/routes/resource.scope.ts | 4 ++-- packages/core/src/routes/resource.ts | 4 ++-- packages/core/src/routes/role.application.ts | 4 ++-- packages/core/src/routes/role.scope.ts | 4 ++-- packages/core/src/routes/role.ts | 6 ++++-- packages/core/src/routes/role.user.ts | 4 ++-- packages/core/src/routes/sign-in-experience/index.ts | 4 ++-- packages/core/src/routes/sso-connector/index.ts | 4 ++-- packages/core/src/routes/system.ts | 4 ++-- packages/core/src/routes/types.ts | 7 +++++-- packages/core/src/routes/user-assets.ts | 6 ++++-- packages/core/src/routes/verification-code.ts | 4 ++-- packages/core/src/utils/test-utils.ts | 8 ++++---- 42 files changed, 98 insertions(+), 87 deletions(-) diff --git a/packages/core/src/routes/admin-user/basics.ts b/packages/core/src/routes/admin-user/basics.ts index 9ab6624e74c..7c7065a28f9 100644 --- a/packages/core/src/routes/admin-user/basics.ts +++ b/packages/core/src/routes/admin-user/basics.ts @@ -14,9 +14,11 @@ import { encryptUserPassword } from '#src/libraries/user.js'; import koaGuard from '#src/middleware/koa-guard.js'; import assertThat from '#src/utils/assert-that.js'; -import type { AuthedRouter, RouterInitArgs } from '../types.js'; +import type { ManagementApiRouter, RouterInitArgs } from '../types.js'; -export default function adminUserBasicsRoutes(...args: RouterInitArgs) { +export default function adminUserBasicsRoutes( + ...args: RouterInitArgs +) { const [router, { queries, libraries }] = args; const { oidcModelInstances: { revokeInstanceByUserId }, @@ -346,9 +348,9 @@ export default function adminUserBasicsRoutes(...args: R ctx.body = pick(user, ...userInfoSelectFields); + // eslint-disable-next-line max-lines return next(); } - // eslint-disable-next-line max-lines ); router.delete( diff --git a/packages/core/src/routes/admin-user/index.ts b/packages/core/src/routes/admin-user/index.ts index 0fb50f6c643..2f57e089d53 100644 --- a/packages/core/src/routes/admin-user/index.ts +++ b/packages/core/src/routes/admin-user/index.ts @@ -1,4 +1,4 @@ -import type { AuthedRouter, RouterInitArgs } from '../types.js'; +import type { ManagementApiRouter, RouterInitArgs } from '../types.js'; import adminUserBasicsRoutes from './basics.js'; import adminUserMfaVerificationsRoutes from './mfa-verifications.js'; @@ -7,7 +7,7 @@ import adminUserRoleRoutes from './role.js'; import adminUserSearchRoutes from './search.js'; import adminUserSocialRoutes from './social.js'; -export default function adminUserRoutes(...args: RouterInitArgs) { +export default function adminUserRoutes(...args: RouterInitArgs) { adminUserBasicsRoutes(...args); adminUserRoleRoutes(...args); adminUserSearchRoutes(...args); diff --git a/packages/core/src/routes/admin-user/mfa-verifications.ts b/packages/core/src/routes/admin-user/mfa-verifications.ts index ffc2d4f631e..bbcd5e0af45 100644 --- a/packages/core/src/routes/admin-user/mfa-verifications.ts +++ b/packages/core/src/routes/admin-user/mfa-verifications.ts @@ -11,9 +11,9 @@ import { transpileUserMfaVerifications } from '#src/utils/user.js'; import { generateBackupCodes } from '../interaction/utils/backup-code-validation.js'; import { generateTotpSecret } from '../interaction/utils/totp-validation.js'; -import type { AuthedRouter, RouterInitArgs } from '../types.js'; +import type { ManagementApiRouter, RouterInitArgs } from '../types.js'; -export default function adminUserMfaVerificationsRoutes( +export default function adminUserMfaVerificationsRoutes( ...args: RouterInitArgs ) { const [ diff --git a/packages/core/src/routes/admin-user/organization.ts b/packages/core/src/routes/admin-user/organization.ts index aaa2298a2d4..1afcc9c640c 100644 --- a/packages/core/src/routes/admin-user/organization.ts +++ b/packages/core/src/routes/admin-user/organization.ts @@ -3,9 +3,9 @@ import { z } from 'zod'; import koaGuard from '#src/middleware/koa-guard.js'; -import { type AuthedRouter, type RouterInitArgs } from '../types.js'; +import { type ManagementApiRouter, type RouterInitArgs } from '../types.js'; -export default function adminUserOrganizationRoutes( +export default function adminUserOrganizationRoutes( ...[router, { queries }]: RouterInitArgs ) { router.get( diff --git a/packages/core/src/routes/admin-user/role.ts b/packages/core/src/routes/admin-user/role.ts index e54a3cce887..dd5d0d1b2be 100644 --- a/packages/core/src/routes/admin-user/role.ts +++ b/packages/core/src/routes/admin-user/role.ts @@ -10,9 +10,9 @@ import koaRoleRlsErrorHandler from '#src/middleware/koa-role-rls-error-handler.j import assertThat from '#src/utils/assert-that.js'; import { parseSearchParamsForSearch } from '#src/utils/search.js'; -import type { AuthedRouter, RouterInitArgs } from '../types.js'; +import type { ManagementApiRouter, RouterInitArgs } from '../types.js'; -export default function adminUserRoleRoutes( +export default function adminUserRoleRoutes( ...[router, { queries }]: RouterInitArgs ) { const { diff --git a/packages/core/src/routes/admin-user/search.ts b/packages/core/src/routes/admin-user/search.ts index 92d995c9325..a00894212a7 100644 --- a/packages/core/src/routes/admin-user/search.ts +++ b/packages/core/src/routes/admin-user/search.ts @@ -12,7 +12,7 @@ import koaPagination from '#src/middleware/koa-pagination.js'; import { type UserConditions } from '#src/queries/user.js'; import { parseSearchParamsForSearch } from '#src/utils/search.js'; -import type { AuthedRouter, RouterInitArgs } from '../types.js'; +import type { ManagementApiRouter, RouterInitArgs } from '../types.js'; const getQueryRelation = ( excludeRoleId: Nullable, @@ -39,7 +39,7 @@ const getQueryRelation = ( return undefined; }; -export default function adminUserSearchRoutes( +export default function adminUserSearchRoutes( ...[router, { queries }]: RouterInitArgs ) { const { diff --git a/packages/core/src/routes/admin-user/social.ts b/packages/core/src/routes/admin-user/social.ts index 1302f9976ee..888d0513052 100644 --- a/packages/core/src/routes/admin-user/social.ts +++ b/packages/core/src/routes/admin-user/social.ts @@ -13,9 +13,9 @@ import RequestError from '#src/errors/RequestError/index.js'; import koaGuard from '#src/middleware/koa-guard.js'; import assertThat from '#src/utils/assert-that.js'; -import type { AuthedRouter, RouterInitArgs } from '../types.js'; +import type { ManagementApiRouter, RouterInitArgs } from '../types.js'; -export default function adminUserSocialRoutes( +export default function adminUserSocialRoutes( ...[router, tenant]: RouterInitArgs ) { const { diff --git a/packages/core/src/routes/applications/application-protected-app-metadata.ts b/packages/core/src/routes/applications/application-protected-app-metadata.ts index c0e72e82477..9dc84894c00 100644 --- a/packages/core/src/routes/applications/application-protected-app-metadata.ts +++ b/packages/core/src/routes/applications/application-protected-app-metadata.ts @@ -6,9 +6,9 @@ import RequestError from '#src/errors/RequestError/index.js'; import koaGuard from '#src/middleware/koa-guard.js'; import assertThat from '#src/utils/assert-that.js'; -import { type AuthedRouter, type RouterInitArgs } from '../types.js'; +import { type ManagementApiRouter, type RouterInitArgs } from '../types.js'; -export default function applicationProtectedAppMetadataRoutes( +export default function applicationProtectedAppMetadataRoutes( ...[ router, { diff --git a/packages/core/src/routes/applications/application-role.ts b/packages/core/src/routes/applications/application-role.ts index 45b31edb1ba..fc6198456c1 100644 --- a/packages/core/src/routes/applications/application-role.ts +++ b/packages/core/src/routes/applications/application-role.ts @@ -10,9 +10,9 @@ import koaRoleRlsErrorHandler from '#src/middleware/koa-role-rls-error-handler.j import assertThat from '#src/utils/assert-that.js'; import { parseSearchParamsForSearch } from '#src/utils/search.js'; -import type { AuthedRouter, RouterInitArgs } from '../types.js'; +import type { ManagementApiRouter, RouterInitArgs } from '../types.js'; -export default function applicationRoleRoutes( +export default function applicationRoleRoutes( ...[router, { queries }]: RouterInitArgs ) { const { diff --git a/packages/core/src/routes/applications/application-sign-in-experience.ts b/packages/core/src/routes/applications/application-sign-in-experience.ts index 7835ccb2666..b5c8db0dbd9 100644 --- a/packages/core/src/routes/applications/application-sign-in-experience.ts +++ b/packages/core/src/routes/applications/application-sign-in-experience.ts @@ -7,9 +7,9 @@ import { object, string } from 'zod'; import RequestError from '#src/errors/RequestError/index.js'; import koaGuard from '#src/middleware/koa-guard.js'; -import type { AuthedRouter, RouterInitArgs } from '../types.js'; +import type { ManagementApiRouter, RouterInitArgs } from '../types.js'; -function applicationSignInExperienceRoutes( +function applicationSignInExperienceRoutes( ...[ router, { diff --git a/packages/core/src/routes/applications/application-user-consent-organization.ts b/packages/core/src/routes/applications/application-user-consent-organization.ts index 114eebf3e1a..67fc3df4222 100644 --- a/packages/core/src/routes/applications/application-user-consent-organization.ts +++ b/packages/core/src/routes/applications/application-user-consent-organization.ts @@ -4,9 +4,9 @@ import { z } from 'zod'; import koaGuard from '#src/middleware/koa-guard.js'; import koaPagination from '#src/middleware/koa-pagination.js'; -import { type AuthedRouter, type RouterInitArgs } from '../types.js'; +import { type ManagementApiRouter, type RouterInitArgs } from '../types.js'; -export default function applicationUserConsentOrganizationRoutes( +export default function applicationUserConsentOrganizationRoutes( ...[ router, { diff --git a/packages/core/src/routes/applications/application-user-consent-scope.ts b/packages/core/src/routes/applications/application-user-consent-scope.ts index 0b685401b9e..cbb11a89ac7 100644 --- a/packages/core/src/routes/applications/application-user-consent-scope.ts +++ b/packages/core/src/routes/applications/application-user-consent-scope.ts @@ -7,9 +7,9 @@ import { object, string, nativeEnum } from 'zod'; import koaGuard from '#src/middleware/koa-guard.js'; -import type { AuthedRouter, RouterInitArgs } from '../types.js'; +import type { ManagementApiRouter, RouterInitArgs } from '../types.js'; -export default function applicationUserConsentScopeRoutes( +export default function applicationUserConsentScopeRoutes( ...[ router, { diff --git a/packages/core/src/routes/applications/application.ts b/packages/core/src/routes/applications/application.ts index e218f82fc20..73b693b5f54 100644 --- a/packages/core/src/routes/applications/application.ts +++ b/packages/core/src/routes/applications/application.ts @@ -17,7 +17,7 @@ import { buildOidcClientMetadata } from '#src/oidc/utils.js'; import assertThat from '#src/utils/assert-that.js'; import { parseSearchParamsForSearch } from '#src/utils/search.js'; -import type { AuthedRouter, RouterInitArgs } from '../types.js'; +import type { ManagementApiRouter, RouterInitArgs } from '../types.js'; import { applicationCreateGuard, applicationPatchGuard } from './types.js'; @@ -34,7 +34,7 @@ const parseIsThirdPartQueryParam = (isThirdPartyQuery: 'true' | 'false' | undefi const applicationTypeGuard = z.nativeEnum(ApplicationType); -export default function applicationRoutes( +export default function applicationRoutes( ...[ router, { diff --git a/packages/core/src/routes/connector/authorization-uri.ts b/packages/core/src/routes/connector/authorization-uri.ts index 420ddc0bc0d..6722b237961 100644 --- a/packages/core/src/routes/connector/authorization-uri.ts +++ b/packages/core/src/routes/connector/authorization-uri.ts @@ -5,9 +5,9 @@ import { object, string } from 'zod'; import koaGuard from '#src/middleware/koa-guard.js'; import assertThat from '#src/utils/assert-that.js'; -import { type AuthedRouter, type RouterInitArgs } from '../types.js'; +import { type ManagementApiRouter, type RouterInitArgs } from '../types.js'; -export default function connectorAuthorizationUriRoutes( +export default function connectorAuthorizationUriRoutes( ...[router, tenant]: RouterInitArgs ) { const { getLogtoConnectorById } = tenant.connectors; diff --git a/packages/core/src/routes/connector/config-testing.ts b/packages/core/src/routes/connector/config-testing.ts index 6e18bdac65f..60eea26979a 100644 --- a/packages/core/src/routes/connector/config-testing.ts +++ b/packages/core/src/routes/connector/config-testing.ts @@ -18,9 +18,9 @@ import koaGuard from '#src/middleware/koa-guard.js'; import assertThat from '#src/utils/assert-that.js'; import { loadConnectorFactories } from '#src/utils/connectors/index.js'; -import type { AuthedRouter, RouterInitArgs } from '../types.js'; +import type { ManagementApiRouter, RouterInitArgs } from '../types.js'; -export default function connectorConfigTestingRoutes( +export default function connectorConfigTestingRoutes( ...[router, { cloudConnection }]: RouterInitArgs ) { const { getClient } = cloudConnection; diff --git a/packages/core/src/routes/connector/factory.ts b/packages/core/src/routes/connector/factory.ts index cf6b8a8f507..652d8f22cc5 100644 --- a/packages/core/src/routes/connector/factory.ts +++ b/packages/core/src/routes/connector/factory.ts @@ -6,9 +6,9 @@ import koaGuard from '#src/middleware/koa-guard.js'; import assertThat from '#src/utils/assert-that.js'; import { loadConnectorFactories, transpileConnectorFactory } from '#src/utils/connectors/index.js'; -import type { AuthedRouter, RouterInitArgs } from '../types.js'; +import type { ManagementApiRouter, RouterInitArgs } from '../types.js'; -export default function connectorFactoryRoutes( +export default function connectorFactoryRoutes( ...[router]: RouterInitArgs ) { router.get( diff --git a/packages/core/src/routes/connector/index.ts b/packages/core/src/routes/connector/index.ts index aeba0f5d3ee..2cb3c9a688b 100644 --- a/packages/core/src/routes/connector/index.ts +++ b/packages/core/src/routes/connector/index.ts @@ -15,7 +15,7 @@ import { buildExtraInfo } from '#src/utils/connectors/extra-information.js'; import { loadConnectorFactories, transpileLogtoConnector } from '#src/utils/connectors/index.js'; import { checkSocialConnectorTargetAndPlatformUniqueness } from '#src/utils/connectors/platform.js'; -import type { AuthedRouter, RouterInitArgs } from '../types.js'; +import type { ManagementApiRouter, RouterInitArgs } from '../types.js'; import connectorAuthorizationUriRoutes from './authorization-uri.js'; import connectorConfigTestingRoutes from './config-testing.js'; @@ -32,7 +32,7 @@ const guardConnectorsQuota = async ( const passwordlessConnector = new Set([ConnectorType.Email, ConnectorType.Sms]); -export default function connectorRoutes( +export default function connectorRoutes( ...[router, tenant]: RouterInitArgs ) { const { diff --git a/packages/core/src/routes/custom-phrase.ts b/packages/core/src/routes/custom-phrase.ts index 04911336be3..bd2082952d6 100644 --- a/packages/core/src/routes/custom-phrase.ts +++ b/packages/core/src/routes/custom-phrase.ts @@ -10,14 +10,14 @@ import koaGuard from '#src/middleware/koa-guard.js'; import assertThat from '#src/utils/assert-that.js'; import { isStrictlyPartial } from '#src/utils/translation.js'; -import type { AuthedRouter, RouterInitArgs } from './types.js'; +import type { ManagementApiRouter, RouterInitArgs } from './types.js'; const cleanDeepTranslation = (translation: Translation) => // Since `Translation` type actually equals `Partial`, force to cast it back to `Translation`. // eslint-disable-next-line no-restricted-syntax cleanDeep(translation) as Translation; -export default function customPhraseRoutes( +export default function customPhraseRoutes( ...[router, { queries }]: RouterInitArgs ) { const { diff --git a/packages/core/src/routes/dashboard.ts b/packages/core/src/routes/dashboard.ts index f5f7b7deb3b..db97891b3a0 100644 --- a/packages/core/src/routes/dashboard.ts +++ b/packages/core/src/routes/dashboard.ts @@ -5,7 +5,7 @@ import { number, object, string } from 'zod'; import koaGuard from '#src/middleware/koa-guard.js'; -import type { AuthedRouter, RouterInitArgs } from './types.js'; +import type { ManagementApiRouter, RouterInitArgs } from './types.js'; const getDateString = (date: Date | number) => format(date, 'yyyy-MM-dd'); @@ -13,7 +13,7 @@ const indices = (length: number) => [...Array.from({ length }).keys()]; const getEndOfDayTimestamp = (date: Date | number) => endOfDay(date).valueOf(); -export default function dashboardRoutes( +export default function dashboardRoutes( ...[router, { queries }]: RouterInitArgs ) { const { diff --git a/packages/core/src/routes/domain.ts b/packages/core/src/routes/domain.ts index 475920c2d54..6a394d3af72 100644 --- a/packages/core/src/routes/domain.ts +++ b/packages/core/src/routes/domain.ts @@ -7,9 +7,9 @@ import koaGuard from '#src/middleware/koa-guard.js'; import koaQuotaGuard from '#src/middleware/koa-quota-guard.js'; import assertThat from '#src/utils/assert-that.js'; -import type { AuthedRouter, RouterInitArgs } from './types.js'; +import type { ManagementApiRouter, RouterInitArgs } from './types.js'; -export default function domainRoutes( +export default function domainRoutes( ...[router, { queries, libraries }]: RouterInitArgs ) { const { diff --git a/packages/core/src/routes/hook.ts b/packages/core/src/routes/hook.ts index 8ae802138fc..8e87c162123 100644 --- a/packages/core/src/routes/hook.ts +++ b/packages/core/src/routes/hook.ts @@ -20,13 +20,13 @@ import koaQuotaGuard from '#src/middleware/koa-quota-guard.js'; import { type AllowedKeyPrefix } from '#src/queries/log.js'; import assertThat from '#src/utils/assert-that.js'; -import type { AuthedRouter, RouterInitArgs } from './types.js'; +import type { ManagementApiRouter, RouterInitArgs } from './types.js'; const nonemptyUniqueHookEventsGuard = hookEventsGuard .nonempty() .transform((events) => deduplicate(events)); -export default function hookRoutes( +export default function hookRoutes( ...[router, { queries, libraries }]: RouterInitArgs ) { const { diff --git a/packages/core/src/routes/init.ts b/packages/core/src/routes/init.ts index a33c483159c..0ab14e1e9ff 100644 --- a/packages/core/src/routes/init.ts +++ b/packages/core/src/routes/init.ts @@ -36,7 +36,7 @@ import ssoConnectors from './sso-connector/index.js'; import statusRoutes from './status.js'; import swaggerRoutes from './swagger/index.js'; import systemRoutes from './system.js'; -import type { AnonymousRouter, AuthedRouter } from './types.js'; +import type { AnonymousRouter, ManagementApiRouter } from './types.js'; import userAssetsRoutes from './user-assets.js'; import verificationCodeRoutes from './verification-code.js'; import wellKnownRoutes from './well-known.js'; @@ -45,7 +45,7 @@ const createRouters = (tenant: TenantContext) => { const interactionRouter: AnonymousRouter = new Router(); interactionRoutes(interactionRouter, tenant); - const managementRouter: AuthedRouter = new Router(); + const managementRouter: ManagementApiRouter = new Router(); managementRouter.use(koaAuth(tenant.envSet, getManagementApiResourceIndicator(tenant.id))); managementRouter.use(koaTenantGuard(tenant.id, tenant.queries)); diff --git a/packages/core/src/routes/log.ts b/packages/core/src/routes/log.ts index 99902032b86..0d53f121183 100644 --- a/packages/core/src/routes/log.ts +++ b/packages/core/src/routes/log.ts @@ -5,9 +5,9 @@ import koaGuard from '#src/middleware/koa-guard.js'; import koaPagination from '#src/middleware/koa-pagination.js'; import { type AllowedKeyPrefix } from '#src/queries/log.js'; -import type { AuthedRouter, RouterInitArgs } from './types.js'; +import type { ManagementApiRouter, RouterInitArgs } from './types.js'; -export default function logRoutes( +export default function logRoutes( ...[router, { queries }]: RouterInitArgs ) { const { findLogById, countLogs, findLogs } = queries.logs; diff --git a/packages/core/src/routes/logto-config/index.ts b/packages/core/src/routes/logto-config/index.ts index 0b9e424d231..b7dabb4934b 100644 --- a/packages/core/src/routes/logto-config/index.ts +++ b/packages/core/src/routes/logto-config/index.ts @@ -19,7 +19,7 @@ import RequestError from '#src/errors/RequestError/index.js'; import koaGuard from '#src/middleware/koa-guard.js'; import { exportJWK } from '#src/utils/jwks.js'; -import type { AuthedRouter, RouterInitArgs } from '../types.js'; +import type { ManagementApiRouter, RouterInitArgs } from '../types.js'; import logtoConfigJwtCustomizerRoutes from './jwt-customizer.js'; @@ -59,7 +59,7 @@ const getRedactedOidcKeyResponse = async ( }) ); -export default function logtoConfigRoutes( +export default function logtoConfigRoutes( ...[router, tenant]: RouterInitArgs ) { const { getAdminConsoleConfig, updateAdminConsoleConfig, updateOidcConfigsByKey } = diff --git a/packages/core/src/routes/logto-config/jwt-customizer.ts b/packages/core/src/routes/logto-config/jwt-customizer.ts index da629a241ff..0ded9ceef73 100644 --- a/packages/core/src/routes/logto-config/jwt-customizer.ts +++ b/packages/core/src/routes/logto-config/jwt-customizer.ts @@ -16,7 +16,7 @@ import RequestError, { formatZodError } from '#src/errors/RequestError/index.js' import koaGuard, { parse } from '#src/middleware/koa-guard.js'; import koaQuotaGuard from '#src/middleware/koa-quota-guard.js'; -import type { AuthedRouter, RouterInitArgs } from '../types.js'; +import type { ManagementApiRouter, RouterInitArgs } from '../types.js'; const getJwtTokenKeyAndBody = (tokenPath: LogtoJwtTokenKeyType, body: unknown) => { if (tokenPath === LogtoJwtTokenKeyType.AccessToken) { @@ -31,7 +31,7 @@ const getJwtTokenKeyAndBody = (tokenPath: LogtoJwtTokenKeyType, body: unknown) = }; }; -export default function logtoConfigJwtCustomizerRoutes( +export default function logtoConfigJwtCustomizerRoutes( ...[ router, { id: tenantId, queries, logtoConfigs, cloudConnection, libraries }, diff --git a/packages/core/src/routes/organization/index.ts b/packages/core/src/routes/organization/index.ts index 54fb04faf23..3d798b6e87c 100644 --- a/packages/core/src/routes/organization/index.ts +++ b/packages/core/src/routes/organization/index.ts @@ -17,14 +17,16 @@ import { userSearchKeys } from '#src/queries/user.js'; import SchemaRouter from '#src/utils/SchemaRouter.js'; import { parseSearchOptions } from '#src/utils/search.js'; -import { type AuthedRouter, type RouterInitArgs } from '../types.js'; +import { type ManagementApiRouter, type RouterInitArgs } from '../types.js'; import organizationInvitationRoutes from './invitations.js'; import organizationRoleRoutes from './roles.js'; import organizationScopeRoutes from './scopes.js'; import { errorHandler } from './utils.js'; -export default function organizationRoutes(...args: RouterInitArgs) { +export default function organizationRoutes( + ...args: RouterInitArgs +) { const [ originalRouter, { diff --git a/packages/core/src/routes/organization/invitations.ts b/packages/core/src/routes/organization/invitations.ts index 4136532b053..c7e886503ae 100644 --- a/packages/core/src/routes/organization/invitations.ts +++ b/packages/core/src/routes/organization/invitations.ts @@ -11,11 +11,11 @@ import koaGuard from '#src/middleware/koa-guard.js'; import SchemaRouter from '#src/utils/SchemaRouter.js'; import assertThat from '#src/utils/assert-that.js'; -import { type AuthedRouter, type RouterInitArgs } from '../types.js'; +import { type ManagementApiRouter, type RouterInitArgs } from '../types.js'; import { errorHandler } from './utils.js'; -export default function organizationInvitationRoutes( +export default function organizationInvitationRoutes( ...[ originalRouter, { diff --git a/packages/core/src/routes/organization/roles.ts b/packages/core/src/routes/organization/roles.ts index 48a85ad3b9c..39b90e59207 100644 --- a/packages/core/src/routes/organization/roles.ts +++ b/packages/core/src/routes/organization/roles.ts @@ -15,11 +15,11 @@ import { organizationRoleSearchKeys } from '#src/queries/organization/index.js'; import SchemaRouter from '#src/utils/SchemaRouter.js'; import { parseSearchOptions } from '#src/utils/search.js'; -import { type AuthedRouter, type RouterInitArgs } from '../types.js'; +import { type ManagementApiRouter, type RouterInitArgs } from '../types.js'; import { errorHandler } from './utils.js'; -export default function organizationRoleRoutes( +export default function organizationRoleRoutes( ...[ originalRouter, { diff --git a/packages/core/src/routes/organization/scopes.ts b/packages/core/src/routes/organization/scopes.ts index 3cab9b2fd7b..39f635fe357 100644 --- a/packages/core/src/routes/organization/scopes.ts +++ b/packages/core/src/routes/organization/scopes.ts @@ -3,11 +3,11 @@ import { OrganizationScopes } from '@logto/schemas'; import koaQuotaGuard from '#src/middleware/koa-quota-guard.js'; import SchemaRouter from '#src/utils/SchemaRouter.js'; -import { type AuthedRouter, type RouterInitArgs } from '../types.js'; +import { type ManagementApiRouter, type RouterInitArgs } from '../types.js'; import { errorHandler } from './utils.js'; -export default function organizationScopeRoutes( +export default function organizationScopeRoutes( ...[ originalRouter, { diff --git a/packages/core/src/routes/resource.scope.ts b/packages/core/src/routes/resource.scope.ts index 3628c6a7e04..f3905bdbbcb 100644 --- a/packages/core/src/routes/resource.scope.ts +++ b/packages/core/src/routes/resource.scope.ts @@ -9,9 +9,9 @@ import koaPagination from '#src/middleware/koa-pagination.js'; import assertThat from '#src/utils/assert-that.js'; import { parseSearchParamsForSearch } from '#src/utils/search.js'; -import type { AuthedRouter, RouterInitArgs } from './types.js'; +import type { ManagementApiRouter, RouterInitArgs } from './types.js'; -export default function resourceScopeRoutes( +export default function resourceScopeRoutes( ...[ router, { diff --git a/packages/core/src/routes/resource.ts b/packages/core/src/routes/resource.ts index 7e4947cbf89..6d2bd88ca30 100644 --- a/packages/core/src/routes/resource.ts +++ b/packages/core/src/routes/resource.ts @@ -10,9 +10,9 @@ import koaQuotaGuard from '#src/middleware/koa-quota-guard.js'; import assertThat from '#src/utils/assert-that.js'; import { attachScopesToResources } from '#src/utils/resource.js'; -import type { AuthedRouter, RouterInitArgs } from './types.js'; +import type { ManagementApiRouter, RouterInitArgs } from './types.js'; -export default function resourceRoutes( +export default function resourceRoutes( ...[ router, { diff --git a/packages/core/src/routes/role.application.ts b/packages/core/src/routes/role.application.ts index 7e78b08d702..48864ffed9b 100644 --- a/packages/core/src/routes/role.application.ts +++ b/packages/core/src/routes/role.application.ts @@ -8,9 +8,9 @@ import koaGuard from '#src/middleware/koa-guard.js'; import koaPagination from '#src/middleware/koa-pagination.js'; import { parseSearchParamsForSearch } from '#src/utils/search.js'; -import type { AuthedRouter, RouterInitArgs } from './types.js'; +import type { ManagementApiRouter, RouterInitArgs } from './types.js'; -export default function roleApplicationRoutes( +export default function roleApplicationRoutes( ...[router, { queries }]: RouterInitArgs ) { const { diff --git a/packages/core/src/routes/role.scope.ts b/packages/core/src/routes/role.scope.ts index 61b731cb65d..b768f086c8b 100644 --- a/packages/core/src/routes/role.scope.ts +++ b/packages/core/src/routes/role.scope.ts @@ -8,9 +8,9 @@ import koaGuard from '#src/middleware/koa-guard.js'; import koaPagination from '#src/middleware/koa-pagination.js'; import { parseSearchParamsForSearch } from '#src/utils/search.js'; -import type { AuthedRouter, RouterInitArgs } from './types.js'; +import type { ManagementApiRouter, RouterInitArgs } from './types.js'; -export default function roleScopeRoutes( +export default function roleScopeRoutes( ...[router, { queries, libraries }]: RouterInitArgs ) { const { diff --git a/packages/core/src/routes/role.ts b/packages/core/src/routes/role.ts index a837e903be5..1cbcfdf8e05 100644 --- a/packages/core/src/routes/role.ts +++ b/packages/core/src/routes/role.ts @@ -13,9 +13,11 @@ import { parseSearchParamsForSearch } from '#src/utils/search.js'; import roleApplicationRoutes from './role.application.js'; import roleUserRoutes from './role.user.js'; -import type { AuthedRouter, RouterInitArgs } from './types.js'; +import type { ManagementApiRouter, RouterInitArgs } from './types.js'; -export default function roleRoutes(...[router, tenant]: RouterInitArgs) { +export default function roleRoutes( + ...[router, tenant]: RouterInitArgs +) { const { queries, libraries } = tenant; const { rolesScopes: { insertRolesScopes }, diff --git a/packages/core/src/routes/role.user.ts b/packages/core/src/routes/role.user.ts index c62baa94a47..2e7c5f6f98b 100644 --- a/packages/core/src/routes/role.user.ts +++ b/packages/core/src/routes/role.user.ts @@ -9,9 +9,9 @@ import koaPagination from '#src/middleware/koa-pagination.js'; import { type UserConditions } from '#src/queries/user.js'; import { parseSearchParamsForSearch } from '#src/utils/search.js'; -import type { AuthedRouter, RouterInitArgs } from './types.js'; +import type { ManagementApiRouter, RouterInitArgs } from './types.js'; -export default function roleUserRoutes( +export default function roleUserRoutes( ...[router, { queries }]: RouterInitArgs ) { const { diff --git a/packages/core/src/routes/sign-in-experience/index.ts b/packages/core/src/routes/sign-in-experience/index.ts index d328479fdcb..3ccc2ceefbb 100644 --- a/packages/core/src/routes/sign-in-experience/index.ts +++ b/packages/core/src/routes/sign-in-experience/index.ts @@ -6,9 +6,9 @@ import { validateSignUp, validateSignIn } from '#src/libraries/sign-in-experienc import { validateMfa } from '#src/libraries/sign-in-experience/mfa.js'; import koaGuard from '#src/middleware/koa-guard.js'; -import type { AuthedRouter, RouterInitArgs } from '../types.js'; +import type { ManagementApiRouter, RouterInitArgs } from '../types.js'; -export default function signInExperiencesRoutes( +export default function signInExperiencesRoutes( ...[router, { queries, libraries, connectors }]: RouterInitArgs ) { const { findDefaultSignInExperience, updateDefaultSignInExperience } = queries.signInExperiences; diff --git a/packages/core/src/routes/sso-connector/index.ts b/packages/core/src/routes/sso-connector/index.ts index e250e35ded8..e3bd55dac56 100644 --- a/packages/core/src/routes/sso-connector/index.ts +++ b/packages/core/src/routes/sso-connector/index.ts @@ -17,7 +17,7 @@ import { isSupportedSsoProvider, isSupportedSsoConnector } from '#src/sso/utils. import { tableToPathname } from '#src/utils/SchemaRouter.js'; import assertThat from '#src/utils/assert-that.js'; -import { type AuthedRouter, type RouterInitArgs } from '../types.js'; +import { type ManagementApiRouter, type RouterInitArgs } from '../types.js'; import { parseFactoryDetail, @@ -27,7 +27,7 @@ import { validateConnectorConfigConnectionStatus, } from './utils.js'; -export default function singleSignOnConnectorsRoutes( +export default function singleSignOnConnectorsRoutes( ...args: RouterInitArgs ) { const [ diff --git a/packages/core/src/routes/system.ts b/packages/core/src/routes/system.ts index 250c279c105..ea0d7884e9d 100644 --- a/packages/core/src/routes/system.ts +++ b/packages/core/src/routes/system.ts @@ -2,9 +2,9 @@ import { object, string } from 'zod'; import koaGuard from '#src/middleware/koa-guard.js'; -import type { AuthedRouter, RouterInitArgs } from './types.js'; +import type { ManagementApiRouter, RouterInitArgs } from './types.js'; -export default function systemRoutes( +export default function systemRoutes( ...[ router, { diff --git a/packages/core/src/routes/types.ts b/packages/core/src/routes/types.ts index 0550f4f993d..2eb5bcb5a84 100644 --- a/packages/core/src/routes/types.ts +++ b/packages/core/src/routes/types.ts @@ -8,9 +8,12 @@ import type TenantContext from '#src/tenants/TenantContext.js'; export type AnonymousRouter = Router; -type AuthedRouterContext = WithAuthContext & WithLogContext & WithI18nContext & ExtendableContext; +type ManagementApiRouterContext = WithAuthContext & + WithLogContext & + WithI18nContext & + ExtendableContext; -export type AuthedRouter = Router; +export type ManagementApiRouter = Router; type RouterInit = (router: T, tenant: TenantContext) => void; export type RouterInitArgs = Parameters>; diff --git a/packages/core/src/routes/user-assets.ts b/packages/core/src/routes/user-assets.ts index fa52bde44e1..9eb0c054597 100644 --- a/packages/core/src/routes/user-assets.ts +++ b/packages/core/src/routes/user-assets.ts @@ -20,9 +20,11 @@ import { uploadFileGuard } from '#src/utils/storage/consts.js'; import { buildUploadFile } from '#src/utils/storage/index.js'; import { getTenantId } from '#src/utils/tenant.js'; -import type { AuthedRouter, RouterInitArgs } from './types.js'; +import type { ManagementApiRouter, RouterInitArgs } from './types.js'; -export default function userAssetsRoutes(...[router]: RouterInitArgs) { +export default function userAssetsRoutes( + ...[router]: RouterInitArgs +) { router.get( '/user-assets/service-status', koaGuard({ diff --git a/packages/core/src/routes/verification-code.ts b/packages/core/src/routes/verification-code.ts index 687ef41950b..d71ea6a249c 100644 --- a/packages/core/src/routes/verification-code.ts +++ b/packages/core/src/routes/verification-code.ts @@ -6,11 +6,11 @@ import { import koaGuard from '#src/middleware/koa-guard.js'; -import type { AuthedRouter, RouterInitArgs } from './types.js'; +import type { ManagementApiRouter, RouterInitArgs } from './types.js'; const codeType = TemplateType.Generic; -export default function verificationCodeRoutes( +export default function verificationCodeRoutes( ...[router, { libraries }]: RouterInitArgs ) { const { diff --git a/packages/core/src/utils/test-utils.ts b/packages/core/src/utils/test-utils.ts index eee58a63b93..fa98c5e481e 100644 --- a/packages/core/src/utils/test-utils.ts +++ b/packages/core/src/utils/test-utils.ts @@ -10,7 +10,7 @@ import type { IRouterParamContext } from 'koa-router'; import Router from 'koa-router'; import request from 'supertest'; -import type { AuthedRouter, AnonymousRouter } from '#src/routes/types.js'; +import type { ManagementApiRouter, AnonymousRouter } from '#src/routes/types.js'; import type TenantContext from '#src/tenants/TenantContext.js'; import type { Options } from '#src/test-utils/jest-koa-mocks/create-mock-context.js'; import createMockContext from '#src/test-utils/jest-koa-mocks/create-mock-context.js'; @@ -106,7 +106,7 @@ export const createContextWithRouteParameters = ( /** * Supertest Request Mock Utils **/ -type RouteLauncher = ( +type RouteLauncher = ( router: T, tenant: TenantContext ) => void; @@ -118,7 +118,7 @@ export function createRequester({ tenantContext, }: { anonymousRoutes?: RouteLauncher | Array>; - authedRoutes?: RouteLauncher | Array>; + authedRoutes?: RouteLauncher | Array>; middlewares?: Middleware[]; tenantContext?: TenantContext; }) { @@ -142,7 +142,7 @@ export function createRequester({ } if (authedRoutes) { - const authRouter: AuthedRouter = new Router(); + const authRouter: ManagementApiRouter = new Router(); authRouter.use(async (ctx, next) => { ctx.auth = { type: 'user', id: 'foo' }; From f9c7a72d515b8d845fa8a0462e88a6a6bc0714ee Mon Sep 17 00:00:00 2001 From: Xiao Yijun Date: Wed, 24 Apr 2024 13:51:41 +0800 Subject: [PATCH 321/687] feat(connector): support `client_secret_basic` and `client_secret_jwt` methods for oauth2 connectors (#5762) --- .changeset/chilled-pugs-notice.md | 6 + .github/workflows/main.yml | 4 + .github/workflows/upload-annotations.yml | 4 + .../connectors/connector-oauth2/README.md | 4 + .../connectors/connector-oauth2/package.json | 6 +- .../connector-oauth2/src/constant.ts | 50 ++--- .../connectors/connector-oauth2/src/index.ts | 44 ++--- .../connector-oauth2/src/oauth2/form-items.ts | 96 +++++++++ .../connector-oauth2/src/oauth2/index.ts | 3 + .../connector-oauth2/src/oauth2/types.ts | 68 +++++++ .../connector-oauth2/src/oauth2/utils.test.ts | 183 ++++++++++++++++++ .../connector-oauth2/src/oauth2/utils.ts | 151 +++++++++++++++ .../connectors/connector-oauth2/src/types.ts | 32 +-- .../connectors/connector-oauth2/src/utils.ts | 99 +++++----- packages/connectors/connector-oidc/README.md | 4 + .../connectors/connector-oidc/package.json | 5 +- .../connectors/connector-oidc/src/constant.ts | 46 ++--- .../connectors/connector-oidc/src/index.ts | 45 +++-- .../connectors/connector-oidc/src/types.ts | 21 +- .../connectors/connector-oidc/src/utils.ts | 76 ++++---- packages/core/jest.config.js | 2 + packages/core/nodemon.json | 3 +- packages/shared/package.json | 1 - pnpm-lock.yaml | 40 ++-- 24 files changed, 726 insertions(+), 267 deletions(-) create mode 100644 .changeset/chilled-pugs-notice.md create mode 100644 packages/connectors/connector-oauth2/src/oauth2/form-items.ts create mode 100644 packages/connectors/connector-oauth2/src/oauth2/index.ts create mode 100644 packages/connectors/connector-oauth2/src/oauth2/types.ts create mode 100644 packages/connectors/connector-oauth2/src/oauth2/utils.test.ts create mode 100644 packages/connectors/connector-oauth2/src/oauth2/utils.ts diff --git a/.changeset/chilled-pugs-notice.md b/.changeset/chilled-pugs-notice.md new file mode 100644 index 00000000000..06b33009b6f --- /dev/null +++ b/.changeset/chilled-pugs-notice.md @@ -0,0 +1,6 @@ +--- +"@logto/connector-oauth": minor +"@logto/connector-oidc": minor +--- + +Support `client_secret_basic` and `client_secret_jwt` token endpoint auth method for oauth & oidc connectors diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index a0af63a9655..cf4bbafcb65 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -36,6 +36,10 @@ jobs: - name: Prepack run: pnpm prepack + # Build connectors before running lint since some connectors rely on the generated types + - name: Build connectors + run: pnpm connectors build + - name: Lint run: pnpm ci:lint diff --git a/.github/workflows/upload-annotations.yml b/.github/workflows/upload-annotations.yml index c4954111bd5..8e749111313 100644 --- a/.github/workflows/upload-annotations.yml +++ b/.github/workflows/upload-annotations.yml @@ -27,6 +27,10 @@ jobs: - name: Prepack run: pnpm prepack + # Build connectors before running lint since some connectors rely on the generated types + - name: Build connectors + run: pnpm connectors build + - name: Lint with Report run: pnpm -r --parallel lint:report && node .scripts/merge-eslint-reports.js diff --git a/packages/connectors/connector-oauth2/README.md b/packages/connectors/connector-oauth2/README.md index 9098feaa73e..16263a1fd76 100644 --- a/packages/connectors/connector-oauth2/README.md +++ b/packages/connectors/connector-oauth2/README.md @@ -24,6 +24,10 @@ We ONLY support "Authorization Code" grant type for security consideration and i *clientSecret*: The client secret is a confidential key that is issued to the client application by the authorization server during registration. The client application uses this secret key to authenticate itself with the authorization server when requesting access tokens. The client secret is considered confidential information and should be kept secure at all times. +*tokenEndpointAuthMethod*: The token endpoint authentication method is used by the client application to authenticate itself with the authorization server when requesting access tokens. To discover supported methods, consult the `token_endpoint_auth_methods_supported` field available at the OAuth 2.0 service provider’s OpenID Connect discovery endpoint, or refer to the relevant documentation provided by the OAuth 2.0 service provider. + +*clientSecretJwtSigningAlgorithm (Optional)*: Only required when `tokenEndpointAuthMethod` is `client_secret_jwt`. The client secret JWT signing algorithm is used by the client application to sign the JWT that is sent to the authorization server during the token request. + *scope*: The scope parameter is used to specify the set of resources and permissions that the client application is requesting access to. The scope parameter is typically defined as a space-separated list of values that represent specific permissions. For example, a scope value of "read write" might indicate that the client application is requesting read and write access to a user's data. You are expected to find `authorizationEndpoint`, `tokenEndpoint` and `userInfoEndpoint` in social vendor's documentation. diff --git a/packages/connectors/connector-oauth2/package.json b/packages/connectors/connector-oauth2/package.json index 9b62d82e912..0112f67ec51 100644 --- a/packages/connectors/connector-oauth2/package.json +++ b/packages/connectors/connector-oauth2/package.json @@ -5,8 +5,10 @@ "author": "Silverhand Inc. ", "dependencies": { "@logto/connector-kit": "workspace:^3.0.0", + "@logto/shared": "workspace:^3.1.0", "@silverhand/essentials": "^2.9.0", - "got": "^14.0.0", + "jose": "^5.0.0", + "ky": "^1.2.3", "query-string": "^9.0.0", "snakecase-keys": "^8.0.0", "zod": "^3.22.4" @@ -64,7 +66,7 @@ "@vitest/coverage-v8": "^1.4.0", "eslint": "^8.56.0", "lint-staged": "^15.0.2", - "nock": "^13.3.1", + "nock": "14.0.0-beta.6", "prettier": "^3.0.0", "rollup": "^4.12.0", "rollup-plugin-output-size": "^1.3.0", diff --git a/packages/connectors/connector-oauth2/src/constant.ts b/packages/connectors/connector-oauth2/src/constant.ts index 4624d338a5f..cd07445dded 100644 --- a/packages/connectors/connector-oauth2/src/constant.ts +++ b/packages/connectors/connector-oauth2/src/constant.ts @@ -1,6 +1,15 @@ import type { ConnectorMetadata } from '@logto/connector-kit'; import { ConnectorConfigFormItemType, ConnectorPlatform } from '@logto/connector-kit'; +import { + authorizationEndpointFormItem, + clientIdFormItem, + clientSecretFormItem, + scopeFormItem, + tokenEndpointAuthOptionsFormItems, + tokenEndpointFormItem, +} from './oauth2/form-items.js'; + export const defaultMetadata: ConnectorMetadata = { id: 'oauth2', target: 'oauth2', @@ -18,20 +27,8 @@ export const defaultMetadata: ConnectorMetadata = { readme: './README.md', isStandard: true, formItems: [ - { - key: 'authorizationEndpoint', - label: 'Authorization Endpoint', - type: ConnectorConfigFormItemType.Text, - required: true, - placeholder: '', - }, - { - key: 'tokenEndpoint', - label: 'Token Endpoint', - type: ConnectorConfigFormItemType.Text, - required: true, - placeholder: '', - }, + authorizationEndpointFormItem, + tokenEndpointFormItem, { key: 'userInfoEndpoint', label: 'User Info Endpoint', @@ -39,20 +36,9 @@ export const defaultMetadata: ConnectorMetadata = { required: true, placeholder: '', }, - { - key: 'clientId', - label: 'Client ID', - type: ConnectorConfigFormItemType.Text, - required: true, - placeholder: '', - }, - { - key: 'clientSecret', - label: 'Client Secret', - type: ConnectorConfigFormItemType.Text, - required: true, - placeholder: '', - }, + clientIdFormItem, + clientSecretFormItem, + ...tokenEndpointAuthOptionsFormItems, { key: 'tokenEndpointResponseType', label: 'Token Endpoint Response Type', @@ -67,13 +53,7 @@ export const defaultMetadata: ConnectorMetadata = { required: false, defaultValue: 'query-string', }, - { - key: 'scope', - label: 'Scope', - type: ConnectorConfigFormItemType.Text, - required: false, - placeholder: '', - }, + scopeFormItem, { key: 'profileMap', label: 'Profile Map', diff --git a/packages/connectors/connector-oauth2/src/index.ts b/packages/connectors/connector-oauth2/src/index.ts index f2b1c274b1c..6d07368306c 100644 --- a/packages/connectors/connector-oauth2/src/index.ts +++ b/packages/connectors/connector-oauth2/src/index.ts @@ -1,6 +1,4 @@ import { assert, pick } from '@silverhand/essentials'; -import { got, HTTPError } from 'got'; -import snakecaseKeys from 'snakecase-keys'; import { type GetAuthorizationUri, @@ -14,45 +12,40 @@ import { validateConfig, ConnectorType, } from '@logto/connector-kit'; +import ky, { HTTPError } from 'ky'; import { defaultMetadata, defaultTimeout } from './constant.js'; -import { oauthConfigGuard } from './types.js'; +import { constructAuthorizationUri } from './oauth2/utils.js'; +import { oauth2ConnectorConfigGuard } from './types.js'; import { userProfileMapping, getAccessToken } from './utils.js'; -const removeUndefinedKeys = (object: Record) => - Object.fromEntries(Object.entries(object).filter(([, value]) => value !== undefined)); +export * from './oauth2/index.js'; const getAuthorizationUri = (getConfig: GetConnectorConfig): GetAuthorizationUri => async ({ state, redirectUri }, setSession) => { const config = await getConfig(defaultMetadata.id); - validateConfig(config, oauthConfigGuard); - const parsedConfig = oauthConfigGuard.parse(config); - - const { customConfig, ...rest } = parsedConfig; - - const parameterObject = snakecaseKeys({ - ...pick(rest, 'responseType', 'clientId', 'scope'), - ...customConfig, - }); + validateConfig(config, oauth2ConnectorConfigGuard); + const parsedConfig = oauth2ConnectorConfigGuard.parse(config); await setSession({ redirectUri }); - const queryParameters = new URLSearchParams({ - ...removeUndefinedKeys(parameterObject), + const { authorizationEndpoint, customConfig } = parsedConfig; + + return constructAuthorizationUri(authorizationEndpoint, { + ...pick(parsedConfig, 'responseType', 'clientId', 'scope'), + redirectUri, state, - redirect_uri: redirectUri, + ...customConfig, }); - - return `${parsedConfig.authorizationEndpoint}?${queryParameters.toString()}`; }; const getUserInfo = (getConfig: GetConnectorConfig): GetUserInfo => async (data, getSession) => { const config = await getConfig(defaultMetadata.id); - validateConfig(config, oauthConfigGuard); - const parsedConfig = oauthConfigGuard.parse(config); + validateConfig(config, oauth2ConnectorConfigGuard); + const parsedConfig = oauth2ConnectorConfigGuard.parse(config); const { redirectUri } = await getSession(); assert( @@ -65,13 +58,14 @@ const getUserInfo = const { access_token, token_type } = await getAccessToken(parsedConfig, data, redirectUri); try { - const httpResponse = await got.get(parsedConfig.userInfoEndpoint, { + const httpResponse = await ky.get(parsedConfig.userInfoEndpoint, { headers: { authorization: `${token_type} ${access_token}`, }, - timeout: { request: defaultTimeout }, + timeout: defaultTimeout, }); - const rawData = parseJsonObject(httpResponse.body); + + const rawData = parseJsonObject(await httpResponse.text()); return { ...userProfileMapping(rawData, parsedConfig.profileMap), rawData }; } catch (error: unknown) { @@ -87,7 +81,7 @@ const createOauthConnector: CreateConnector = async ({ getConfi return { metadata: defaultMetadata, type: ConnectorType.Social, - configGuard: oauthConfigGuard, + configGuard: oauth2ConnectorConfigGuard, getAuthorizationUri: getAuthorizationUri(getConfig), getUserInfo: getUserInfo(getConfig), }; diff --git a/packages/connectors/connector-oauth2/src/oauth2/form-items.ts b/packages/connectors/connector-oauth2/src/oauth2/form-items.ts new file mode 100644 index 00000000000..3e04565cb73 --- /dev/null +++ b/packages/connectors/connector-oauth2/src/oauth2/form-items.ts @@ -0,0 +1,96 @@ +import { type ConnectorConfigFormItem, ConnectorConfigFormItemType } from '@logto/connector-kit'; + +import { TokenEndpointAuthMethod, ClientSecretJwtSigningAlgorithm } from './types.js'; + +export const authorizationEndpointFormItem: ConnectorConfigFormItem = Object.freeze({ + key: 'authorizationEndpoint', + label: 'Authorization Endpoint', + type: ConnectorConfigFormItemType.Text, + required: true, + placeholder: '', +}); + +export const tokenEndpointFormItem: ConnectorConfigFormItem = Object.freeze({ + key: 'tokenEndpoint', + label: 'Token Endpoint', + type: ConnectorConfigFormItemType.Text, + required: true, + placeholder: '', +}); + +export const clientIdFormItem: ConnectorConfigFormItem = Object.freeze({ + key: 'clientId', + label: 'Client ID', + type: ConnectorConfigFormItemType.Text, + required: true, + placeholder: '', +}); + +export const clientSecretFormItem: ConnectorConfigFormItem = Object.freeze({ + key: 'clientSecret', + label: 'Client Secret', + type: ConnectorConfigFormItemType.Text, + required: true, + placeholder: '', +}); + +export const tokenEndpointAuthOptionsFormItems: ConnectorConfigFormItem[] = [ + Object.freeze({ + key: 'tokenEndpointAuthMethod', + label: 'Token Endpoint Auth Method', + type: ConnectorConfigFormItemType.Select, + selectItems: [ + { + title: TokenEndpointAuthMethod.ClientSecretPost, + value: TokenEndpointAuthMethod.ClientSecretPost, + }, + { + title: TokenEndpointAuthMethod.ClientSecretBasic, + value: TokenEndpointAuthMethod.ClientSecretBasic, + }, + { + title: TokenEndpointAuthMethod.ClientSecretJwt, + value: TokenEndpointAuthMethod.ClientSecretJwt, + }, + ], + required: true, + defaultValue: TokenEndpointAuthMethod.ClientSecretPost, + description: 'The method used for client authentication at the token endpoint in OAuth 2.0.', + }), + Object.freeze({ + key: 'clientSecretJwtSigningAlgorithm', + label: 'Client Secret JWT Signing Algorithm', + type: ConnectorConfigFormItemType.Select, + selectItems: [ + { + title: ClientSecretJwtSigningAlgorithm.HS256, + value: ClientSecretJwtSigningAlgorithm.HS256, + }, + { + title: ClientSecretJwtSigningAlgorithm.HS384, + value: ClientSecretJwtSigningAlgorithm.HS384, + }, + { + title: ClientSecretJwtSigningAlgorithm.HS512, + value: ClientSecretJwtSigningAlgorithm.HS512, + }, + ], + showConditions: [ + { + targetKey: 'tokenEndpointAuthMethod', + expectValue: TokenEndpointAuthMethod.ClientSecretJwt, + }, + ], + required: true, + defaultValue: ClientSecretJwtSigningAlgorithm.HS256, + description: 'The signing algorithm used for the client secret JWT.', + }), +]; + +export const scopeFormItem: ConnectorConfigFormItem = Object.freeze({ + key: 'scope', + label: 'Scope', + type: ConnectorConfigFormItemType.Text, + required: false, + placeholder: '', +}); diff --git a/packages/connectors/connector-oauth2/src/oauth2/index.ts b/packages/connectors/connector-oauth2/src/oauth2/index.ts new file mode 100644 index 00000000000..6449585de66 --- /dev/null +++ b/packages/connectors/connector-oauth2/src/oauth2/index.ts @@ -0,0 +1,3 @@ +export * from './types.js'; +export * from './utils.js'; +export * from './form-items.js'; diff --git a/packages/connectors/connector-oauth2/src/oauth2/types.ts b/packages/connectors/connector-oauth2/src/oauth2/types.ts new file mode 100644 index 00000000000..6c9e8c47331 --- /dev/null +++ b/packages/connectors/connector-oauth2/src/oauth2/types.ts @@ -0,0 +1,68 @@ +import { z } from 'zod'; + +/** + * OAuth 2.0 Client Authentication methods that are used by Clients to authenticate to the Authorization Server when using the Token Endpoint. + */ +export enum TokenEndpointAuthMethod { + ClientSecretBasic = 'client_secret_basic', + ClientSecretPost = 'client_secret_post', + ClientSecretJwt = 'client_secret_jwt', +} + +/* + * Enumeration of algorithms supported for JWT signing when using client secrets. + * + * These "HS" algorithms (HMAC using SHA) are specifically chosen for scenarios where the + * client authentication method is 'client_secret_jwt'. HMAC algorithms utilize the + * client_secret as a shared symmetric key to generate a secure hash, ensuring the integrity + * and authenticity of the JWT. + * + * Other types of algorithms, such as RSASSA (RS256, RS384, RS512) or ECDSA (ES256, ES384, ES512), + * utilize asymmetric keys, are complex and requires secure key management infrastructure. + * + * In the 'client_secret_jwt' context, where simplicity and symmetric key usage are preferred for + * straightforward validation by the authorization server without the need to manage or distribute + * public keys, HMAC algorithms are more suitable. + */ +export enum ClientSecretJwtSigningAlgorithm { + /** HMAC using SHA-256 hash algorithm */ + HS256 = 'HS256', + /** HMAC using SHA-384 hash algorithm */ + HS384 = 'HS384', + /** HMAC using SHA-512 hash algorithm */ + HS512 = 'HS512', +} + +export const oauth2ConfigGuard = z.object({ + responseType: z.literal('code').optional().default('code'), + grantType: z.literal('authorization_code').optional().default('authorization_code'), + authorizationEndpoint: z.string(), + tokenEndpoint: z.string(), + clientId: z.string(), + clientSecret: z.string(), + tokenEndpointAuthMethod: z + .nativeEnum(TokenEndpointAuthMethod) + .optional() + .default(TokenEndpointAuthMethod.ClientSecretPost), + clientSecretJwtSigningAlgorithm: z + .nativeEnum(ClientSecretJwtSigningAlgorithm) + .optional() + .default(ClientSecretJwtSigningAlgorithm.HS256), + scope: z.string().optional(), +}); + +export const oauth2AuthResponseGuard = z.object({ + code: z.string(), + state: z.string().optional(), +}); + +export type Oauth2AuthResponse = z.infer; + +export const oauth2AccessTokenResponseGuard = z.object({ + access_token: z.string(), + token_type: z.string(), + expires_in: z.number().optional(), + refresh_token: z.string().optional(), +}); + +export type Oauth2AccessTokenResponse = z.infer; diff --git a/packages/connectors/connector-oauth2/src/oauth2/utils.test.ts b/packages/connectors/connector-oauth2/src/oauth2/utils.test.ts new file mode 100644 index 00000000000..e4b7184991c --- /dev/null +++ b/packages/connectors/connector-oauth2/src/oauth2/utils.test.ts @@ -0,0 +1,183 @@ +import nock from 'nock'; + +import ky from 'ky'; + +import { ClientSecretJwtSigningAlgorithm, TokenEndpointAuthMethod } from './types.js'; +import { constructAuthorizationUri, type RequestTokenEndpointOptions } from './utils.js'; + +const kyPostMock = vi.spyOn(ky, 'post'); + +vi.mock('jose', () => ({ + SignJWT: vi.fn(() => ({ + setProtectedHeader: vi.fn().mockReturnThis(), + sign: vi.fn().mockResolvedValue('signed-jwt'), + })), +})); + +const { requestTokenEndpoint } = await import('./utils.js'); + +const tokenEndpointUrl = new URL('https://example.com/token'); + +describe('requestTokenEndpoint', () => { + beforeEach(() => { + nock(tokenEndpointUrl.origin) + .post(tokenEndpointUrl.pathname) + .query(true) + .reply( + 200, + JSON.stringify({ + access_token: 'access_token', + token_type: 'bearer', + }) + ); + }); + + afterEach(() => { + nock.cleanAll(); + }); + + afterAll(() => { + vi.clearAllMocks(); + }); + + it('should handle TokenEndpointAuthMethod.ClientSecretJwt correctly', async () => { + const options: RequestTokenEndpointOptions = { + tokenEndpoint: 'https://example.com/token', + tokenEndpointAuthOptions: { + method: TokenEndpointAuthMethod.ClientSecretJwt, + clientSecretJwtSigningAlgorithm: ClientSecretJwtSigningAlgorithm.HS256, + }, + tokenRequestBody: { + grantType: 'authorization_code', + code: 'authcode123', + redirectUri: 'https://example.com/callback', + clientId: 'client123', + clientSecret: 'secret123', + extraParam: 'extra', + }, + timeout: 5000, + }; + + await requestTokenEndpoint(options); + expect(kyPostMock).toHaveBeenCalledWith(options.tokenEndpoint, { + body: new URLSearchParams({ + grant_type: 'authorization_code', + code: 'authcode123', + redirect_uri: 'https://example.com/callback', + extra_param: 'extra', + client_id: 'client123', + client_assertion: 'signed-jwt', + client_assertion_type: 'urn:ietf:params:oauth:client-assertion-type:jwt-bearer', + }), + timeout: 5000, + }); + }); + + it('should handle TokenEndpointAuthMethod.ClientSecretBasic correctly', async () => { + const options: RequestTokenEndpointOptions = { + tokenEndpoint: 'https://example.com/token', + tokenEndpointAuthOptions: { + method: TokenEndpointAuthMethod.ClientSecretBasic, + }, + tokenRequestBody: { + grantType: 'authorization_code', + code: 'authcode123', + redirectUri: 'https://example.com/callback', + clientId: 'client123', + clientSecret: 'secret123', + extraParam: 'extra', + }, + timeout: 5000, + }; + + await requestTokenEndpoint(options); + expect(kyPostMock).toHaveBeenCalledWith(options.tokenEndpoint, { + headers: { + Authorization: `Basic ${Buffer.from('client123:secret123').toString('base64')}`, + }, + body: new URLSearchParams({ + grant_type: 'authorization_code', + code: 'authcode123', + redirect_uri: 'https://example.com/callback', + extra_param: 'extra', + }), + timeout: 5000, + }); + }); + + it('should handle TokenEndpointAuthMethod.ClientSecretPost correctly', async () => { + const options: RequestTokenEndpointOptions = { + tokenEndpoint: 'https://example.com/token', + tokenEndpointAuthOptions: { + method: TokenEndpointAuthMethod.ClientSecretPost, + }, + tokenRequestBody: { + grantType: 'authorization_code', + code: 'authcode123', + redirectUri: 'https://example.com/callback', + clientId: 'client123', + clientSecret: 'secret123', + extraParam: 'extra', + }, + timeout: 5000, + }; + + await requestTokenEndpoint(options); + expect(kyPostMock).toHaveBeenCalledWith(options.tokenEndpoint, { + body: new URLSearchParams({ + grant_type: 'authorization_code', + code: 'authcode123', + redirect_uri: 'https://example.com/callback', + client_id: 'client123', + client_secret: 'secret123', + extra_param: 'extra', + }), + timeout: 5000, + }); + }); +}); + +describe('constructAuthorizationUri', () => { + it('constructs a valid authorization URL with all parameters', async () => { + const authorizationEndpoint = 'https://example.com/oauth/authorize'; + const queryParameters = { + responseType: 'code', + clientId: 'client123', + scope: 'openid email', + redirectUri: 'https://example.com/callback', + state: 'state123', + }; + + const expectedParams = new URLSearchParams({ + response_type: 'code', + client_id: 'client123', + scope: 'openid email', + redirect_uri: 'https://example.com/callback', + state: 'state123', + }).toString(); + + const result = constructAuthorizationUri(authorizationEndpoint, queryParameters); + expect(result).toBe(`${authorizationEndpoint}?${expectedParams}`); + }); + + it('omits undefined values from the constructed URL', async () => { + const authorizationEndpoint = 'https://example.com/oauth/authorize'; + const queryParameters = { + responseType: 'code', + clientId: 'client123', + redirectUri: 'https://example.com/callback', + state: 'state123', + scope: undefined, // This should not appear in the final URL + }; + + const expectedParams = new URLSearchParams({ + response_type: 'code', + client_id: 'client123', + redirect_uri: 'https://example.com/callback', + state: 'state123', + }).toString(); + + const result = constructAuthorizationUri(authorizationEndpoint, queryParameters); + expect(result).toBe(`${authorizationEndpoint}?${expectedParams}`); + }); +}); diff --git a/packages/connectors/connector-oauth2/src/oauth2/utils.ts b/packages/connectors/connector-oauth2/src/oauth2/utils.ts new file mode 100644 index 00000000000..51f87565f15 --- /dev/null +++ b/packages/connectors/connector-oauth2/src/oauth2/utils.ts @@ -0,0 +1,151 @@ +import { removeUndefinedKeys } from '@silverhand/essentials'; +import snakecaseKeys from 'snakecase-keys'; + +import { ConnectorError, ConnectorErrorCodes } from '@logto/connector-kit'; +import { generateStandardId } from '@logto/shared/universal'; +import { SignJWT } from 'jose'; +import ky, { HTTPError } from 'ky'; + +import { TokenEndpointAuthMethod } from './types.js'; + +type TokenEndpointAuthOptions = + T extends TokenEndpointAuthMethod.ClientSecretJwt + ? { + method: TokenEndpointAuthMethod.ClientSecretJwt; + clientSecretJwtSigningAlgorithm: string; + } + : { + method: + | TokenEndpointAuthMethod.ClientSecretBasic + | TokenEndpointAuthMethod.ClientSecretPost; + }; + +export type RequestTokenEndpointOptions = { + tokenEndpoint: string; + tokenEndpointAuthOptions: TokenEndpointAuthOptions; + tokenRequestBody: { + grantType: string; + code: string; + redirectUri: string; + clientId: string; + clientSecret: string; + } & Record; + timeout?: number; +}; + +/** + * Requests the token endpoint for an access token with given client authentication options. + * + * @param tokenEndpoint - The URL of the token endpoint. + * @param clientCredentials - The client credentials (client ID and client secret). + * @param tokenEndpointAuthOptions - The options for authenticating with the token endpoint. + * @param tokenEndpointAuthOptions.method - The method to use for authenticating with the token endpoint. + * @param tokenEndpointAuthOptions.clientSecretJwtSigningAlgorithm - The signing algorithm to use for the client secret JWT. Required if the `method` is `TokenEndpointAuthMethod.ClientSecretJwt`. + * @param tokenRequestBody - The request body to be sent as application/x-www-form-urlencoded to the token endpoint. Parameters are automatically converted to snake_case and undefined values are removed. + * @param timeout - The timeout for the request in milliseconds. + * @returns A Promise that resolves to the response from the token endpoint. + */ +export const requestTokenEndpoint = async ({ + tokenEndpoint, + tokenEndpointAuthOptions, + tokenRequestBody, + timeout, +}: RequestTokenEndpointOptions) => { + const postTokenEndpoint = async ({ + form, + headers, + }: { + form: Record; + headers?: Record; + }) => { + try { + return await ky.post(tokenEndpoint, { + headers, + body: new URLSearchParams(removeUndefinedKeys(snakecaseKeys(form))), + timeout, + }); + } catch (error: unknown) { + if (error instanceof HTTPError) { + throw new ConnectorError(ConnectorErrorCodes.General, JSON.stringify(error.response.body)); + } + + throw error; + } + }; + + const { clientId, clientSecret, ...requestBodyWithoutClientCredentials } = tokenRequestBody; + + switch (tokenEndpointAuthOptions.method) { + case TokenEndpointAuthMethod.ClientSecretJwt: { + const clientSecretJwt = await new SignJWT({ + iss: clientId, + sub: clientId, + aud: tokenEndpoint, + jti: generateStandardId(), + exp: Math.floor(Date.now() / 1000) + 600, // Expiration time is 10 minutes + iat: Math.floor(Date.now() / 1000), + }) + .setProtectedHeader({ + alg: tokenEndpointAuthOptions.clientSecretJwtSigningAlgorithm, + }) + .sign(Buffer.from(clientSecret)) + .catch((error: unknown) => { + if (error instanceof Error) { + throw new ConnectorError( + ConnectorErrorCodes.General, + 'Failed to sign client secret JWT' + ); + } + throw error; + }); + + return postTokenEndpoint({ + form: { + ...requestBodyWithoutClientCredentials, + clientId, + clientAssertion: clientSecretJwt, + /** + * `client_assertion_type` parameter MUST be "urn:ietf:params:oauth:client-assertion-type:jwt-bearer" + * see https://datatracker.ietf.org/doc/html/rfc7523#section-2.2 + */ + clientAssertionType: 'urn:ietf:params:oauth:client-assertion-type:jwt-bearer', + }, + }); + } + case TokenEndpointAuthMethod.ClientSecretBasic: { + return postTokenEndpoint({ + form: requestBodyWithoutClientCredentials, + headers: { + Authorization: `Basic ${Buffer.from(`${clientId}:${clientSecret}`).toString('base64')}`, + }, + }); + } + case TokenEndpointAuthMethod.ClientSecretPost: { + return postTokenEndpoint({ + form: tokenRequestBody, + }); + } + } +}; + +/** + * Constructs a complete URL for initiating OAuth authorization by appending properly formatted + * query parameters to the provided authorization endpoint URL. + * + * @param authorizationEndpoint The base URL to which the OAuth authorization request is sent. + * @param queryParameters An object containing OAuth specific parameters such as responseType, clientId, scope, redirectUri, and state. Additional custom parameters can also be included as needed. Parameters are automatically converted to snake_case and undefined values are removed. + * @returns A string representing the fully constructed URL to be used for OAuth authorization. + */ +export const constructAuthorizationUri = ( + authorizationEndpoint: string, + queryParameters: { + responseType: string; + clientId: string; + scope?: string; + redirectUri: string; + state: string; + } & Record +) => + `${authorizationEndpoint}?${new URLSearchParams( + removeUndefinedKeys(snakecaseKeys(queryParameters)) + ).toString()}`; diff --git a/packages/connectors/connector-oauth2/src/types.ts b/packages/connectors/connector-oauth2/src/types.ts index efae11b4c5f..1aa04aaee27 100644 --- a/packages/connectors/connector-oauth2/src/types.ts +++ b/packages/connectors/connector-oauth2/src/types.ts @@ -1,5 +1,7 @@ import { z } from 'zod'; +import { oauth2ConfigGuard } from './oauth2/types.js'; + export const profileMapGuard = z .object({ id: z.string().optional().default('id'), @@ -36,35 +38,11 @@ const tokenEndpointResponseTypeGuard = z export type TokenEndpointResponseType = z.input; -export const oauthConfigGuard = z.object({ - responseType: z.literal('code').optional().default('code'), - grantType: z.literal('authorization_code').optional().default('authorization_code'), - tokenEndpointResponseType: tokenEndpointResponseTypeGuard, - authorizationEndpoint: z.string(), - tokenEndpoint: z.string(), +export const oauth2ConnectorConfigGuard = oauth2ConfigGuard.extend({ userInfoEndpoint: z.string(), - clientId: z.string(), - clientSecret: z.string(), - scope: z.string().optional(), + tokenEndpointResponseType: tokenEndpointResponseTypeGuard, profileMap: profileMapGuard, customConfig: z.record(z.string()).optional(), }); -export type OauthConfig = z.infer; - -export const authResponseGuard = z.object({ - code: z.string(), - state: z.string().optional(), -}); - -export type AuthResponse = z.infer; - -export const accessTokenResponseGuard = z.object({ - access_token: z.string(), - token_type: z.string(), - expires_in: z.number().optional(), - refresh_token: z.string().optional(), - scope: z.string().optional(), -}); - -export type AccessTokenResponse = z.infer; +export type Oauth2ConnectorConfig = z.infer; diff --git a/packages/connectors/connector-oauth2/src/utils.ts b/packages/connectors/connector-oauth2/src/utils.ts index a304854bd7c..18d51f407a4 100644 --- a/packages/connectors/connector-oauth2/src/utils.ts +++ b/packages/connectors/connector-oauth2/src/utils.ts @@ -1,48 +1,25 @@ -import { assert, pick } from '@silverhand/essentials'; -import type { Response } from 'got'; -import { got, HTTPError } from 'got'; -import snakecaseKeys from 'snakecase-keys'; +import { assert } from '@silverhand/essentials'; import { ConnectorError, ConnectorErrorCodes, parseJson } from '@logto/connector-kit'; +import { type KyResponse } from 'ky'; import qs from 'query-string'; -import { defaultTimeout } from './constant.js'; -import type { - OauthConfig, - TokenEndpointResponseType, - AccessTokenResponse, - ProfileMap, -} from './types.js'; -import { authResponseGuard, accessTokenResponseGuard, userProfileGuard } from './types.js'; - -export const accessTokenRequester = async ( - tokenEndpoint: string, - queryParameters: Record, - tokenEndpointResponseType: TokenEndpointResponseType, - timeout: number = defaultTimeout -): Promise => { - try { - const httpResponse = await got.post({ - url: tokenEndpoint, - form: queryParameters, - timeout: { request: timeout }, - }); - - return await accessTokenResponseHandler(httpResponse, tokenEndpointResponseType); - } catch (error: unknown) { - if (error instanceof HTTPError) { - throw new ConnectorError(ConnectorErrorCodes.General, JSON.stringify(error.response.body)); - } - throw error; - } -}; +import { + type Oauth2AccessTokenResponse, + oauth2AccessTokenResponseGuard, + oauth2AuthResponseGuard, +} from './oauth2/types.js'; +import { requestTokenEndpoint } from './oauth2/utils.js'; +import type { Oauth2ConnectorConfig, TokenEndpointResponseType, ProfileMap } from './types.js'; +import { userProfileGuard } from './types.js'; const accessTokenResponseHandler = async ( - response: Response, + response: KyResponse, tokenEndpointResponseType: TokenEndpointResponseType -): Promise => { - const result = accessTokenResponseGuard.safeParse( - tokenEndpointResponseType === 'json' ? parseJson(response.body) : qs.parse(response.body) +): Promise => { + const responseContent = await response.text(); + const result = oauth2AccessTokenResponseGuard.safeParse( + tokenEndpointResponseType === 'json' ? parseJson(responseContent) : qs.parse(responseContent) ); // Why it works with qs.parse() if (!result.success) { @@ -84,8 +61,12 @@ export const userProfileMapping = ( return result.data; }; -export const getAccessToken = async (config: OauthConfig, data: unknown, redirectUri: string) => { - const result = authResponseGuard.safeParse(data); +export const getAccessToken = async ( + config: Oauth2ConnectorConfig, + data: unknown, + redirectUri: string +) => { + const result = oauth2AuthResponseGuard.safeParse(data); if (!result.success) { throw new ConnectorError(ConnectorErrorCodes.General, data); @@ -93,18 +74,32 @@ export const getAccessToken = async (config: OauthConfig, data: unknown, redirec const { code } = result.data; - const { customConfig, ...rest } = config; - - const parameterObject = snakecaseKeys({ - ...pick(rest, 'grantType', 'clientId', 'clientSecret'), - ...customConfig, - code, - redirectUri, + const { + grantType, + tokenEndpoint, + tokenEndpointResponseType, + clientId, + clientSecret, + tokenEndpointAuthMethod, + clientSecretJwtSigningAlgorithm, + customConfig, + } = config; + + const tokenResponse = await requestTokenEndpoint({ + tokenEndpoint, + tokenEndpointAuthOptions: { + method: tokenEndpointAuthMethod, + clientSecretJwtSigningAlgorithm, + }, + tokenRequestBody: { + grantType, + code, + redirectUri, + clientId, + clientSecret, + ...customConfig, + }, }); - return accessTokenRequester( - config.tokenEndpoint, - parameterObject, - config.tokenEndpointResponseType - ); + return accessTokenResponseHandler(tokenResponse, tokenEndpointResponseType); }; diff --git a/packages/connectors/connector-oidc/README.md b/packages/connectors/connector-oidc/README.md index eb58ca8e3ab..68bae7495ad 100644 --- a/packages/connectors/connector-oidc/README.md +++ b/packages/connectors/connector-oidc/README.md @@ -24,6 +24,10 @@ We ONLY support "Authorization Code" grant type for security consideration and i *clientSecret*: The client secret is a confidential key that is issued to the client application by the authorization server during registration. The client application uses this secret key to authenticate itself with the authorization server when requesting access tokens. The client secret is considered confidential information and should be kept secure at all times. +*tokenEndpointAuthMethod*: The token endpoint authentication method is used by the client application to authenticate itself with the authorization server when requesting access tokens. To discover supported methods, consult the `token_endpoint_auth_methods_supported` field available at the OAuth 2.0 service provider’s OpenID Connect discovery endpoint, or refer to the relevant documentation provided by the OAuth 2.0 service provider. + +*clientSecretJwtSigningAlgorithm (Optional)*: Only required when `tokenEndpointAuthMethod` is `client_secret_jwt`. The client secret JWT signing algorithm is used by the client application to sign the JWT that is sent to the authorization server during the token request. + *scope*: The scope parameter is used to specify the set of resources and permissions that the client application is requesting access to. The scope parameter is typically defined as a space-separated list of values that represent specific permissions. For example, a scope value of "read write" might indicate that the client application is requesting read and write access to a user's data. You are expected to find `authorizationEndpoint`, `tokenEndpoint`, `jwksUri` and `issuer` as OpenID Provider's configuration information. They should be available in social vendor's documentation. diff --git a/packages/connectors/connector-oidc/package.json b/packages/connectors/connector-oidc/package.json index 56dc91630af..d605f729d69 100644 --- a/packages/connectors/connector-oidc/package.json +++ b/packages/connectors/connector-oidc/package.json @@ -4,10 +4,11 @@ "description": "OIDC standard connector implementation.", "dependencies": { "@logto/connector-kit": "workspace:^3.0.0", + "@logto/connector-oauth": "workspace:^1.2.0", "@logto/shared": "workspace:^3.1.0", "@silverhand/essentials": "^2.9.0", - "got": "^14.0.0", "jose": "^5.0.0", + "ky": "^1.2.3", "nanoid": "^5.0.1", "snakecase-keys": "^8.0.0", "zod": "^3.22.4" @@ -65,7 +66,7 @@ "@vitest/coverage-v8": "^1.4.0", "eslint": "^8.56.0", "lint-staged": "^15.0.2", - "nock": "^13.3.1", + "nock": "14.0.0-beta.6", "prettier": "^3.0.0", "rollup": "^4.12.0", "rollup-plugin-output-size": "^1.3.0", diff --git a/packages/connectors/connector-oidc/src/constant.ts b/packages/connectors/connector-oidc/src/constant.ts index 2315bc1e4a0..44fc1349a4d 100644 --- a/packages/connectors/connector-oidc/src/constant.ts +++ b/packages/connectors/connector-oidc/src/constant.ts @@ -1,5 +1,13 @@ import type { ConnectorMetadata } from '@logto/connector-kit'; import { ConnectorConfigFormItemType, ConnectorPlatform } from '@logto/connector-kit'; +import { + tokenEndpointAuthOptionsFormItems, + clientSecretFormItem, + clientIdFormItem, + tokenEndpointFormItem, + authorizationEndpointFormItem, + scopeFormItem, +} from '@logto/connector-oauth'; export const defaultMetadata: ConnectorMetadata = { id: 'oidc', @@ -18,40 +26,14 @@ export const defaultMetadata: ConnectorMetadata = { readme: './README.md', isStandard: true, formItems: [ + authorizationEndpointFormItem, + tokenEndpointFormItem, + clientIdFormItem, + clientSecretFormItem, + ...tokenEndpointAuthOptionsFormItems, { - key: 'authorizationEndpoint', - label: 'Authorization Endpoint', - type: ConnectorConfigFormItemType.Text, + ...scopeFormItem, required: true, - placeholder: '', - }, - { - key: 'tokenEndpoint', - label: 'Token Endpoint', - type: ConnectorConfigFormItemType.Text, - required: true, - placeholder: '', - }, - { - key: 'clientId', - label: 'Client ID', - type: ConnectorConfigFormItemType.Text, - required: true, - placeholder: '', - }, - { - key: 'clientSecret', - label: 'Client Secret', - type: ConnectorConfigFormItemType.Text, - required: true, - placeholder: '', - }, - { - key: 'scope', - label: 'Scope', - type: ConnectorConfigFormItemType.Text, - required: true, - placeholder: '', }, { key: 'idTokenVerificationConfig', diff --git a/packages/connectors/connector-oidc/src/index.ts b/packages/connectors/connector-oidc/src/index.ts index a413a26c06f..a05af49ca09 100644 --- a/packages/connectors/connector-oidc/src/index.ts +++ b/packages/connectors/connector-oidc/src/index.ts @@ -1,6 +1,4 @@ -import { assert, conditional, pick } from '@silverhand/essentials'; -import { HTTPError } from 'got'; -import snakecaseKeys from 'snakecase-keys'; +import { assert, conditional } from '@silverhand/essentials'; import type { GetAuthorizationUri, @@ -16,11 +14,13 @@ import { ConnectorType, jsonGuard, } from '@logto/connector-kit'; +import { constructAuthorizationUri } from '@logto/connector-oauth'; import { generateStandardId } from '@logto/shared/universal'; import { createRemoteJWKSet, jwtVerify } from 'jose'; +import { HTTPError } from 'ky'; import { defaultMetadata } from './constant.js'; -import { idTokenProfileStandardClaimsGuard, oidcConfigGuard } from './types.js'; +import { idTokenProfileStandardClaimsGuard, oidcConnectorConfigGuard } from './types.js'; import { getIdToken } from './utils.js'; const generateNonce = () => generateStandardId(); @@ -29,8 +29,8 @@ const getAuthorizationUri = (getConfig: GetConnectorConfig): GetAuthorizationUri => async ({ state, redirectUri }, setSession) => { const config = await getConfig(defaultMetadata.id); - validateConfig(config, oidcConfigGuard); - const parsedConfig = oidcConfigGuard.parse(config); + validateConfig(config, oidcConnectorConfigGuard); + const parsedConfig = oidcConnectorConfigGuard.parse(config); const nonce = generateNonce(); @@ -42,28 +42,33 @@ const getAuthorizationUri = ); await setSession({ nonce, redirectUri }); - const { customConfig, authRequestOptionalConfig, ...rest } = parsedConfig; - - const queryParameters = new URLSearchParams({ + const { + authorizationEndpoint, + responseType, + clientId, + scope, + customConfig, + authRequestOptionalConfig, + } = parsedConfig; + + return constructAuthorizationUri(authorizationEndpoint, { + responseType, + clientId, + scope, + redirectUri, state, - ...snakecaseKeys({ - ...pick(rest, 'responseType', 'scope', 'clientId'), - ...authRequestOptionalConfig, - ...customConfig, - }), nonce, - redirect_uri: redirectUri, + ...authRequestOptionalConfig, + ...customConfig, }); - - return `${parsedConfig.authorizationEndpoint}?${queryParameters.toString()}`; }; const getUserInfo = (getConfig: GetConnectorConfig): GetUserInfo => async (data, getSession) => { const config = await getConfig(defaultMetadata.id); - validateConfig(config, oidcConfigGuard); - const parsedConfig = oidcConfigGuard.parse(config); + validateConfig(config, oidcConnectorConfigGuard); + const parsedConfig = oidcConnectorConfigGuard.parse(config); assert( getSession, @@ -153,7 +158,7 @@ const createOidcConnector: CreateConnector = async ({ getConfig return { metadata: defaultMetadata, type: ConnectorType.Social, - configGuard: oidcConfigGuard, + configGuard: oidcConnectorConfigGuard, getAuthorizationUri: getAuthorizationUri(getConfig), getUserInfo: getUserInfo(getConfig), }; diff --git a/packages/connectors/connector-oidc/src/types.ts b/packages/connectors/connector-oidc/src/types.ts index 4039d553c7c..432a43af916 100644 --- a/packages/connectors/connector-oidc/src/types.ts +++ b/packages/connectors/connector-oidc/src/types.ts @@ -1,5 +1,7 @@ import { z } from 'zod'; +import { oauth2ConfigGuard } from '@logto/connector-oauth'; + const scopeOpenid = 'openid'; export const delimiter = /[ +]/; @@ -38,16 +40,6 @@ export const userProfileGuard = z.object({ export type UserProfile = z.infer; -const endpointConfigObject = { - authorizationEndpoint: z.string(), - tokenEndpoint: z.string(), -}; - -const clientConfigObject = { - clientId: z.string(), - clientSecret: z.string(), -}; - /** * We remove `nonce` in `authRequestOptionalConfigGuard` because it should be a randomly generated string, * should not be fixed in config and will be generated in Logto core according to `response_type` of authorization request. @@ -84,18 +76,15 @@ export const idTokenVerificationConfigGuard = z.object({ jwksUri: z.string() }). export type IdTokenVerificationConfig = z.infer; -export const oidcConfigGuard = z.object({ - responseType: z.literal('code').optional().default('code'), - grantType: z.literal('authorization_code').optional().default('authorization_code'), +export const oidcConnectorConfigGuard = oauth2ConfigGuard.extend({ + // Override `scope` to ensure it contains 'openid'. scope: z.string().transform(scopePostProcessor), idTokenVerificationConfig: idTokenVerificationConfigGuard, authRequestOptionalConfig: authRequestOptionalConfigGuard.optional(), customConfig: z.record(z.string()).optional(), - ...endpointConfigObject, - ...clientConfigObject, }); -export type OidcConfig = z.infer; +export type OidcConnectorConfig = z.infer; export const authResponseGuard = z .object({ diff --git a/packages/connectors/connector-oidc/src/utils.ts b/packages/connectors/connector-oidc/src/utils.ts index fa227364d0a..e623eb20272 100644 --- a/packages/connectors/connector-oidc/src/utils.ts +++ b/packages/connectors/connector-oidc/src/utils.ts @@ -1,39 +1,12 @@ -import { pick } from '@silverhand/essentials'; -import type { Response } from 'got'; -import { got, HTTPError } from 'got'; -import snakecaseKeys from 'snakecase-keys'; - import { ConnectorError, ConnectorErrorCodes, parseJson } from '@logto/connector-kit'; +import { requestTokenEndpoint } from '@logto/connector-oauth'; +import { type KyResponse } from 'ky'; -import { defaultTimeout } from './constant.js'; -import type { AccessTokenResponse, OidcConfig } from './types.js'; +import type { AccessTokenResponse, OidcConnectorConfig } from './types.js'; import { accessTokenResponseGuard, authResponseGuard } from './types.js'; -export const accessTokenRequester = async ( - tokenEndpoint: string, - queryParameters: Record, - timeout: number = defaultTimeout -): Promise => { - try { - const httpResponse = await got.post({ - url: tokenEndpoint, - form: queryParameters, - timeout: { request: timeout }, - }); - - return await accessTokenResponseHandler(httpResponse); - } catch (error: unknown) { - if (error instanceof HTTPError) { - throw new ConnectorError(ConnectorErrorCodes.General, JSON.stringify(error.response.body)); - } - throw error; - } -}; - -const accessTokenResponseHandler = async ( - response: Response -): Promise => { - const result = accessTokenResponseGuard.safeParse(parseJson(response.body)); +const accessTokenResponseHandler = async (response: KyResponse): Promise => { + const result = accessTokenResponseGuard.safeParse(parseJson(await response.text())); if (!result.success) { throw new ConnectorError(ConnectorErrorCodes.InvalidResponse, result.error); @@ -42,7 +15,11 @@ const accessTokenResponseHandler = async ( return result.data; }; -export const getIdToken = async (config: OidcConfig, data: unknown, redirectUri: string) => { +export const getIdToken = async ( + config: OidcConnectorConfig, + data: unknown, + redirectUri: string +) => { const result = authResponseGuard.safeParse(data); if (!result.success) { @@ -51,14 +28,31 @@ export const getIdToken = async (config: OidcConfig, data: unknown, redirectUri: const { code } = result.data; - const { customConfig, ...rest } = config; - - const parameterObject = snakecaseKeys({ - ...pick(rest, 'grantType', 'clientId', 'clientSecret'), - ...customConfig, - code, - redirectUri, + const { + tokenEndpoint, + grantType, + clientId, + clientSecret, + tokenEndpointAuthMethod, + clientSecretJwtSigningAlgorithm, + customConfig, + } = config; + + const tokenResponse = await requestTokenEndpoint({ + tokenEndpoint, + tokenEndpointAuthOptions: { + method: tokenEndpointAuthMethod, + clientSecretJwtSigningAlgorithm, + }, + tokenRequestBody: { + grantType, + code, + redirectUri, + clientId, + clientSecret, + ...customConfig, + }, }); - return accessTokenRequester(config.tokenEndpoint, parameterObject); + return accessTokenResponseHandler(tokenResponse); }; diff --git a/packages/core/jest.config.js b/packages/core/jest.config.js index dad1a7aff3c..7345a0ed30d 100644 --- a/packages/core/jest.config.js +++ b/packages/core/jest.config.js @@ -11,6 +11,8 @@ const config = { moduleNameMapper: { '^#src/(.*)\\.js(x)?$': '/build/$1', '^(chalk|inquirer)$': '/../shared/lib/esm/module-proxy.js', + // Map the connector-kit to the installed version rather than finding it from the `shared` package (which is the default behavior of `mockEsm` in the `shared` package) + '^@logto/connector-kit$': '/node_modules/@logto/connector-kit/lib/index.js', }, }; diff --git a/packages/core/nodemon.json b/packages/core/nodemon.json index b56fb7e927f..ca594d4cb81 100644 --- a/packages/core/nodemon.json +++ b/packages/core/nodemon.json @@ -9,7 +9,8 @@ "../core/src/", "../core/node_modules/", ".env", - "../../.env" + "../../.env", + "../connectors/*/lib/" ], "ext": "json,js,jsx,ts,tsx", "delay": 500 diff --git a/packages/shared/package.json b/packages/shared/package.json index 54ed3e0c77c..d667762af30 100644 --- a/packages/shared/package.json +++ b/packages/shared/package.json @@ -38,7 +38,6 @@ }, "devDependencies": { "@jest/globals": "^29.7.0", - "@logto/connector-kit": "workspace:^3.0.0", "@silverhand/eslint-config": "6.0.1", "@silverhand/ts-config": "6.0.0", "@types/node": "^20.9.5", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 43d3d51dbba..17f9cdee912 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -1860,12 +1860,18 @@ importers: '@logto/connector-kit': specifier: workspace:^3.0.0 version: link:../../toolkit/connector-kit + '@logto/shared': + specifier: workspace:^3.1.0 + version: link:../../shared '@silverhand/essentials': specifier: ^2.9.0 version: 2.9.0 - got: - specifier: ^14.0.0 - version: 14.0.0 + jose: + specifier: ^5.0.0 + version: 5.2.2 + ky: + specifier: ^1.2.3 + version: 1.2.3 query-string: specifier: ^9.0.0 version: 9.0.0 @@ -1910,8 +1916,8 @@ importers: specifier: ^15.0.2 version: 15.0.2 nock: - specifier: ^13.3.1 - version: 13.3.1 + specifier: 14.0.0-beta.6 + version: 14.0.0-beta.6 prettier: specifier: ^3.0.0 version: 3.0.0 @@ -1936,18 +1942,21 @@ importers: '@logto/connector-kit': specifier: workspace:^3.0.0 version: link:../../toolkit/connector-kit + '@logto/connector-oauth': + specifier: workspace:^1.2.0 + version: link:../connector-oauth2 '@logto/shared': specifier: workspace:^3.1.0 version: link:../../shared '@silverhand/essentials': specifier: ^2.9.0 version: 2.9.0 - got: - specifier: ^14.0.0 - version: 14.0.0 jose: specifier: ^5.0.0 version: 5.0.1 + ky: + specifier: ^1.2.3 + version: 1.2.3 nanoid: specifier: ^5.0.1 version: 5.0.1 @@ -1992,8 +2001,8 @@ importers: specifier: ^15.0.2 version: 15.0.2 nock: - specifier: ^13.3.1 - version: 13.3.1 + specifier: 14.0.0-beta.6 + version: 14.0.0-beta.6 prettier: specifier: ^3.0.0 version: 3.0.0 @@ -3851,9 +3860,6 @@ importers: '@jest/globals': specifier: ^29.7.0 version: 29.7.0 - '@logto/connector-kit': - specifier: workspace:^3.0.0 - version: link:../toolkit/connector-kit '@silverhand/eslint-config': specifier: 6.0.1 version: 6.0.1(eslint@8.57.0)(prettier@3.0.0)(typescript@5.3.3) @@ -17269,6 +17275,14 @@ packages: propagate: 2.0.1 dev: true + /nock@14.0.0-beta.6: + resolution: {integrity: sha512-b7lc7qvj1dQzxtbU7TqyTMnKbNKwGQd585xsRtcCZOv3I/yOK9Vwv4nOgnLFxFtX9m1yjhQDRbgqFCqNh9HuEw==} + engines: {node: '>= 18'} + dependencies: + json-stringify-safe: 5.0.1 + propagate: 2.0.1 + dev: true + /node-addon-api@3.2.1: resolution: {integrity: sha512-mmcei9JghVNDYydghQmeDX8KoAm0FAiYyIcUt/N4nhyAipB17pllZQDOJD2fotxABnt4Mdz+dKTO7eftLg4d0A==} dev: true From be6fac92b3a16bb62c90f2358a9ad3b521a864b9 Mon Sep 17 00:00:00 2001 From: simeng-li Date: Wed, 24 Apr 2024 18:52:57 +0800 Subject: [PATCH 322/687] chore: ignore the hidden file found zap alert (#5786) ignore the hidden file found zap alert --- .zap/rules.conf | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.zap/rules.conf b/.zap/rules.conf index 395184be14d..22a186b983e 100644 --- a/.zap/rules.conf +++ b/.zap/rules.conf @@ -12,3 +12,6 @@ # The applicationInsights endpoint will be removed 10055 IGNORE (CSP - Wildcard Directive) + +# Experience app is rendered under the root path. No hidden files are exposed. A 404 experience page will be returned. +40035 IGNORE (Hidden File Found - Active/release) From eb7290b0302f6d21626d8af48a2f335dcf44285c Mon Sep 17 00:00:00 2001 From: simeng-li Date: Wed, 24 Apr 2024 19:42:38 +0800 Subject: [PATCH 323/687] fix: fix zap config file (#5788) fix zap config file --- .zap/rules.conf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.zap/rules.conf b/.zap/rules.conf index 22a186b983e..d473f0966ec 100644 --- a/.zap/rules.conf +++ b/.zap/rules.conf @@ -14,4 +14,4 @@ 10055 IGNORE (CSP - Wildcard Directive) # Experience app is rendered under the root path. No hidden files are exposed. A 404 experience page will be returned. -40035 IGNORE (Hidden File Found - Active/release) +40035 IGNORE (Hidden File Found) From 0359cbac0396d31071e623ef4290fbe34ecc7e87 Mon Sep 17 00:00:00 2001 From: simeng-li Date: Wed, 24 Apr 2024 20:41:14 +0800 Subject: [PATCH 324/687] fix: fix zap config file syntax (#5790) fix zap config file syntax --- .zap/rules.conf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.zap/rules.conf b/.zap/rules.conf index d473f0966ec..b19a3b81c41 100644 --- a/.zap/rules.conf +++ b/.zap/rules.conf @@ -14,4 +14,4 @@ 10055 IGNORE (CSP - Wildcard Directive) # Experience app is rendered under the root path. No hidden files are exposed. A 404 experience page will be returned. -40035 IGNORE (Hidden File Found) +40035 IGNORE (Hidden File Found - Active/release) From 09a1b2438d775036fc29fed5de52de167401ca27 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 24 Apr 2024 22:37:30 +0800 Subject: [PATCH 325/687] fix(deps): update dependency tar to v7 (#5678) * fix(deps): update dependency tar to v7 * refactor: fix import --------- Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> Co-authored-by: Gao Sun --- packages/cli/package.json | 2 +- packages/cli/src/commands/connector/utils.ts | 4 +- packages/cli/src/commands/install/utils.ts | 4 +- pnpm-lock.yaml | 151 +++++++++++++------ 4 files changed, 111 insertions(+), 50 deletions(-) diff --git a/packages/cli/package.json b/packages/cli/package.json index aeb0b3943de..2e09797e275 100644 --- a/packages/cli/package.json +++ b/packages/cli/package.json @@ -65,7 +65,7 @@ "pg-protocol": "^1.6.0", "roarr": "^7.11.0", "semver": "^7.3.8", - "tar": "^6.2.1", + "tar": "^7.0.0", "typescript": "^5.3.3", "yargs": "^17.6.0", "zod": "^3.22.4" diff --git a/packages/cli/src/commands/connector/utils.ts b/packages/cli/src/commands/connector/utils.ts index 858dfd4d69f..06c36cbc76b 100644 --- a/packages/cli/src/commands/connector/utils.ts +++ b/packages/cli/src/commands/connector/utils.ts @@ -9,7 +9,7 @@ import chalk from 'chalk'; import { got } from 'got'; import pLimit from 'p-limit'; import pRetry from 'p-retry'; -import tar from 'tar'; +import { extract } from 'tar'; import { z } from 'zod'; import { connectorDirectory, coreDirectory } from '../../constants.js'; @@ -102,7 +102,7 @@ export const addConnectorsToPath = async (cwd: string, packageNames: string[]) = await fs.rm(packageDirectory, { force: true, recursive: true }); await fs.mkdir(packageDirectory, { recursive: true }); - await tar.extract({ cwd: packageDirectory, file: tarPath, strip: 1 }); + await extract({ cwd: packageDirectory, file: tarPath, strip: 1 }); await fs.unlink(tarPath); consoleLog.succeed(`Added ${chalk.green(name)} v${version}`); diff --git a/packages/cli/src/commands/install/utils.ts b/packages/cli/src/commands/install/utils.ts index 0ddd9b7692f..f39d90ec9a8 100644 --- a/packages/cli/src/commands/install/utils.ts +++ b/packages/cli/src/commands/install/utils.ts @@ -9,7 +9,7 @@ import chalk from 'chalk'; import { got, RequestError } from 'got'; import inquirer from 'inquirer'; import * as semver from 'semver'; -import tar from 'tar'; +import { extract } from 'tar'; import { defaultPath } from '../../constants.js'; import { createPoolAndDatabaseIfNeeded } from '../../database.js'; @@ -140,7 +140,7 @@ export const decompress = async (toPath: string, tarPath: string) => { const run = async () => { try { await fs.mkdir(toPath); - await tar.extract({ file: tarPath, cwd: toPath, strip: 1 }); + await extract({ file: tarPath, cwd: toPath, strip: 1 }); } catch (error: unknown) { consoleLog.fatal(error); } diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 17f9cdee912..d3f9faf9bd0 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -152,8 +152,8 @@ importers: specifier: ^7.3.8 version: 7.5.2 tar: - specifier: ^6.2.1 - version: 6.2.1 + specifier: ^7.0.0 + version: 7.0.1 typescript: specifier: ^5.3.3 version: 5.3.3 @@ -6204,6 +6204,25 @@ packages: react: 18.2.0 dev: true + /@isaacs/cliui@8.0.2: + resolution: {integrity: sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==} + engines: {node: '>=12'} + dependencies: + string-width: 5.1.2 + string-width-cjs: /string-width@4.2.3 + strip-ansi: 7.1.0 + strip-ansi-cjs: /strip-ansi@6.0.1 + wrap-ansi: 8.1.0 + wrap-ansi-cjs: /wrap-ansi@7.0.0 + dev: false + + /@isaacs/fs-minipass@4.0.1: + resolution: {integrity: sha512-wgm9Ehl2jpeqP3zw/7mo3kRHFp5MEDhqAdwy1fTGkHAwnkGOVsgpvQhL8B5n1qlb01jV3n/bI0ZfZp5lWA1k4w==} + engines: {node: '>=18.0.0'} + dependencies: + minipass: 7.0.4 + dev: false + /@istanbuljs/load-nyc-config@1.1.0: resolution: {integrity: sha512-VjeHSlIzpv/NyD3N0YuHfXOPDIixcA1q2ZV98wsMqcYlPmv2n3Yb2lYP9XMElnaFVXg5A7YLTeLu6V84uQDjmQ==} engines: {node: '>=8'} @@ -7773,6 +7792,13 @@ packages: tslib: 2.6.2 dev: false + /@pkgjs/parseargs@0.11.0: + resolution: {integrity: sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==} + engines: {node: '>=14'} + requiresBuild: true + dev: false + optional: true + /@pkgr/core@0.1.1: resolution: {integrity: sha512-cq8o4cWH0ibXh9VGi5P20Tu9XF/0fFXl9EUinr9QfTM7a7p0oTA4iJRCQWppXR1Pg8dSM0UCItCkPwsk9qWWYA==} engines: {node: ^12.20.0 || ^14.18.0 || >=16.0.0} @@ -10665,7 +10691,6 @@ packages: /balanced-match@1.0.2: resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==} - dev: true /balanced-match@2.0.0: resolution: {integrity: sha512-1ugUSr8BHXRnK23KfuYS+gVMC3LB8QGH9W1iGtDPsNWoQbgtXSExkBu2aDR4epiGWZOjZsj6lDl/N/AqqTC3UA==} @@ -10764,7 +10789,6 @@ packages: resolution: {integrity: sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==} dependencies: balanced-match: 1.0.2 - dev: true /braces@3.0.2: resolution: {integrity: sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==} @@ -11073,9 +11097,9 @@ packages: fsevents: 2.3.3 dev: true - /chownr@2.0.0: - resolution: {integrity: sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ==} - engines: {node: '>=10'} + /chownr@3.0.0: + resolution: {integrity: sha512-+IxzY9BZOQd/XuYPRmrvEVjF/nqj5kgT4kEq7VofrDoM1MxoRjEWkrCC3EtLi59TVawxTAn+orJwFQcrqEN1+g==} + engines: {node: '>=18'} dev: false /chrome-trace-event@1.0.3: @@ -11549,7 +11573,6 @@ packages: path-key: 3.1.1 shebang-command: 2.0.0 which: 2.0.2 - dev: true /css-functions-list@3.2.1: resolution: {integrity: sha512-Nj5YcaGgBtuUmn1D7oHqPW0c9iui7xsTsj5lIX8ZgevdfhmjFfKB3r8moHJtNJnctnYXJyYX5I1pp90HM4TPgQ==} @@ -13307,6 +13330,14 @@ packages: is-callable: 1.2.7 dev: true + /foreground-child@3.1.1: + resolution: {integrity: sha512-TMKDUnIte6bfb5nWv7V/caI169OHgvwjb7V4WkeUvbQQdjr5rWKqHFiKWb/fcOwB+CzBT+qbWjvj+DVwRskpIg==} + engines: {node: '>=14'} + dependencies: + cross-spawn: 7.0.3 + signal-exit: 4.1.0 + dev: false + /form-data-encoder@2.1.4: resolution: {integrity: sha512-yDYSgNMraqvnxiEXO4hi88+YZxaHC6QKzb5N84iRCTDeRO7ZALpir/lVmf/uXUhnwUr2O4HU8s/n6x+yNjQkHw==} engines: {node: '>= 14.17'} @@ -13382,13 +13413,6 @@ packages: universalify: 0.1.2 dev: true - /fs-minipass@2.1.0: - resolution: {integrity: sha512-V/JgOLFCS+R6Vcq0slCuaeWEdNC3ouDlJMNIsacH2VtALiu9mV4LPrHc5cDl8k5aw6J8jwgWWpiTo5RYhmIzvg==} - engines: {node: '>= 8'} - dependencies: - minipass: 3.3.5 - dev: false - /fs.realpath@1.0.0: resolution: {integrity: sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==} dev: true @@ -13597,6 +13621,18 @@ packages: is-glob: 4.0.3 dev: true + /glob@10.3.12: + resolution: {integrity: sha512-TCNv8vJ+xz4QiqTpfOJA7HvYv+tNIRHKfUWw/q+v2jdgN4ebz+KY9tGx5J4rHP0o84mNP+ApH66HRX8us3Khqg==} + engines: {node: '>=16 || 14 >=14.17'} + hasBin: true + dependencies: + foreground-child: 3.1.1 + jackspeak: 2.3.6 + minimatch: 9.0.4 + minipass: 7.0.4 + path-scurry: 1.10.2 + dev: false + /glob@7.2.3: resolution: {integrity: sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==} dependencies: @@ -14795,7 +14831,6 @@ packages: /isexe@2.0.0: resolution: {integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==} - dev: true /iso8601-duration@2.1.2: resolution: {integrity: sha512-yXteYUiKv6x8seaDzyBwnZtPpmx766KfvQuaVNyPifYOjmPdOo3ajd4phDNa7Y5mTQGnXsNEcXFtVun1FjYXxQ==} @@ -14880,6 +14915,15 @@ packages: set-function-name: 2.0.2 dev: true + /jackspeak@2.3.6: + resolution: {integrity: sha512-N3yCS/NegsOBokc8GAdM8UcmfsKiSS8cipheD/nivzr700H+nsMOxJjQnvwOcRYVuFkdH0wGUvW2WbXGmrZGbQ==} + engines: {node: '>=14'} + dependencies: + '@isaacs/cliui': 8.0.2 + optionalDependencies: + '@pkgjs/parseargs': 0.11.0 + dev: false + /jest-changed-files@29.7.0: resolution: {integrity: sha512-fEArFiwf1BpQ+4bXSprcDc3/x4HSzL4al2tozwVpDFpsxALjLYdyiIK4e5Vz66GQJIbXJ82+35PtysofptNX2w==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} @@ -16440,6 +16484,11 @@ packages: engines: {node: 14 || >=16.14} dev: false + /lru-cache@10.2.0: + resolution: {integrity: sha512-2bIM8x+VAf6JT4bKAljS1qUWgMsqZRPGJS6FSahIMPVvctcNhyVp7AJu7quxOW9jwkryBReKZY5tY5JYv2n/7Q==} + engines: {node: 14 || >=16.14} + dev: false + /lru-cache@4.1.5: resolution: {integrity: sha512-sWZlbEP2OsHNkXrMl5GYk/jKk70MBng6UU4YI/qGDYbgf6YbP4EvmqISbXCoJiRKs+1bSpFHVgQxvJ17F2li5g==} dependencies: @@ -17089,7 +17138,6 @@ packages: engines: {node: '>=16 || 14 >=14.17'} dependencies: brace-expansion: 2.0.1 - dev: true /minimist-options@4.1.0: resolution: {integrity: sha512-Q4r8ghd80yhO/0j1O3B2BjweX3fiHg9cdOwjJd2J76Q135c+NDxGCqdYKQ1SKBuFfgWbAUzBfvYjPUEeNgqN1A==} @@ -17104,13 +17152,6 @@ packages: resolution: {integrity: sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==} dev: true - /minipass@3.3.5: - resolution: {integrity: sha512-rQ/p+KfKBkeNwo04U15i+hOwoVBVmekmm/HcfTkTN2t9pbQKCMm4eN5gFeqgrrSp/kH/7BYYhTIHOxGqzbBPaA==} - engines: {node: '>=8'} - dependencies: - yallist: 4.0.0 - dev: false - /minipass@4.2.8: resolution: {integrity: sha512-fNzuVyifolSLFL4NzpF+wEF4qrgqaaKX0haXPQEdQ7NKAN+WecoKMHV09YcuL/DHxrUsYQOK3MiuDf7Ip2OXfQ==} engines: {node: '>=8'} @@ -17121,12 +17162,17 @@ packages: engines: {node: '>=8'} dev: false - /minizlib@2.1.2: - resolution: {integrity: sha512-bAxsR8BVfj60DWXHE3u30oHzfl4G7khkSuPW+qvpd7jFRHm7dLxOjUk1EHACJ/hxLY8phGJ0YhYHZo7jil7Qdg==} - engines: {node: '>= 8'} + /minipass@7.0.4: + resolution: {integrity: sha512-jYofLM5Dam9279rdkWzqHozUo4ybjdZmCsDHePy5V/PbBcVMiSZR97gmAy45aqi8CK1lG2ECd356FU86avfwUQ==} + engines: {node: '>=16 || 14 >=14.17'} + dev: false + + /minizlib@3.0.1: + resolution: {integrity: sha512-umcy022ILvb5/3Djuu8LWeqUa8D68JaBzlttKeMWen48SjabqS3iY5w/vzeMzMUNhLDifyhbOwKDSznB1vvrwg==} + engines: {node: '>= 18'} dependencies: - minipass: 3.3.5 - yallist: 4.0.0 + minipass: 7.0.4 + rimraf: 5.0.5 dev: false /mitt@3.0.1: @@ -17138,8 +17184,8 @@ packages: engines: {node: '>= 8.0.0'} dev: true - /mkdirp@1.0.4: - resolution: {integrity: sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==} + /mkdirp@3.0.1: + resolution: {integrity: sha512-+NsyUUAZDmo6YVHzL/stxSu3t9YS1iljliy3BSDrXJ/dkn1KYdmtZODGGjLcc9XLgVVpH4KshHB8XmZgMhaBXg==} engines: {node: '>=10'} hasBin: true dev: false @@ -17948,7 +17994,6 @@ packages: /path-key@3.1.1: resolution: {integrity: sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==} engines: {node: '>=8'} - dev: true /path-key@4.0.0: resolution: {integrity: sha512-haREypq7xkM7ErfgIyA0z+Bj4AGKlMSdlQE2jvJo6huWD1EdkKYV+G/T4nq0YEF2vgTT8kqMFKo1uHn950r4SQ==} @@ -17965,6 +18010,14 @@ packages: /path-parse@1.0.7: resolution: {integrity: sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==} + /path-scurry@1.10.2: + resolution: {integrity: sha512-7xTavNy5RQXnsjANvVvMkEjvloOinkAjv/Z6Ildz9v2RinZ4SBKTWFOVRbaF8p0vpHnyjV/UwNDdKuUv6M5qcA==} + engines: {node: '>=16 || 14 >=14.17'} + dependencies: + lru-cache: 10.2.0 + minipass: 7.0.4 + dev: false + /path-to-regexp@1.8.0: resolution: {integrity: sha512-n43JRhlUKUAlibEJhPeir1ncUID16QnEjNpwzNdO3Lm4ywrBpBZ5oLD0I6br9evr1Y9JTqwRtAh7JLoOzAQdVA==} dependencies: @@ -19452,6 +19505,14 @@ packages: glob: 7.2.3 dev: true + /rimraf@5.0.5: + resolution: {integrity: sha512-CqDakW+hMe/Bz202FPEymy68P+G50RfMQK+Qo5YUqc9SPipvbGjCGKd0RSKEelbsfQuw3g5NZDSrlZZAJurH1A==} + engines: {node: '>=14'} + hasBin: true + dependencies: + glob: 10.3.12 + dev: false + /roarr@7.11.0: resolution: {integrity: sha512-DKiMaEYHoOZ0JyD4Ohr5KRnqybQ162s3ZL/WNO9oy6EUszYvpp0eLYJErc/U4NI96HYnHsbROhFaH4LYuJPnDg==} engines: {node: '>=12.0'} @@ -19712,7 +19773,6 @@ packages: engines: {node: '>=8'} dependencies: shebang-regex: 3.0.0 - dev: true /shebang-regex@1.0.0: resolution: {integrity: sha512-wpoSFAxys6b2a2wHZ1XpDSgD7N9iVjg29Ph9uV/uaP9Ex/KXlkTZTeddxDPSYQpgvzKLGJke2UU0AzoGCjNIvQ==} @@ -19722,7 +19782,6 @@ packages: /shebang-regex@3.0.0: resolution: {integrity: sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==} engines: {node: '>=8'} - dev: true /shell-quote@1.7.3: resolution: {integrity: sha512-Vpfqwm4EnqGdlsBFNmHhxhElJYrdfcxPThu+ryKS5J8L/fhAwLazFZtq+S+TWZ9ANj2piSQLGj6NQg+lKPmxrw==} @@ -19759,7 +19818,6 @@ packages: /signal-exit@4.1.0: resolution: {integrity: sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==} engines: {node: '>=14'} - dev: true /simple-swizzle@0.2.2: resolution: {integrity: sha512-JA//kQgZtbuY83m+xT+tXJkmJncGMTFT+C+g2h2R9uxkYIrE2yy9sgmcLhCnw57/WSD+Eh3J97FPEDFnbXnDUg==} @@ -20481,16 +20539,16 @@ packages: streamx: 2.15.1 dev: true - /tar@6.2.1: - resolution: {integrity: sha512-DZ4yORTwrbTj/7MZYq2w+/ZFdI6OZ/f9SFHR+71gIVUZhOQPHzVCLpvRnPgyaMpfWxxk/4ONva3GQSyNIKRv6A==} - engines: {node: '>=10'} + /tar@7.0.1: + resolution: {integrity: sha512-IjMhdQMZFpKsHEQT3woZVxBtCQY+0wk3CVxdRkGXEgyGa0dNS/ehPvOMr2nmfC7x5Zj2N+l6yZUpmICjLGS35w==} + engines: {node: '>=18'} dependencies: - chownr: 2.0.0 - fs-minipass: 2.1.0 + '@isaacs/fs-minipass': 4.0.1 + chownr: 3.0.0 minipass: 5.0.0 - minizlib: 2.1.2 - mkdirp: 1.0.4 - yallist: 4.0.0 + minizlib: 3.0.1 + mkdirp: 3.0.1 + yallist: 5.0.0 dev: false /teeny-request@9.0.0: @@ -21581,7 +21639,6 @@ packages: hasBin: true dependencies: isexe: 2.0.0 - dev: true /why-is-node-running@2.2.2: resolution: {integrity: sha512-6tSwToZxTOcotxHeA+qGCq1mVzKR3CwcJGmVcY+QE8SHy6TnpFnh8PAvPNHYr7EcuVeG0QSMxtYCuO1ta/G/oA==} @@ -21629,7 +21686,6 @@ packages: ansi-styles: 6.2.1 string-width: 5.1.2 strip-ansi: 7.1.0 - dev: true /wrappy@1.0.2: resolution: {integrity: sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==} @@ -21732,6 +21788,11 @@ packages: /yallist@4.0.0: resolution: {integrity: sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==} + /yallist@5.0.0: + resolution: {integrity: sha512-YgvUTfwqyc7UXVMrB+SImsVYSmTS8X/tSrtdNZMImM+n7+QTriRXyXim0mBrTXNeqzVF0KWGgHPeiyViFFrNDw==} + engines: {node: '>=18'} + dev: false + /yaml@1.10.2: resolution: {integrity: sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg==} engines: {node: '>= 6'} From 61e20940fe9472f1450d4650c4f23645965e9586 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 25 Apr 2024 11:53:00 +0800 Subject: [PATCH 326/687] chore(deps): update dependency supertest to v7 (#5791) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- .../connector-alipay-native/package.json | 2 +- .../connector-alipay-web/package.json | 2 +- .../connector-aliyun-dm/package.json | 2 +- .../connector-aliyun-sms/package.json | 2 +- .../connectors/connector-apple/package.json | 2 +- .../connectors/connector-aws-ses/package.json | 2 +- .../connectors/connector-azuread/package.json | 2 +- .../connectors/connector-discord/package.json | 2 +- .../connector-facebook/package.json | 2 +- .../connector-feishu-web/package.json | 2 +- .../connectors/connector-github/package.json | 2 +- .../connectors/connector-google/package.json | 2 +- .../connectors/connector-kakao/package.json | 2 +- .../connector-logto-email/package.json | 2 +- .../connector-logto-sms/package.json | 2 +- .../connector-logto-social-demo/package.json | 2 +- .../connectors/connector-mailgun/package.json | 2 +- .../package.json | 2 +- .../connector-mock-email/package.json | 2 +- .../connector-mock-sms/package.json | 2 +- .../connector-mock-social/package.json | 2 +- .../connectors/connector-naver/package.json | 2 +- .../connectors/connector-oauth2/package.json | 2 +- .../connectors/connector-oidc/package.json | 2 +- .../connectors/connector-saml/package.json | 2 +- .../connector-sendgrid-email/package.json | 2 +- .../connectors/connector-smsaero/package.json | 2 +- .../connectors/connector-smtp/package.json | 2 +- .../connector-tencent-sms/package.json | 2 +- .../connector-twilio-sms/package.json | 2 +- .../connector-wechat-native/package.json | 2 +- .../connector-wechat-web/package.json | 2 +- .../connectors/connector-wecom/package.json | 2 +- packages/core/package.json | 2 +- pnpm-lock.yaml | 223 ++++++++---------- 35 files changed, 132 insertions(+), 159 deletions(-) diff --git a/packages/connectors/connector-alipay-native/package.json b/packages/connectors/connector-alipay-native/package.json index 0a3c8841693..84227e3f274 100644 --- a/packages/connectors/connector-alipay-native/package.json +++ b/packages/connectors/connector-alipay-native/package.json @@ -29,7 +29,7 @@ "prettier": "^3.0.0", "rollup": "^4.12.0", "rollup-plugin-output-size": "^1.3.0", - "supertest": "^6.3.4", + "supertest": "^7.0.0", "typescript": "^5.3.3", "vitest": "^1.4.0" }, diff --git a/packages/connectors/connector-alipay-web/package.json b/packages/connectors/connector-alipay-web/package.json index a97573a74dd..b65a156b7d0 100644 --- a/packages/connectors/connector-alipay-web/package.json +++ b/packages/connectors/connector-alipay-web/package.json @@ -28,7 +28,7 @@ "prettier": "^3.0.0", "rollup": "^4.12.0", "rollup-plugin-output-size": "^1.3.0", - "supertest": "^6.3.4", + "supertest": "^7.0.0", "typescript": "^5.3.3", "vitest": "^1.4.0" }, diff --git a/packages/connectors/connector-aliyun-dm/package.json b/packages/connectors/connector-aliyun-dm/package.json index 0f496e558c2..9f3ee0b478e 100644 --- a/packages/connectors/connector-aliyun-dm/package.json +++ b/packages/connectors/connector-aliyun-dm/package.json @@ -66,7 +66,7 @@ "prettier": "^3.0.0", "rollup": "^4.12.0", "rollup-plugin-output-size": "^1.3.0", - "supertest": "^6.3.4", + "supertest": "^7.0.0", "typescript": "^5.3.3", "vitest": "^1.4.0" } diff --git a/packages/connectors/connector-aliyun-sms/package.json b/packages/connectors/connector-aliyun-sms/package.json index 1db260eaee3..f8bd264496d 100644 --- a/packages/connectors/connector-aliyun-sms/package.json +++ b/packages/connectors/connector-aliyun-sms/package.json @@ -66,7 +66,7 @@ "prettier": "^3.0.0", "rollup": "^4.12.0", "rollup-plugin-output-size": "^1.3.0", - "supertest": "^6.3.4", + "supertest": "^7.0.0", "typescript": "^5.3.3", "vitest": "^1.4.0" } diff --git a/packages/connectors/connector-apple/package.json b/packages/connectors/connector-apple/package.json index 555447d29ea..64da97b4b6f 100644 --- a/packages/connectors/connector-apple/package.json +++ b/packages/connectors/connector-apple/package.json @@ -68,7 +68,7 @@ "prettier": "^3.0.0", "rollup": "^4.12.0", "rollup-plugin-output-size": "^1.3.0", - "supertest": "^6.3.4", + "supertest": "^7.0.0", "typescript": "^5.3.3", "vitest": "^1.4.0" } diff --git a/packages/connectors/connector-aws-ses/package.json b/packages/connectors/connector-aws-ses/package.json index 60aa9ad5369..397fd55d50e 100644 --- a/packages/connectors/connector-aws-ses/package.json +++ b/packages/connectors/connector-aws-ses/package.json @@ -69,7 +69,7 @@ "prettier": "^3.0.0", "rollup": "^4.12.0", "rollup-plugin-output-size": "^1.3.0", - "supertest": "^6.3.4", + "supertest": "^7.0.0", "typescript": "^5.3.3", "vitest": "^1.4.0" } diff --git a/packages/connectors/connector-azuread/package.json b/packages/connectors/connector-azuread/package.json index b17b2e157ba..ec941edc84a 100644 --- a/packages/connectors/connector-azuread/package.json +++ b/packages/connectors/connector-azuread/package.json @@ -68,7 +68,7 @@ "prettier": "^3.0.0", "rollup": "^4.12.0", "rollup-plugin-output-size": "^1.3.0", - "supertest": "^6.3.4", + "supertest": "^7.0.0", "typescript": "^5.3.3", "vitest": "^1.4.0" } diff --git a/packages/connectors/connector-discord/package.json b/packages/connectors/connector-discord/package.json index a286ca321fd..0d585c35ed0 100644 --- a/packages/connectors/connector-discord/package.json +++ b/packages/connectors/connector-discord/package.json @@ -67,7 +67,7 @@ "prettier": "^3.0.0", "rollup": "^4.12.0", "rollup-plugin-output-size": "^1.3.0", - "supertest": "^6.3.4", + "supertest": "^7.0.0", "typescript": "^5.3.3", "vitest": "^1.4.0" } diff --git a/packages/connectors/connector-facebook/package.json b/packages/connectors/connector-facebook/package.json index 788e6cb3c9d..a9adc562727 100644 --- a/packages/connectors/connector-facebook/package.json +++ b/packages/connectors/connector-facebook/package.json @@ -67,7 +67,7 @@ "prettier": "^3.0.0", "rollup": "^4.12.0", "rollup-plugin-output-size": "^1.3.0", - "supertest": "^6.3.4", + "supertest": "^7.0.0", "typescript": "^5.3.3", "vitest": "^1.4.0" } diff --git a/packages/connectors/connector-feishu-web/package.json b/packages/connectors/connector-feishu-web/package.json index 027aa8a5a3f..50bc45c13b0 100644 --- a/packages/connectors/connector-feishu-web/package.json +++ b/packages/connectors/connector-feishu-web/package.json @@ -67,7 +67,7 @@ "prettier": "^3.0.0", "rollup": "^4.12.0", "rollup-plugin-output-size": "^1.3.0", - "supertest": "^6.3.4", + "supertest": "^7.0.0", "typescript": "^5.3.3", "vitest": "^1.4.0" } diff --git a/packages/connectors/connector-github/package.json b/packages/connectors/connector-github/package.json index e5a353bcef3..b0e35afbd78 100644 --- a/packages/connectors/connector-github/package.json +++ b/packages/connectors/connector-github/package.json @@ -68,7 +68,7 @@ "prettier": "^3.0.0", "rollup": "^4.12.0", "rollup-plugin-output-size": "^1.3.0", - "supertest": "^6.3.4", + "supertest": "^7.0.0", "typescript": "^5.3.3", "vitest": "^1.4.0" } diff --git a/packages/connectors/connector-google/package.json b/packages/connectors/connector-google/package.json index 63d236552e1..a837908f041 100644 --- a/packages/connectors/connector-google/package.json +++ b/packages/connectors/connector-google/package.json @@ -67,7 +67,7 @@ "prettier": "^3.0.0", "rollup": "^4.12.0", "rollup-plugin-output-size": "^1.3.0", - "supertest": "^6.3.4", + "supertest": "^7.0.0", "typescript": "^5.3.3", "vitest": "^1.4.0" } diff --git a/packages/connectors/connector-kakao/package.json b/packages/connectors/connector-kakao/package.json index 98d1e9c80ab..af1be48d8c5 100644 --- a/packages/connectors/connector-kakao/package.json +++ b/packages/connectors/connector-kakao/package.json @@ -67,7 +67,7 @@ "prettier": "^3.0.0", "rollup": "^4.12.0", "rollup-plugin-output-size": "^1.3.0", - "supertest": "^6.3.4", + "supertest": "^7.0.0", "typescript": "^5.3.3", "vitest": "^1.4.0" } diff --git a/packages/connectors/connector-logto-email/package.json b/packages/connectors/connector-logto-email/package.json index 00b99415472..8ecae3af35f 100644 --- a/packages/connectors/connector-logto-email/package.json +++ b/packages/connectors/connector-logto-email/package.json @@ -68,7 +68,7 @@ "prettier": "^3.0.0", "rollup": "^4.12.0", "rollup-plugin-output-size": "^1.3.0", - "supertest": "^6.3.4", + "supertest": "^7.0.0", "typescript": "^5.3.3", "vitest": "^1.4.0" } diff --git a/packages/connectors/connector-logto-sms/package.json b/packages/connectors/connector-logto-sms/package.json index 4220ff24172..aa97290af74 100644 --- a/packages/connectors/connector-logto-sms/package.json +++ b/packages/connectors/connector-logto-sms/package.json @@ -67,7 +67,7 @@ "prettier": "^3.0.0", "rollup": "^4.12.0", "rollup-plugin-output-size": "^1.3.0", - "supertest": "^6.3.4", + "supertest": "^7.0.0", "typescript": "^5.3.3", "vitest": "^1.4.0" } diff --git a/packages/connectors/connector-logto-social-demo/package.json b/packages/connectors/connector-logto-social-demo/package.json index 7bb675b2c38..3434cd239c2 100644 --- a/packages/connectors/connector-logto-social-demo/package.json +++ b/packages/connectors/connector-logto-social-demo/package.json @@ -67,7 +67,7 @@ "prettier": "^3.0.0", "rollup": "^4.12.0", "rollup-plugin-output-size": "^1.3.0", - "supertest": "^6.3.4", + "supertest": "^7.0.0", "typescript": "^5.3.3", "vitest": "^1.4.0" } diff --git a/packages/connectors/connector-mailgun/package.json b/packages/connectors/connector-mailgun/package.json index 1d7d4dee09a..4ae0879adde 100644 --- a/packages/connectors/connector-mailgun/package.json +++ b/packages/connectors/connector-mailgun/package.json @@ -67,7 +67,7 @@ "prettier": "^3.0.0", "rollup": "^4.12.0", "rollup-plugin-output-size": "^1.3.0", - "supertest": "^6.3.4", + "supertest": "^7.0.0", "typescript": "^5.3.3", "vitest": "^1.4.0" } diff --git a/packages/connectors/connector-mock-email-alternative/package.json b/packages/connectors/connector-mock-email-alternative/package.json index ef2cc2b4b61..665d563c533 100644 --- a/packages/connectors/connector-mock-email-alternative/package.json +++ b/packages/connectors/connector-mock-email-alternative/package.json @@ -67,7 +67,7 @@ "prettier": "^3.0.0", "rollup": "^4.12.0", "rollup-plugin-output-size": "^1.3.0", - "supertest": "^6.3.4", + "supertest": "^7.0.0", "typescript": "^5.3.3", "vitest": "^1.4.0" } diff --git a/packages/connectors/connector-mock-email/package.json b/packages/connectors/connector-mock-email/package.json index 23b22a2fdbf..e5115863583 100644 --- a/packages/connectors/connector-mock-email/package.json +++ b/packages/connectors/connector-mock-email/package.json @@ -67,7 +67,7 @@ "prettier": "^3.0.0", "rollup": "^4.12.0", "rollup-plugin-output-size": "^1.3.0", - "supertest": "^6.3.4", + "supertest": "^7.0.0", "typescript": "^5.3.3", "vitest": "^1.4.0" } diff --git a/packages/connectors/connector-mock-sms/package.json b/packages/connectors/connector-mock-sms/package.json index 5334736a548..b495e3a8c5e 100644 --- a/packages/connectors/connector-mock-sms/package.json +++ b/packages/connectors/connector-mock-sms/package.json @@ -67,7 +67,7 @@ "prettier": "^3.0.0", "rollup": "^4.12.0", "rollup-plugin-output-size": "^1.3.0", - "supertest": "^6.3.4", + "supertest": "^7.0.0", "typescript": "^5.3.3", "vitest": "^1.4.0" } diff --git a/packages/connectors/connector-mock-social/package.json b/packages/connectors/connector-mock-social/package.json index 50e58345c38..3ed7a26b15a 100644 --- a/packages/connectors/connector-mock-social/package.json +++ b/packages/connectors/connector-mock-social/package.json @@ -67,7 +67,7 @@ "prettier": "^3.0.0", "rollup": "^4.12.0", "rollup-plugin-output-size": "^1.3.0", - "supertest": "^6.3.4", + "supertest": "^7.0.0", "typescript": "^5.3.3", "vitest": "^1.4.0" } diff --git a/packages/connectors/connector-naver/package.json b/packages/connectors/connector-naver/package.json index 1668372c023..0de8c44c93f 100644 --- a/packages/connectors/connector-naver/package.json +++ b/packages/connectors/connector-naver/package.json @@ -67,7 +67,7 @@ "prettier": "^3.0.0", "rollup": "^4.12.0", "rollup-plugin-output-size": "^1.3.0", - "supertest": "^6.3.4", + "supertest": "^7.0.0", "typescript": "^5.3.3", "vitest": "^1.4.0" } diff --git a/packages/connectors/connector-oauth2/package.json b/packages/connectors/connector-oauth2/package.json index 0112f67ec51..f360e9382ec 100644 --- a/packages/connectors/connector-oauth2/package.json +++ b/packages/connectors/connector-oauth2/package.json @@ -70,7 +70,7 @@ "prettier": "^3.0.0", "rollup": "^4.12.0", "rollup-plugin-output-size": "^1.3.0", - "supertest": "^6.3.4", + "supertest": "^7.0.0", "typescript": "^5.3.3", "vitest": "^1.4.0" } diff --git a/packages/connectors/connector-oidc/package.json b/packages/connectors/connector-oidc/package.json index d605f729d69..41ee8d68fa5 100644 --- a/packages/connectors/connector-oidc/package.json +++ b/packages/connectors/connector-oidc/package.json @@ -70,7 +70,7 @@ "prettier": "^3.0.0", "rollup": "^4.12.0", "rollup-plugin-output-size": "^1.3.0", - "supertest": "^6.3.4", + "supertest": "^7.0.0", "typescript": "^5.3.3", "vitest": "^1.4.0" } diff --git a/packages/connectors/connector-saml/package.json b/packages/connectors/connector-saml/package.json index af9800e0e26..3161db135d4 100644 --- a/packages/connectors/connector-saml/package.json +++ b/packages/connectors/connector-saml/package.json @@ -69,7 +69,7 @@ "prettier": "^3.0.0", "rollup": "^4.12.0", "rollup-plugin-output-size": "^1.3.0", - "supertest": "^6.3.4", + "supertest": "^7.0.0", "typescript": "^5.3.3", "vitest": "^1.4.0" } diff --git a/packages/connectors/connector-sendgrid-email/package.json b/packages/connectors/connector-sendgrid-email/package.json index 15ca0184df3..393fe20450e 100644 --- a/packages/connectors/connector-sendgrid-email/package.json +++ b/packages/connectors/connector-sendgrid-email/package.json @@ -67,7 +67,7 @@ "prettier": "^3.0.0", "rollup": "^4.12.0", "rollup-plugin-output-size": "^1.3.0", - "supertest": "^6.3.4", + "supertest": "^7.0.0", "typescript": "^5.3.3", "vitest": "^1.4.0" } diff --git a/packages/connectors/connector-smsaero/package.json b/packages/connectors/connector-smsaero/package.json index 69fb8b4a8b3..65477b45b71 100644 --- a/packages/connectors/connector-smsaero/package.json +++ b/packages/connectors/connector-smsaero/package.json @@ -67,7 +67,7 @@ "prettier": "^3.0.0", "rollup": "^4.12.0", "rollup-plugin-output-size": "^1.3.0", - "supertest": "^6.3.4", + "supertest": "^7.0.0", "typescript": "^5.3.3", "vitest": "^1.4.0" } diff --git a/packages/connectors/connector-smtp/package.json b/packages/connectors/connector-smtp/package.json index cf3b55f659a..a9364a07905 100644 --- a/packages/connectors/connector-smtp/package.json +++ b/packages/connectors/connector-smtp/package.json @@ -28,7 +28,7 @@ "prettier": "^3.0.0", "rollup": "^4.12.0", "rollup-plugin-output-size": "^1.3.0", - "supertest": "^6.3.4", + "supertest": "^7.0.0", "typescript": "^5.3.3", "vitest": "^1.4.0" }, diff --git a/packages/connectors/connector-tencent-sms/package.json b/packages/connectors/connector-tencent-sms/package.json index 9588a766b82..02bcb8b9509 100644 --- a/packages/connectors/connector-tencent-sms/package.json +++ b/packages/connectors/connector-tencent-sms/package.json @@ -67,7 +67,7 @@ "prettier": "^3.0.0", "rollup": "^4.12.0", "rollup-plugin-output-size": "^1.3.0", - "supertest": "^6.3.4", + "supertest": "^7.0.0", "typescript": "^5.3.3", "vitest": "^1.4.0" } diff --git a/packages/connectors/connector-twilio-sms/package.json b/packages/connectors/connector-twilio-sms/package.json index bc657ba8758..8a1bcfc6091 100644 --- a/packages/connectors/connector-twilio-sms/package.json +++ b/packages/connectors/connector-twilio-sms/package.json @@ -67,7 +67,7 @@ "prettier": "^3.0.0", "rollup": "^4.12.0", "rollup-plugin-output-size": "^1.3.0", - "supertest": "^6.3.4", + "supertest": "^7.0.0", "typescript": "^5.3.3", "vitest": "^1.4.0" } diff --git a/packages/connectors/connector-wechat-native/package.json b/packages/connectors/connector-wechat-native/package.json index b082fe5ae06..4a1a319895d 100644 --- a/packages/connectors/connector-wechat-native/package.json +++ b/packages/connectors/connector-wechat-native/package.json @@ -67,7 +67,7 @@ "prettier": "^3.0.0", "rollup": "^4.12.0", "rollup-plugin-output-size": "^1.3.0", - "supertest": "^6.3.4", + "supertest": "^7.0.0", "typescript": "^5.3.3", "vitest": "^1.4.0" } diff --git a/packages/connectors/connector-wechat-web/package.json b/packages/connectors/connector-wechat-web/package.json index 640a20d831e..50c54bf2af5 100644 --- a/packages/connectors/connector-wechat-web/package.json +++ b/packages/connectors/connector-wechat-web/package.json @@ -67,7 +67,7 @@ "prettier": "^3.0.0", "rollup": "^4.12.0", "rollup-plugin-output-size": "^1.3.0", - "supertest": "^6.3.4", + "supertest": "^7.0.0", "typescript": "^5.3.3", "vitest": "^1.4.0" } diff --git a/packages/connectors/connector-wecom/package.json b/packages/connectors/connector-wecom/package.json index bc6e24955f7..4510fcc46d6 100644 --- a/packages/connectors/connector-wecom/package.json +++ b/packages/connectors/connector-wecom/package.json @@ -67,7 +67,7 @@ "prettier": "^3.0.0", "rollup": "^4.12.0", "rollup-plugin-output-size": "^1.3.0", - "supertest": "^6.3.4", + "supertest": "^7.0.0", "typescript": "^5.3.3", "vitest": "^1.4.0" } diff --git a/packages/core/package.json b/packages/core/package.json index 312040d0b83..96d9968a9fa 100644 --- a/packages/core/package.json +++ b/packages/core/package.json @@ -122,7 +122,7 @@ "nodemon": "^3.0.0", "prettier": "^3.0.0", "sinon": "^17.0.0", - "supertest": "^6.3.4", + "supertest": "^7.0.0", "typescript": "^5.3.3" }, "engines": { diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index d3f9faf9bd0..b8e4f967a40 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -283,8 +283,8 @@ importers: specifier: ^1.3.0 version: 1.3.0(rollup@4.12.0) supertest: - specifier: ^6.3.4 - version: 6.3.4 + specifier: ^7.0.0 + version: 7.0.0 typescript: specifier: ^5.3.3 version: 5.3.3 @@ -365,8 +365,8 @@ importers: specifier: ^1.3.0 version: 1.3.0(rollup@4.12.0) supertest: - specifier: ^6.3.4 - version: 6.3.4 + specifier: ^7.0.0 + version: 7.0.0 typescript: specifier: ^5.3.3 version: 5.3.3 @@ -438,8 +438,8 @@ importers: specifier: ^1.3.0 version: 1.3.0(rollup@4.12.0) supertest: - specifier: ^6.3.4 - version: 6.3.4 + specifier: ^7.0.0 + version: 7.0.0 typescript: specifier: ^5.3.3 version: 5.3.3 @@ -511,8 +511,8 @@ importers: specifier: ^1.3.0 version: 1.3.0(rollup@4.12.0) supertest: - specifier: ^6.3.4 - version: 6.3.4 + specifier: ^7.0.0 + version: 7.0.0 typescript: specifier: ^5.3.3 version: 5.3.3 @@ -590,8 +590,8 @@ importers: specifier: ^1.3.0 version: 1.3.0(rollup@4.12.0) supertest: - specifier: ^6.3.4 - version: 6.3.4 + specifier: ^7.0.0 + version: 7.0.0 typescript: specifier: ^5.3.3 version: 5.3.3 @@ -669,8 +669,8 @@ importers: specifier: ^1.3.0 version: 1.3.0(rollup@4.12.0) supertest: - specifier: ^6.3.4 - version: 6.3.4 + specifier: ^7.0.0 + version: 7.0.0 typescript: specifier: ^5.3.3 version: 5.3.3 @@ -745,8 +745,8 @@ importers: specifier: ^1.3.0 version: 1.3.0(rollup@4.12.0) supertest: - specifier: ^6.3.4 - version: 6.3.4 + specifier: ^7.0.0 + version: 7.0.0 typescript: specifier: ^5.3.3 version: 5.3.3 @@ -818,8 +818,8 @@ importers: specifier: ^1.3.0 version: 1.3.0(rollup@4.12.0) supertest: - specifier: ^6.3.4 - version: 6.3.4 + specifier: ^7.0.0 + version: 7.0.0 typescript: specifier: ^5.3.3 version: 5.3.3 @@ -891,8 +891,8 @@ importers: specifier: ^1.3.0 version: 1.3.0(rollup@4.12.0) supertest: - specifier: ^6.3.4 - version: 6.3.4 + specifier: ^7.0.0 + version: 7.0.0 typescript: specifier: ^5.3.3 version: 5.3.3 @@ -964,8 +964,8 @@ importers: specifier: ^1.3.0 version: 1.3.0(rollup@4.12.0) supertest: - specifier: ^6.3.4 - version: 6.3.4 + specifier: ^7.0.0 + version: 7.0.0 typescript: specifier: ^5.3.3 version: 5.3.3 @@ -1040,8 +1040,8 @@ importers: specifier: ^1.3.0 version: 1.3.0(rollup@4.12.0) supertest: - specifier: ^6.3.4 - version: 6.3.4 + specifier: ^7.0.0 + version: 7.0.0 typescript: specifier: ^5.3.3 version: 5.3.3 @@ -1113,8 +1113,8 @@ importers: specifier: ^1.3.0 version: 1.3.0(rollup@4.12.0) supertest: - specifier: ^6.3.4 - version: 6.3.4 + specifier: ^7.0.0 + version: 7.0.0 typescript: specifier: ^5.3.3 version: 5.3.3 @@ -1186,8 +1186,8 @@ importers: specifier: ^1.3.0 version: 1.3.0(rollup@4.12.0) supertest: - specifier: ^6.3.4 - version: 6.3.4 + specifier: ^7.0.0 + version: 7.0.0 typescript: specifier: ^5.3.3 version: 5.3.3 @@ -1262,8 +1262,8 @@ importers: specifier: ^1.3.0 version: 1.3.0(rollup@4.12.0) supertest: - specifier: ^6.3.4 - version: 6.3.4 + specifier: ^7.0.0 + version: 7.0.0 typescript: specifier: ^5.3.3 version: 5.3.3 @@ -1335,8 +1335,8 @@ importers: specifier: ^1.3.0 version: 1.3.0(rollup@4.12.0) supertest: - specifier: ^6.3.4 - version: 6.3.4 + specifier: ^7.0.0 + version: 7.0.0 typescript: specifier: ^5.3.3 version: 5.3.3 @@ -1408,8 +1408,8 @@ importers: specifier: ^1.3.0 version: 1.3.0(rollup@4.12.0) supertest: - specifier: ^6.3.4 - version: 6.3.4 + specifier: ^7.0.0 + version: 7.0.0 typescript: specifier: ^5.3.3 version: 5.3.3 @@ -1481,8 +1481,8 @@ importers: specifier: ^1.3.0 version: 1.3.0(rollup@4.12.0) supertest: - specifier: ^6.3.4 - version: 6.3.4 + specifier: ^7.0.0 + version: 7.0.0 typescript: specifier: ^5.3.3 version: 5.3.3 @@ -1554,8 +1554,8 @@ importers: specifier: ^1.3.0 version: 1.3.0(rollup@4.12.0) supertest: - specifier: ^6.3.4 - version: 6.3.4 + specifier: ^7.0.0 + version: 7.0.0 typescript: specifier: ^5.3.3 version: 5.3.3 @@ -1627,8 +1627,8 @@ importers: specifier: ^1.3.0 version: 1.3.0(rollup@4.12.0) supertest: - specifier: ^6.3.4 - version: 6.3.4 + specifier: ^7.0.0 + version: 7.0.0 typescript: specifier: ^5.3.3 version: 5.3.3 @@ -1700,8 +1700,8 @@ importers: specifier: ^1.3.0 version: 1.3.0(rollup@4.12.0) supertest: - specifier: ^6.3.4 - version: 6.3.4 + specifier: ^7.0.0 + version: 7.0.0 typescript: specifier: ^5.3.3 version: 5.3.3 @@ -1773,8 +1773,8 @@ importers: specifier: ^1.3.0 version: 1.3.0(rollup@4.12.0) supertest: - specifier: ^6.3.4 - version: 6.3.4 + specifier: ^7.0.0 + version: 7.0.0 typescript: specifier: ^5.3.3 version: 5.3.3 @@ -1846,8 +1846,8 @@ importers: specifier: ^1.3.0 version: 1.3.0(rollup@4.12.0) supertest: - specifier: ^6.3.4 - version: 6.3.4 + specifier: ^7.0.0 + version: 7.0.0 typescript: specifier: ^5.3.3 version: 5.3.3 @@ -1928,8 +1928,8 @@ importers: specifier: ^1.3.0 version: 1.3.0(rollup@4.12.0) supertest: - specifier: ^6.3.4 - version: 6.3.4 + specifier: ^7.0.0 + version: 7.0.0 typescript: specifier: ^5.3.3 version: 5.3.3 @@ -2013,8 +2013,8 @@ importers: specifier: ^1.3.0 version: 1.3.0(rollup@4.12.0) supertest: - specifier: ^6.3.4 - version: 6.3.4 + specifier: ^7.0.0 + version: 7.0.0 typescript: specifier: ^5.3.3 version: 5.3.3 @@ -2092,8 +2092,8 @@ importers: specifier: ^1.3.0 version: 1.3.0(rollup@4.12.0) supertest: - specifier: ^6.3.4 - version: 6.3.4 + specifier: ^7.0.0 + version: 7.0.0 typescript: specifier: ^5.3.3 version: 5.3.3 @@ -2165,8 +2165,8 @@ importers: specifier: ^1.3.0 version: 1.3.0(rollup@4.12.0) supertest: - specifier: ^6.3.4 - version: 6.3.4 + specifier: ^7.0.0 + version: 7.0.0 typescript: specifier: ^5.3.3 version: 5.3.3 @@ -2238,8 +2238,8 @@ importers: specifier: ^1.3.0 version: 1.3.0(rollup@4.12.0) supertest: - specifier: ^6.3.4 - version: 6.3.4 + specifier: ^7.0.0 + version: 7.0.0 typescript: specifier: ^5.3.3 version: 5.3.3 @@ -2317,8 +2317,8 @@ importers: specifier: ^1.3.0 version: 1.3.0(rollup@4.12.0) supertest: - specifier: ^6.3.4 - version: 6.3.4 + specifier: ^7.0.0 + version: 7.0.0 typescript: specifier: ^5.3.3 version: 5.3.3 @@ -2390,8 +2390,8 @@ importers: specifier: ^1.3.0 version: 1.3.0(rollup@4.12.0) supertest: - specifier: ^6.3.4 - version: 6.3.4 + specifier: ^7.0.0 + version: 7.0.0 typescript: specifier: ^5.3.3 version: 5.3.3 @@ -2463,8 +2463,8 @@ importers: specifier: ^1.3.0 version: 1.3.0(rollup@4.12.0) supertest: - specifier: ^6.3.4 - version: 6.3.4 + specifier: ^7.0.0 + version: 7.0.0 typescript: specifier: ^5.3.3 version: 5.3.3 @@ -2536,8 +2536,8 @@ importers: specifier: ^1.3.0 version: 1.3.0(rollup@4.12.0) supertest: - specifier: ^6.3.4 - version: 6.3.4 + specifier: ^7.0.0 + version: 7.0.0 typescript: specifier: ^5.3.3 version: 5.3.3 @@ -2609,8 +2609,8 @@ importers: specifier: ^1.3.0 version: 1.3.0(rollup@4.12.0) supertest: - specifier: ^6.3.4 - version: 6.3.4 + specifier: ^7.0.0 + version: 7.0.0 typescript: specifier: ^5.3.3 version: 5.3.3 @@ -2682,8 +2682,8 @@ importers: specifier: ^1.3.0 version: 1.3.0(rollup@4.12.0) supertest: - specifier: ^6.3.4 - version: 6.3.4 + specifier: ^7.0.0 + version: 7.0.0 typescript: specifier: ^5.3.3 version: 5.3.3 @@ -3286,8 +3286,8 @@ importers: specifier: ^17.0.0 version: 17.0.0 supertest: - specifier: ^6.3.4 - version: 6.3.4 + specifier: ^7.0.0 + version: 7.0.0 typescript: specifier: ^5.3.3 version: 5.3.3 @@ -10420,7 +10420,7 @@ packages: resolution: {integrity: sha512-roTU0KWIOmJ4DRLmwKd19Otg0/mT3qPNt0Qb3GWW8iObuZXxrjB/pzn0R3hqpRSWg4HCwqx+0vwOnWnvlOyeIA==} engines: {node: '>= 0.4'} dependencies: - call-bind: 1.0.2 + call-bind: 1.0.7 define-properties: 1.1.4 es-abstract: 1.20.4 es-shim-unscopables: 1.0.0 @@ -10906,13 +10906,6 @@ packages: responselike: 3.0.0 dev: false - /call-bind@1.0.2: - resolution: {integrity: sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==} - dependencies: - function-bind: 1.1.1 - get-intrinsic: 1.1.3 - dev: true - /call-bind@1.0.7: resolution: {integrity: sha512-GHTSNSYICQ7scH7sZ+M2rFopRoLh8t2bLSW6BbgrtLsahOIB5iyAVJf9GjWK3cYTDaMj4XdBpM1cA6pIS0Kv2w==} engines: {node: '>= 0.4'} @@ -12258,14 +12251,14 @@ packages: resolution: {integrity: sha512-0UtvRN79eMe2L+UNEF1BwRe364sj/DXhQ/k5FmivgoSdpM90b8Jc0mDzKMGo7QS0BVbOP/bTwBKNnDc9rNzaPA==} engines: {node: '>= 0.4'} dependencies: - call-bind: 1.0.2 + call-bind: 1.0.7 es-to-primitive: 1.2.1 - function-bind: 1.1.1 + function-bind: 1.1.2 function.prototype.name: 1.1.5 - get-intrinsic: 1.1.3 + get-intrinsic: 1.2.4 get-symbol-description: 1.0.0 has: 1.0.3 - has-property-descriptors: 1.0.0 + has-property-descriptors: 1.0.2 has-symbols: 1.0.3 internal-slot: 1.0.3 is-callable: 1.2.7 @@ -12274,7 +12267,7 @@ packages: is-shared-array-buffer: 1.0.2 is-string: 1.0.7 is-weakref: 1.0.2 - object-inspect: 1.12.2 + object-inspect: 1.13.1 object-keys: 1.1.1 object.assign: 4.1.4 regexp.prototype.flags: 1.4.3 @@ -13435,7 +13428,7 @@ packages: resolution: {integrity: sha512-uN7m/BzVKQnCUF/iW8jYea67v++2u7m5UgENbHRtdDVclOUP+FMPlCNdmk0h/ysGyo2tavMJEDqJAkJdRa1vMA==} engines: {node: '>= 0.4'} dependencies: - call-bind: 1.0.2 + call-bind: 1.0.7 define-properties: 1.1.4 es-abstract: 1.20.4 functions-have-names: 1.2.3 @@ -13508,13 +13501,6 @@ packages: resolution: {integrity: sha512-8vXOvuE167CtIc3OyItco7N/dpRtBbYOsPsXCz7X/PMnlGjYjSGuZJgM1Y7mmew7BKf9BqvLX2tnOVy1BBUsxQ==} dev: true - /get-intrinsic@1.1.3: - resolution: {integrity: sha512-QJVz1Tj7MS099PevUG5jvnt9tSkXN8K14dxQlikJuPt4uD9hHAHjLyLBiLR5zELelBdD9QNRAXZzsJx0WaDL9A==} - dependencies: - function-bind: 1.1.1 - has: 1.0.3 - has-symbols: 1.0.3 - /get-intrinsic@1.2.4: resolution: {integrity: sha512-5uYhsJH8VJBTv7oslg4BznJYhDoRI6waYCxMmCdnTrcCrHA/fCFKoTFz2JKKE0HdDFUF7/oQuhzumXJK7paBRQ==} engines: {node: '>= 0.4'} @@ -13566,8 +13552,8 @@ packages: resolution: {integrity: sha512-2EmdH1YvIQiZpltCNgkuiUnyukzxM/R6NDJX31Ke3BG1Nq5b0S2PhX59UKi9vZpPDQVdqn+1IcaAwnzTT5vCjw==} engines: {node: '>= 0.4'} dependencies: - call-bind: 1.0.2 - get-intrinsic: 1.1.3 + call-bind: 1.0.7 + get-intrinsic: 1.2.4 dev: true /get-symbol-description@1.0.2: @@ -13863,7 +13849,7 @@ packages: /has-property-descriptors@1.0.0: resolution: {integrity: sha512-62DVLZGoiEBDHQyqG4w9xCuZ7eJEwNmJRWw2VY84Oedb7WFcA27fiEVe8oUQx9hAUJ4ekurquucTGwsyO1XGdQ==} dependencies: - get-intrinsic: 1.1.3 + get-intrinsic: 1.2.4 /has-property-descriptors@1.0.2: resolution: {integrity: sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==} @@ -14418,9 +14404,9 @@ packages: resolution: {integrity: sha512-O0DB1JC/sPyZl7cIo78n5dR7eUSwwpYPiXRhTzNxZVAMUuB8vlnRFyLxdrVToks6XPLVnFfbzaVd5WLjhgg+vA==} engines: {node: '>= 0.4'} dependencies: - get-intrinsic: 1.1.3 + get-intrinsic: 1.2.4 has: 1.0.3 - side-channel: 1.0.4 + side-channel: 1.0.6 dev: true /internal-slot@1.0.7: @@ -14499,7 +14485,7 @@ packages: resolution: {integrity: sha512-gDYaKHJmnj4aWxyj6YHyXVpdQawtVLHU5cb+eztPGczf6cjuTdwve5ZIEfgXqH4e57An1D1AKf8CZ3kYrQRqYA==} engines: {node: '>= 0.4'} dependencies: - call-bind: 1.0.2 + call-bind: 1.0.7 has-tostringtag: 1.0.0 dev: true @@ -14709,7 +14695,7 @@ packages: resolution: {integrity: sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg==} engines: {node: '>= 0.4'} dependencies: - call-bind: 1.0.2 + call-bind: 1.0.7 has-tostringtag: 1.0.0 dev: true @@ -14721,7 +14707,7 @@ packages: /is-shared-array-buffer@1.0.2: resolution: {integrity: sha512-sqN2UDu1/0y6uvXyStCOzyhAjCSlHceFoMKJW8W9EU9cvic/QdsZ0kEU93HEy3IUEFZIiH/3w+AH/UQbPHNdhA==} dependencies: - call-bind: 1.0.2 + call-bind: 1.0.7 dev: true /is-shared-array-buffer@1.0.3: @@ -14793,7 +14779,7 @@ packages: /is-weakref@1.0.2: resolution: {integrity: sha512-qctsuLZmIQ0+vSSMfoVvyFe2+GSEvnmZ2ezTup1SBse9+twCCeial6EEi3Nc2KFcf6+qz2FBPnjXsk8xhKSaPQ==} dependencies: - call-bind: 1.0.2 + call-bind: 1.0.7 dev: true /is-weakset@2.0.3: @@ -15691,7 +15677,6 @@ packages: /jose@5.2.2: resolution: {integrity: sha512-/WByRr4jDcsKlvMd1dRJnPfS1GVO3WuKyaurJ/vvXcOaUQO8rnNObCQMlv/5uCceVQIq5Q4WLF44ohsdiTohdg==} - dev: true /jose@5.2.4: resolution: {integrity: sha512-6ScbIk2WWCeXkmzF6bRPmEuaqy1m8SbsRFMa/FLrSCkGIhj8OLVG/IH+XHVmNMx/KUo8cVWEE6oKR4dJ+S0Rkg==} @@ -17519,10 +17504,6 @@ packages: engines: {node: '>= 6'} dev: false - /object-inspect@1.12.2: - resolution: {integrity: sha512-z+cPxW0QGUp0mcqcsgQyLVRDoXFQbXOwBaqyF7VIgI4TWNQsDHrBpUQslRmIfAoYWdYzs6UlKJtB2XJpTaNSpQ==} - dev: true - /object-inspect@1.13.1: resolution: {integrity: sha512-5qoj1RUiKOMsCCNLV1CBiPYE10sziTsnmNxkAI/rZhiD63CF7IqdFGC/XzjWjpSgLf0LxXX3bDFIh0E18f6UhQ==} @@ -17534,7 +17515,7 @@ packages: resolution: {integrity: sha512-1mxKf0e58bvyjSCtKYY4sRe9itRk3PJpquJOjeIkz885CczcI4IvJJDLPS72oowuSh+pBxUFROpX+TU++hxhZQ==} engines: {node: '>= 0.4'} dependencies: - call-bind: 1.0.2 + call-bind: 1.0.7 define-properties: 1.1.4 has-symbols: 1.0.3 object-keys: 1.1.1 @@ -19246,7 +19227,7 @@ packages: resolution: {integrity: sha512-fjggEOO3slI6Wvgjwflkc4NFRCTZAu5CnNfBd5qOMYhWdn67nJBBu34/TkD++eeFmd8C9r9jfXJ27+nSiRkSUA==} engines: {node: '>= 0.4'} dependencies: - call-bind: 1.0.2 + call-bind: 1.0.7 define-properties: 1.1.4 functions-have-names: 1.2.3 dev: true @@ -19634,8 +19615,8 @@ packages: /safe-regex-test@1.0.0: resolution: {integrity: sha512-JBUUzyOgEwXQY1NuPtvcj/qcBDbDmEvWufhlnXZIm75DEHp+afM1r1ujJpJsV/gSM4t59tpDyPi1sd6ZaPFfsA==} dependencies: - call-bind: 1.0.2 - get-intrinsic: 1.1.3 + call-bind: 1.0.7 + get-intrinsic: 1.2.4 is-regex: 1.1.4 dev: true @@ -19791,14 +19772,6 @@ packages: resolution: {integrity: sha512-sQTKC1Re/rM6XyFM6fIAGHRPVGvyXfgzIDvzoq608vM+jeyVD0Tu1E6Np0Kc2zAIFWIj963V2800iF/9LPieQw==} dev: false - /side-channel@1.0.4: - resolution: {integrity: sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==} - dependencies: - call-bind: 1.0.2 - get-intrinsic: 1.1.3 - object-inspect: 1.12.2 - dev: true - /side-channel@1.0.6: resolution: {integrity: sha512-fDW/EZ6Q9RiO8eFG8Hj+7u/oW+XrPTIChwCOM2+th2A6OblDtYYIpve9m+KvI9Z4C9qSEXlaGR6bTEYHReuglA==} engines: {node: '>= 0.4'} @@ -20180,7 +20153,7 @@ packages: /string.prototype.trimend@1.0.5: resolution: {integrity: sha512-I7RGvmjV4pJ7O3kdf+LXFpVfdNOxtCW/2C8f6jNiW4+PQchwxkCDzlk1/7p+Wl4bqFIZeF47qAHXLuHHWKAxog==} dependencies: - call-bind: 1.0.2 + call-bind: 1.0.7 define-properties: 1.1.4 es-abstract: 1.20.4 dev: true @@ -20196,7 +20169,7 @@ packages: /string.prototype.trimstart@1.0.5: resolution: {integrity: sha512-THx16TJCGlsN0o6dl2o6ncWUsdgnLRSA23rRE5pyGBw/mLr3Ej/R2LaqCtgP8VNMGZsvMWnf9ooZPyY2bHvUFg==} dependencies: - call-bind: 1.0.2 + call-bind: 1.0.7 define-properties: 1.1.4 es-abstract: 1.20.4 dev: true @@ -20397,9 +20370,9 @@ packages: - typescript dev: true - /superagent@8.1.2: - resolution: {integrity: sha512-6WTxW1EB6yCxV5VFOIPQruWGHqc3yI7hEmZK6h+pyk69Lk/Ut7rLUY6W/ONF2MjBuGjvmMiIpsrVJ2vjrHlslA==} - engines: {node: '>=6.4.0 <13 || >=14'} + /superagent@9.0.1: + resolution: {integrity: sha512-CcRSdb/P2oUVaEpQ87w9Obsl+E9FruRd6b2b7LdiBtJoyMr2DQt7a89anAfiX/EL59j9b2CbRFvf2S91DhuCww==} + engines: {node: '>=14.18.0'} dependencies: component-emitter: 1.3.0 cookiejar: 2.1.4 @@ -20420,12 +20393,12 @@ packages: engines: {node: '>=14.0.0'} dev: true - /supertest@6.3.4: - resolution: {integrity: sha512-erY3HFDG0dPnhw4U+udPfrzXa4xhSG+n4rxfRuZWCUvjFWwKl+OxWf/7zk50s84/fAAs7vf5QAb9uRa0cCykxw==} - engines: {node: '>=6.4.0'} + /supertest@7.0.0: + resolution: {integrity: sha512-qlsr7fIC0lSddmA3tzojvzubYxvlGtzumcdHgPwbFWMISQwL22MhM2Y3LNt+6w9Yyx7559VW5ab70dgphm8qQA==} + engines: {node: '>=14.18.0'} dependencies: methods: 1.1.2 - superagent: 8.1.2 + superagent: 9.0.1 transitivePeerDependencies: - supports-color dev: true @@ -20959,7 +20932,7 @@ packages: /unbox-primitive@1.0.2: resolution: {integrity: sha512-61pPlCD9h51VoreyJ0BReideM3MDKMKnh6+V9L08331ipq6Q8OFXZYiqP6n/tbHx4s5I9uRhcye6BrbkizkBDw==} dependencies: - call-bind: 1.0.2 + call-bind: 1.0.7 has-bigints: 1.0.2 has-symbols: 1.0.3 which-boxed-primitive: 1.0.2 From 397dfcdf927d38b82cf5874d5c381ef8bbb5ef07 Mon Sep 17 00:00:00 2001 From: simeng-li Date: Thu, 25 Apr 2024 14:00:07 +0800 Subject: [PATCH 327/687] fix(experience): redirect to sign-in page on socical sign-in error (#5787) * fix(experience): redirect to sign-in page on socical sign-in error redirect user to sign-in page on social sign-in error * test(experience): add integration tests add integration tests --- .../use-single-sign-on-listener.ts | 5 +++++ .../use-social-sign-in-listener.ts | 5 +++++ .../tests/experience/social-sign-in.test.ts | 18 +++++++++++++++++- 3 files changed, 27 insertions(+), 1 deletion(-) diff --git a/packages/experience/src/pages/SocialSignInWebCallback/use-single-sign-on-listener.ts b/packages/experience/src/pages/SocialSignInWebCallback/use-single-sign-on-listener.ts index 00f7b88f87d..e59abf46110 100644 --- a/packages/experience/src/pages/SocialSignInWebCallback/use-single-sign-on-listener.ts +++ b/packages/experience/src/pages/SocialSignInWebCallback/use-single-sign-on-listener.ts @@ -87,6 +87,11 @@ const useSingleSignOnListener = (connectorId: string) => { await registerSingleSignOnIdentity(connectorId); }, + // Redirect to sign-in page if error is not handled by the error handlers + global: async (error) => { + setToast(error.message); + navigate('/' + experience.routes.signIn); + }, }); return; } diff --git a/packages/experience/src/pages/SocialSignInWebCallback/use-social-sign-in-listener.ts b/packages/experience/src/pages/SocialSignInWebCallback/use-social-sign-in-listener.ts index 240d5c2a9be..902a23f3a58 100644 --- a/packages/experience/src/pages/SocialSignInWebCallback/use-social-sign-in-listener.ts +++ b/packages/experience/src/pages/SocialSignInWebCallback/use-social-sign-in-listener.ts @@ -76,6 +76,11 @@ const useSocialSignInListener = (connectorId: string) => { await accountNotExistErrorHandler(error); }, ...preSignInErrorHandler, + // Redirect to sign-in page if error is not handled by the error handlers + global: async (error) => { + setToast(error.message); + navigate('/' + experience.routes.signIn); + }, }), [ preSignInErrorHandler, diff --git a/packages/integration-tests/src/tests/experience/social-sign-in.test.ts b/packages/integration-tests/src/tests/experience/social-sign-in.test.ts index 9f89563b2db..c4e223b8141 100644 --- a/packages/integration-tests/src/tests/experience/social-sign-in.test.ts +++ b/packages/integration-tests/src/tests/experience/social-sign-in.test.ts @@ -31,15 +31,17 @@ describe('social sign-in (with email identifier)', () => { // eslint-disable-next-line @silverhand/fp/no-let let experience: ExpectExperience; const socialUserId = 'foo_' + randomString(); + const ssoEmailDomain = `foo${randomString()}.com`; beforeAll(async () => { await clearConnectorsByTypes([ConnectorType.Social, ConnectorType.Email, ConnectorType.Sms]); await setEmailConnector(); await setSocialConnector(); + const ssoConnector = await createSsoConnector({ providerName: SsoProviderName.OIDC, connectorName: 'test-oidc-' + randomString(), - domains: [`foo${randomString()}.com`], + domains: [ssoEmailDomain], config: { clientId: 'foo', clientSecret: 'bar', @@ -160,4 +162,18 @@ describe('social sign-in (with email identifier)', () => { await experience.toCompleteVerification('continue', 'Email'); await experience.verifyThenEnd(); }); + + it('should redirect to the sign-in page if the socialEmail is SSO email domain', async () => { + // eslint-disable-next-line @silverhand/fp/no-mutation + experience = new ExpectExperience(await browser.newPage()); + await experience.startWith(demoAppUrl, 'sign-in'); + await experience.toProcessSocialSignIn({ + socialUserId, + socialEmail: generateEmail(ssoEmailDomain), + }); + await experience.waitForToast( + 'Single sign on is enabled for this given email. Please sign in with SSO.' + ); + experience.toBeAt('sign-in'); + }); }); From d6930f96679750434b1ed9aa27a461e24314d3a5 Mon Sep 17 00:00:00 2001 From: Darcy Ye Date: Thu, 25 Apr 2024 21:20:19 +0800 Subject: [PATCH 328/687] refactor: reorg the implementation --- ... => jwt-customizer.script-merging.test.ts} | 0 packages/core/src/libraries/jwt-customizer.ts | 97 ++++++++++++++++++- packages/core/src/libraries/logto-config.ts | 89 ----------------- .../logto-config/jwt-customizer.test.ts | 49 +++++----- .../src/routes/logto-config/jwt-customizer.ts | 19 ++-- packages/core/src/tenants/Libraries.ts | 13 ++- packages/core/src/tenants/Tenant.ts | 8 +- .../core/src/test-utils/mock-libraries.ts | 2 - packages/core/src/test-utils/tenant.ts | 8 +- 9 files changed, 148 insertions(+), 137 deletions(-) rename packages/core/src/libraries/{logto-config.script-merging.test.ts => jwt-customizer.script-merging.test.ts} (100%) diff --git a/packages/core/src/libraries/logto-config.script-merging.test.ts b/packages/core/src/libraries/jwt-customizer.script-merging.test.ts similarity index 100% rename from packages/core/src/libraries/logto-config.script-merging.test.ts rename to packages/core/src/libraries/jwt-customizer.script-merging.test.ts diff --git a/packages/core/src/libraries/jwt-customizer.ts b/packages/core/src/libraries/jwt-customizer.ts index 2e1d73e7b3c..fae9698cd9e 100644 --- a/packages/core/src/libraries/jwt-customizer.ts +++ b/packages/core/src/libraries/jwt-customizer.ts @@ -1,13 +1,29 @@ -import type { JwtCustomizerUserContext } from '@logto/schemas'; -import { userInfoSelectFields, jwtCustomizerUserContextGuard } from '@logto/schemas'; -import { deduplicate, pick, pickState } from '@silverhand/essentials'; +import { + userInfoSelectFields, + jwtCustomizerUserContextGuard, + type LogtoJwtTokenKey, + type JwtCustomizerType, + type JwtCustomizerUserContext, +} from '@logto/schemas'; +import { deduplicate, pick, pickState, assert } from '@silverhand/essentials'; +import deepmerge from 'deepmerge'; +import RequestError from '#src/errors/RequestError/index.js'; +import type { LogtoConfigLibrary } from '#src/libraries/logto-config.js'; import { type ScopeLibrary } from '#src/libraries/scope.js'; import { type UserLibrary } from '#src/libraries/user.js'; import type Queries from '#src/tenants/Queries.js'; +import { + getJwtCustomizerScripts, + type CustomJwtDeployRequestBody, +} from '#src/utils/custom-jwt/index.js'; + +import { type CloudConnectionLibrary } from './cloud-connection.js'; export const createJwtCustomizerLibrary = ( queries: Queries, + logtoConfigs: LogtoConfigLibrary, + cloudConnection: CloudConnectionLibrary, userLibrary: UserLibrary, scopeLibrary: ScopeLibrary ) => { @@ -20,6 +36,7 @@ export const createJwtCustomizerLibrary = ( } = queries; const { findUserRoles } = userLibrary; const { attachResourceToScopes } = scopeLibrary; + const { getJwtCustomizers } = logtoConfigs; /** * We does not include org roles' scopes for the following reason: @@ -65,7 +82,81 @@ export const createJwtCustomizerLibrary = ( return jwtCustomizerUserContextGuard.parse(userContext); }; + /** + * This method is used to deploy the give JWT customizer scripts to the cloud worker service. + * + * @remarks Since cloud worker service deploy all the JWT customizer scripts at once, + * and the latest JWT customizer updates needs to be deployed ahead before saving it to the database, + * we need to merge the input payload with the existing JWT customizer scripts. + * + * @params payload - The latest JWT customizer payload needs to be deployed. + * @params payload.key - The tokenType of the JWT customizer. + * @params payload.value - JWT customizer value + * @params payload.useCase - The use case of JWT customizer script, can be either `test` or `production`. + */ + const deployJwtCustomizerScript = async (payload: { + key: T; + value: JwtCustomizerType[T]; + useCase: 'test' | 'production'; + }) => { + const [client, jwtCustomizers] = await Promise.all([ + cloudConnection.getClient(), + getJwtCustomizers(), + ]); + + const customizerScriptsFromDatabase = getJwtCustomizerScripts(jwtCustomizers); + + const newCustomizerScripts: CustomJwtDeployRequestBody = { + /** + * There are at most 4 custom JWT scripts in the `CustomJwtDeployRequestBody`-typed object, + * and can be indexed by `data[CustomJwtType][UseCase]`. + * + * Per our design, each script will be deployed as a API endpoint in the Cloudflare + * worker service. A production script will be deployed to `/api/custom-jwt` + * endpoint and a test script will be deployed to `/api/custom-jwt/test` endpoint. + * + * If the current use case is `test`, then the script should be deployed to a `/test` endpoint; + * otherwise, the script should be deployed to the `/api/custom-jwt` endpoint and overwrite + * previous handler of the API endpoint. + */ + [payload.key]: { [payload.useCase]: payload.value.script }, + }; + + await client.put(`/api/services/custom-jwt/worker`, { + body: deepmerge(customizerScriptsFromDatabase, newCustomizerScripts), + }); + }; + + const undeployJwtCustomizerScript = async (key: T) => { + const [client, jwtCustomizers] = await Promise.all([ + cloudConnection.getClient(), + getJwtCustomizers(), + ]); + + assert(jwtCustomizers[key], new RequestError({ code: 'entity.not_exists', key })); + + // Undeploy the worker directly if the only JWT customizer is being deleted. + if (Object.entries(jwtCustomizers).length === 1) { + await client.delete(`/api/services/custom-jwt/worker`); + return; + } + + // Remove the JWT customizer script (of given `key`) from the existing JWT customizer scripts and redeploy. + const customizerScriptsFromDatabase = getJwtCustomizerScripts(jwtCustomizers); + const newCustomizerScripts: CustomJwtDeployRequestBody = { + [key]: { + production: undefined, + test: undefined, + }, + }; + + await client.put(`/api/services/custom-jwt/worker`, { + body: deepmerge(customizerScriptsFromDatabase, newCustomizerScripts), + }); + }; return { getUserContext, + deployJwtCustomizerScript, + undeployJwtCustomizerScript, }; }; diff --git a/packages/core/src/libraries/logto-config.ts b/packages/core/src/libraries/logto-config.ts index 333586b27c1..54fed67a668 100644 --- a/packages/core/src/libraries/logto-config.ts +++ b/packages/core/src/libraries/logto-config.ts @@ -8,20 +8,12 @@ import { jwtCustomizerConfigGuard, logtoOidcConfigGuard, } from '@logto/schemas'; -import { assert } from '@silverhand/essentials'; import chalk from 'chalk'; -import deepmerge from 'deepmerge'; import { ZodError, z } from 'zod'; import RequestError from '#src/errors/RequestError/index.js'; import type Queries from '#src/tenants/Queries.js'; import { consoleLog } from '#src/utils/console.js'; -import { - getJwtCustomizerScripts, - type CustomJwtDeployRequestBody, -} from '#src/utils/custom-jwt/index.js'; - -import { type CloudConnectionLibrary } from './cloud-connection.js'; export type LogtoConfigLibrary = ReturnType; @@ -137,85 +129,6 @@ export const createLogtoConfigLibrary = ({ return updatedRow.value; }; - /** - * This method is used to deploy the give JWT customizer scripts to the cloud worker service. - * - * @remarks Since cloud worker service deploy all the JWT customizer scripts at once, - * and the latest JWT customizer updates needs to be deployed ahead before saving it to the database, - * we need to merge the input payload with the existing JWT customizer scripts. - * - * @params payload - The latest JWT customizer payload needs to be deployed. - * @params payload.key - The tokenType of the JWT customizer. - * @params payload.value - JWT customizer value - * @params payload.useCase - The use case of JWT customizer script, can be either `test` or `production`. - */ - const deployJwtCustomizerScript = async ( - cloudConnection: CloudConnectionLibrary, - payload: { - key: T; - value: JwtCustomizerType[T]; - useCase: 'test' | 'production'; - } - ) => { - const [client, jwtCustomizers] = await Promise.all([ - cloudConnection.getClient(), - getJwtCustomizers(), - ]); - - const customizerScriptsFromDatabase = getJwtCustomizerScripts(jwtCustomizers); - - const newCustomizerScripts: CustomJwtDeployRequestBody = { - /** - * There are at most 4 custom JWT scripts in the `CustomJwtDeployRequestBody`-typed object, - * and can be indexed by `data[CustomJwtType][UseCase]`. - * - * Per our design, each script will be deployed as a API endpoint in the Cloudflare - * worker service. A production script will be deployed to `/api/custom-jwt` - * endpoint and a test script will be deployed to `/api/custom-jwt/test` endpoint. - * - * If the current use case is `test`, then the script should be deployed to a `/test` endpoint; - * otherwise, the script should be deployed to the `/api/custom-jwt` endpoint and overwrite - * previous handler of the API endpoint. - */ - [payload.key]: { [payload.useCase]: payload.value.script }, - }; - - await client.put(`/api/services/custom-jwt/worker`, { - body: deepmerge(customizerScriptsFromDatabase, newCustomizerScripts), - }); - }; - - const undeployJwtCustomizerScript = async ( - cloudConnection: CloudConnectionLibrary, - key: T - ) => { - const [client, jwtCustomizers] = await Promise.all([ - cloudConnection.getClient(), - getJwtCustomizers(), - ]); - - assert(jwtCustomizers[key], new RequestError({ code: 'entity.not_exists', key })); - - // Undeploy the worker directly if the only JWT customizer is being deleted. - if (Object.entries(jwtCustomizers).length === 1) { - await client.delete(`/api/services/custom-jwt/worker`); - return; - } - - // Remove the JWT customizer script (of given `key`) from the existing JWT customizer scripts and redeploy. - const customizerScriptsFromDatabase = getJwtCustomizerScripts(jwtCustomizers); - const newCustomizerScripts: CustomJwtDeployRequestBody = { - [key]: { - production: undefined, - test: undefined, - }, - }; - - await client.put(`/api/services/custom-jwt/worker`, { - body: deepmerge(customizerScriptsFromDatabase, newCustomizerScripts), - }); - }; - return { getOidcConfigs, getCloudConnectionData, @@ -223,7 +136,5 @@ export const createLogtoConfigLibrary = ({ getJwtCustomizer, getJwtCustomizers, updateJwtCustomizer, - deployJwtCustomizerScript, - undeployJwtCustomizerScript, }; }; diff --git a/packages/core/src/routes/logto-config/jwt-customizer.test.ts b/packages/core/src/routes/logto-config/jwt-customizer.test.ts index 88c0424c724..56d560c505f 100644 --- a/packages/core/src/routes/logto-config/jwt-customizer.test.ts +++ b/packages/core/src/routes/logto-config/jwt-customizer.test.ts @@ -29,7 +29,12 @@ describe('configs JWT customizer routes', () => { undefined, { logtoConfigs: logtoConfigQueries }, undefined, - undefined, + { + jwtCustomizers: { + deployJwtCustomizerScript: jest.fn(), + undeployJwtCustomizerScript: jest.fn(), + }, + }, mockLogtoConfigsLibrary ); @@ -55,14 +60,11 @@ describe('configs JWT customizer routes', () => { .put(`/configs/jwt-customizer/access-token`) .send(mockJwtCustomizerConfigForAccessToken.value); - expect(mockLogtoConfigsLibrary.deployJwtCustomizerScript).toHaveBeenCalledWith( - tenantContext.cloudConnection, - { - key: LogtoJwtTokenKey.AccessToken, - value: mockJwtCustomizerConfigForAccessToken.value, - useCase: 'production', - } - ); + expect(tenantContext.libraries.jwtCustomizers.deployJwtCustomizerScript).toHaveBeenCalledWith({ + key: LogtoJwtTokenKey.AccessToken, + value: mockJwtCustomizerConfigForAccessToken.value, + useCase: 'production', + }); expect(mockLogtoConfigsLibrary.upsertJwtCustomizer).toHaveBeenCalledWith( LogtoJwtTokenKey.AccessToken, @@ -100,14 +102,11 @@ describe('configs JWT customizer routes', () => { .patch('/configs/jwt-customizer/access-token') .send(mockJwtCustomizerConfigForAccessToken.value); - expect(mockLogtoConfigsLibrary.deployJwtCustomizerScript).toHaveBeenCalledWith( - tenantContext.cloudConnection, - { - key: LogtoJwtTokenKey.AccessToken, - value: mockJwtCustomizerConfigForAccessToken.value, - useCase: 'production', - } - ); + expect(tenantContext.libraries.jwtCustomizers.deployJwtCustomizerScript).toHaveBeenCalledWith({ + key: LogtoJwtTokenKey.AccessToken, + value: mockJwtCustomizerConfigForAccessToken.value, + useCase: 'production', + }); expect(mockLogtoConfigsLibrary.updateJwtCustomizer).toHaveBeenCalledWith( LogtoJwtTokenKey.AccessToken, @@ -141,8 +140,7 @@ describe('configs JWT customizer routes', () => { it('DELETE /configs/jwt-customizer/:tokenType should delete the record', async () => { const response = await routeRequester.delete('/configs/jwt-customizer/client-credentials'); - expect(mockLogtoConfigsLibrary.undeployJwtCustomizerScript).toHaveBeenCalledWith( - tenantContext.cloudConnection, + expect(tenantContext.libraries.jwtCustomizers.undeployJwtCustomizerScript).toHaveBeenCalledWith( LogtoJwtTokenKey.ClientCredentials ); expect(logtoConfigQueries.deleteJwtCustomizer).toHaveBeenCalledWith( @@ -165,14 +163,11 @@ describe('configs JWT customizer routes', () => { const response = await routeRequester.post('/configs/jwt-customizer/test').send(payload); - expect(mockLogtoConfigsLibrary.deployJwtCustomizerScript).toHaveBeenCalledWith( - tenantContext.cloudConnection, - { - key: LogtoJwtTokenKey.ClientCredentials, - value: payload, - useCase: 'test', - } - ); + expect(tenantContext.libraries.jwtCustomizers.deployJwtCustomizerScript).toHaveBeenCalledWith({ + key: LogtoJwtTokenKey.ClientCredentials, + value: payload, + useCase: 'test', + }); expect(mockCloudClient.post).toHaveBeenCalledWith('/api/services/custom-jwt', { body: payload, diff --git a/packages/core/src/routes/logto-config/jwt-customizer.ts b/packages/core/src/routes/logto-config/jwt-customizer.ts index da629a241ff..67ca3522753 100644 --- a/packages/core/src/routes/logto-config/jwt-customizer.ts +++ b/packages/core/src/routes/logto-config/jwt-customizer.ts @@ -38,14 +38,9 @@ export default function logtoConfigJwtCustomizerRoutes( ]: RouterInitArgs ) { const { getRowsByKeys, deleteJwtCustomizer } = queries.logtoConfigs; - const { - upsertJwtCustomizer, - getJwtCustomizer, - getJwtCustomizers, - updateJwtCustomizer, - deployJwtCustomizerScript, - undeployJwtCustomizerScript, - } = logtoConfigs; + const { upsertJwtCustomizer, getJwtCustomizer, getJwtCustomizers, updateJwtCustomizer } = + logtoConfigs; + const { deployJwtCustomizerScript, undeployJwtCustomizerScript } = libraries.jwtCustomizers; router.put( '/configs/jwt-customizer/:tokenTypePath', @@ -83,7 +78,7 @@ export default function logtoConfigJwtCustomizerRoutes( // Deploy first to avoid the case where the JWT customizer was saved to DB but not deployed successfully. if (!isIntegrationTest) { - await deployJwtCustomizerScript(cloudConnection, { + await deployJwtCustomizerScript({ key, value: body, useCase: 'production', @@ -127,7 +122,7 @@ export default function logtoConfigJwtCustomizerRoutes( // Deploy first to avoid the case where the JWT customizer was saved to DB but not deployed successfully. if (!isIntegrationTest) { - await deployJwtCustomizerScript(cloudConnection, { + await deployJwtCustomizerScript({ key, value: body, useCase: 'production', @@ -199,7 +194,7 @@ export default function logtoConfigJwtCustomizerRoutes( // Undeploy the script first to avoid the case where the JWT customizer was deleted from DB but worker script not updated successfully. if (!isIntegrationTest) { - await undeployJwtCustomizerScript(cloudConnection, tokenKey); + await undeployJwtCustomizerScript(tokenKey); } await deleteJwtCustomizer(tokenKey); @@ -224,7 +219,7 @@ export default function logtoConfigJwtCustomizerRoutes( const { body } = ctx.guard; // Deploy the test script - await deployJwtCustomizerScript(cloudConnection, { + await deployJwtCustomizerScript({ key: body.tokenType === LogtoJwtTokenKeyType.AccessToken ? LogtoJwtTokenKey.AccessToken diff --git a/packages/core/src/tenants/Libraries.ts b/packages/core/src/tenants/Libraries.ts index 12a70374847..6c4ecfcbbfe 100644 --- a/packages/core/src/tenants/Libraries.ts +++ b/packages/core/src/tenants/Libraries.ts @@ -4,6 +4,7 @@ import type { ConnectorLibrary } from '#src/libraries/connector.js'; import { createDomainLibrary } from '#src/libraries/domain.js'; import { createHookLibrary } from '#src/libraries/hook/index.js'; import { createJwtCustomizerLibrary } from '#src/libraries/jwt-customizer.js'; +import type { LogtoConfigLibrary } from '#src/libraries/logto-config.js'; import { OrganizationInvitationLibrary } from '#src/libraries/organization-invitation.js'; import { createPasscodeLibrary } from '#src/libraries/passcode.js'; import { createPhraseLibrary } from '#src/libraries/phrase.js'; @@ -25,7 +26,14 @@ export default class Libraries { hooks = createHookLibrary(this.queries); scopes = createScopeLibrary(this.queries); socials = createSocialLibrary(this.queries, this.connectors); - jwtCustomizers = createJwtCustomizerLibrary(this.queries, this.users, this.scopes); + jwtCustomizers = createJwtCustomizerLibrary( + this.queries, + this.logtoConfigs, + this.cloudConnection, + this.users, + this.scopes + ); + passcodes = createPasscodeLibrary(this.queries, this.connectors); applications = createApplicationLibrary(this.queries); verificationStatuses = createVerificationStatusLibrary(this.queries); @@ -52,6 +60,7 @@ export default class Libraries { private readonly queries: Queries, // Explicitly passing connector library to eliminate dependency issue private readonly connectors: ConnectorLibrary, - private readonly cloudConnection: CloudConnectionLibrary + private readonly cloudConnection: CloudConnectionLibrary, + private readonly logtoConfigs: LogtoConfigLibrary ) {} } diff --git a/packages/core/src/tenants/Tenant.ts b/packages/core/src/tenants/Tenant.ts index 1cafa3594cf..ece5ed4e408 100644 --- a/packages/core/src/tenants/Tenant.ts +++ b/packages/core/src/tenants/Tenant.ts @@ -62,7 +62,13 @@ export default class Tenant implements TenantContext { public readonly logtoConfigs = createLogtoConfigLibrary(queries), public readonly cloudConnection = createCloudConnectionLibrary(logtoConfigs), public readonly connectors = createConnectorLibrary(queries, cloudConnection), - public readonly libraries = new Libraries(id, queries, connectors, cloudConnection), + public readonly libraries = new Libraries( + id, + queries, + connectors, + cloudConnection, + logtoConfigs + ), public readonly sentinel = new BasicSentinel(envSet.pool) ) { const isAdminTenant = id === adminTenantId; diff --git a/packages/core/src/test-utils/mock-libraries.ts b/packages/core/src/test-utils/mock-libraries.ts index d016bbd7b0d..bde91839ee5 100644 --- a/packages/core/src/test-utils/mock-libraries.ts +++ b/packages/core/src/test-utils/mock-libraries.ts @@ -12,8 +12,6 @@ export const mockLogtoConfigsLibrary: jest.Mocked = { getJwtCustomizer: jest.fn(), getJwtCustomizers: jest.fn(), updateJwtCustomizer: jest.fn(), - deployJwtCustomizerScript: jest.fn(), - undeployJwtCustomizerScript: jest.fn(), }; export const mockCloudClient = new Client({ baseUrl: 'http://localhost:3001' }); diff --git a/packages/core/src/test-utils/tenant.ts b/packages/core/src/test-utils/tenant.ts index f3be908e591..33d012f1e9d 100644 --- a/packages/core/src/test-utils/tenant.ts +++ b/packages/core/src/test-utils/tenant.ts @@ -84,7 +84,13 @@ export class MockTenant implements TenantContext { ...createConnectorLibrary(this.queries, this.cloudConnection), ...connectorsOverride, }; - this.libraries = new Libraries(this.id, this.queries, this.connectors, this.cloudConnection); + this.libraries = new Libraries( + this.id, + this.queries, + this.connectors, + this.cloudConnection, + this.logtoConfigs + ); this.setPartial('libraries', librariesOverride); this.sentinel = new MockSentinel(); } From e8c41b16441a73e290d933c01f40f2d872a68b96 Mon Sep 17 00:00:00 2001 From: Gao Sun Date: Thu, 25 Apr 2024 22:16:59 +0800 Subject: [PATCH 329/687] feat: support organization custom data (#5785) * feat: support organization custom data * chore: update changeset --- .changeset/healthy-knives-draw.md | 11 ++++ .../OrganizationDetails/Settings/index.tsx | 51 ++++++++++++++++--- .../src/helpers/organization.ts | 7 ++- .../api/organization/organization.test.ts | 22 ++++++-- .../admin-console/organization-details.ts | 7 +++ .../admin-console/organization-details.ts | 4 ++ .../admin-console/organization-details.ts | 7 +++ .../admin-console/organization-details.ts | 7 +++ .../admin-console/organization-details.ts | 7 +++ .../admin-console/organization-details.ts | 7 +++ .../admin-console/organization-details.ts | 7 +++ .../admin-console/organization-details.ts | 7 +++ .../admin-console/organization-details.ts | 7 +++ .../admin-console/organization-details.ts | 7 +++ .../admin-console/organization-details.ts | 7 +++ .../admin-console/organization-details.ts | 7 +++ .../admin-console/organization-details.ts | 7 +++ .../admin-console/organization-details.ts | 7 +++ .../admin-console/organization-details.ts | 7 +++ ...1713942039-add-organization-custom-data.ts | 25 +++++++++ packages/schemas/tables/organizations.sql | 2 + 21 files changed, 210 insertions(+), 10 deletions(-) create mode 100644 .changeset/healthy-knives-draw.md create mode 100644 packages/schemas/alterations/next-1713942039-add-organization-custom-data.ts diff --git a/.changeset/healthy-knives-draw.md b/.changeset/healthy-knives-draw.md new file mode 100644 index 00000000000..6b807ff01a1 --- /dev/null +++ b/.changeset/healthy-knives-draw.md @@ -0,0 +1,11 @@ +--- +"@logto/schemas": minor +"@logto/core": minor +--- + +support organization custom data + +Now you can save additional data associated with the organization with the organization-level `customData` field by: + +- Edit in the Console organization details page. +- Specify `customData` field when using organization Management APIs. diff --git a/packages/console/src/pages/OrganizationDetails/Settings/index.tsx b/packages/console/src/pages/OrganizationDetails/Settings/index.tsx index a1489161fb4..29471ce012e 100644 --- a/packages/console/src/pages/OrganizationDetails/Settings/index.tsx +++ b/packages/console/src/pages/OrganizationDetails/Settings/index.tsx @@ -1,5 +1,6 @@ import { type Organization } from '@logto/schemas'; -import { useForm } from 'react-hook-form'; +import { trySafe } from '@silverhand/essentials'; +import { Controller, useForm } from 'react-hook-form'; import { toast } from 'react-hot-toast'; import { useTranslation } from 'react-i18next'; import { useOutletContext } from 'react-router-dom'; @@ -7,6 +8,7 @@ import { useOutletContext } from 'react-router-dom'; import DetailsForm from '@/components/DetailsForm'; import FormCard from '@/components/FormCard'; import UnsavedChangesAlertModal from '@/components/UnsavedChangesAlertModal'; +import CodeEditor from '@/ds-components/CodeEditor'; import FormField from '@/ds-components/FormField'; import TextInput from '@/ds-components/TextInput'; import useApi from '@/hooks/use-api'; @@ -14,29 +16,50 @@ import { trySubmitSafe } from '@/utils/form'; import { type OrganizationDetailsOutletContext } from '../types'; +type FormData = Partial & { customData: string }>; + +const isJsonObject = (value: string) => { + const parsed = trySafe(() => JSON.parse(value)); + return Boolean(parsed && typeof parsed === 'object'); +}; + +const normalizeData = (data: Organization): FormData => ({ + ...data, + customData: JSON.stringify(data.customData, undefined, 2), +}); + +const assembleData = (data: FormData): Partial => ({ + ...data, + // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment + customData: JSON.parse(data.customData ?? '{}'), +}); + function Settings() { const { isDeleting, data, onUpdated } = useOutletContext(); const { t } = useTranslation(undefined, { keyPrefix: 'admin_console' }); const { register, reset, + control, handleSubmit, formState: { isDirty, isSubmitting, errors }, - } = useForm>({ - defaultValues: data, + } = useForm({ + defaultValues: normalizeData(data), }); const api = useApi(); const onSubmit = handleSubmit( - trySubmitSafe(async (json) => { + trySubmitSafe(async (data) => { if (isSubmitting) { return; } const updatedData = await api - .patch(`api/organizations/${data.id}`, { json }) + .patch(`api/organizations/${data.id}`, { + json: assembleData(data), + }) .json(); - reset(updatedData); + reset(normalizeData(updatedData)); toast.success(t('general.saved')); onUpdated(updatedData); }) @@ -66,6 +89,22 @@ function Settings() { {...register('description')} /> + + + isJsonObject(value ?? '') ? true : t('organization_details.invalid_json_object'), + }} + render={({ field }) => ( + + )} + /> + diff --git a/packages/integration-tests/src/helpers/organization.ts b/packages/integration-tests/src/helpers/organization.ts index e2d15ef4c4d..d45ef5d44a7 100644 --- a/packages/integration-tests/src/helpers/organization.ts +++ b/packages/integration-tests/src/helpers/organization.ts @@ -4,6 +4,7 @@ import { type Organization, type OrganizationRoleWithScopes, type OrganizationInvitationEntity, + type JsonObject, } from '@logto/schemas'; import { trySafe } from '@silverhand/essentials'; @@ -122,7 +123,11 @@ export class OrganizationApiTest extends OrganizationApi { return this.#organizations; } - override async create(data: { name: string; description?: string }): Promise { + override async create(data: { + name: string; + description?: string; + customData?: JsonObject; + }): Promise { const created = await super.create(data); this.organizations.push(created); return created; diff --git a/packages/integration-tests/src/tests/api/organization/organization.test.ts b/packages/integration-tests/src/tests/api/organization/organization.test.ts index 892a98ba57b..fb0cd6eeeb0 100644 --- a/packages/integration-tests/src/tests/api/organization/organization.test.ts +++ b/packages/integration-tests/src/tests/api/organization/organization.test.ts @@ -13,15 +13,23 @@ describe('organization APIs', () => { }); it('should get organizations successfully', async () => { - await organizationApi.create({ name: 'test', description: 'A test organization.' }); + await organizationApi.create({ + name: 'test', + description: 'A test organization.', + customData: { foo: 'bar' }, + }); await organizationApi.create({ name: 'test2' }); const organizations = await organizationApi.getList(); expect(organizations).toContainEqual( - expect.objectContaining({ name: 'test', description: 'A test organization.' }) + expect.objectContaining({ + name: 'test', + description: 'A test organization.', + customData: { foo: 'bar' }, + }) ); expect(organizations).toContainEqual( - expect.objectContaining({ name: 'test2', description: null }) + expect.objectContaining({ name: 'test2', description: null, customData: {} }) ); for (const organization of organizations) { expect(organization).not.toHaveProperty('usersCount'); @@ -29,6 +37,14 @@ describe('organization APIs', () => { } }); + it('should fail when input data is malformed', async () => { + const response = await organizationApi + // @ts-expect-error intended to test invalid input + .create({ name: 'a', customData: 'b' }) + .catch((error: unknown) => error); + expect(response instanceof HTTPError && response.response.status).toBe(400); + }); + it('should get organizations with featured users', async () => { const [organization1, organization2] = await Promise.all([ organizationApi.create({ name: 'test' }), diff --git a/packages/phrases/src/locales/de/translation/admin-console/organization-details.ts b/packages/phrases/src/locales/de/translation/admin-console/organization-details.ts index a34648f79ff..73cf60d6e1e 100644 --- a/packages/phrases/src/locales/de/translation/admin-console/organization-details.ts +++ b/packages/phrases/src/locales/de/translation/admin-console/organization-details.ts @@ -22,6 +22,13 @@ const organization_details = { 'Wenn entfernt, verliert der Benutzer seine Mitgliedschaft und Rollen in dieser Organisation. Diese Aktion kann nicht rückgängig gemacht werden.', search_user_placeholder: 'Nach Name, E-Mail, Telefon oder Benutzer-ID suchen', at_least_one_user: 'Mindestens ein Benutzer ist erforderlich.', + /** UNTRANSLATED */ + custom_data: 'Custom data', + /** UNTRANSLATED */ + custom_data_tip: + 'Custom data is a JSON object that can be used to store additional data associated with the organization.', + /** UNTRANSLATED */ + invalid_json_object: 'Invalid JSON object.', }; export default Object.freeze(organization_details); diff --git a/packages/phrases/src/locales/en/translation/admin-console/organization-details.ts b/packages/phrases/src/locales/en/translation/admin-console/organization-details.ts index 98291aab40b..65018c53182 100644 --- a/packages/phrases/src/locales/en/translation/admin-console/organization-details.ts +++ b/packages/phrases/src/locales/en/translation/admin-console/organization-details.ts @@ -22,6 +22,10 @@ const organization_details = { 'Once removed, the user will lose their membership and roles in this organization. This action cannot be undone.', search_user_placeholder: 'Search by name, email, phone or user ID', at_least_one_user: 'At least one user is required.', + custom_data: 'Custom data', + custom_data_tip: + 'Custom data is a JSON object that can be used to store additional data associated with the organization.', + invalid_json_object: 'Invalid JSON object.', }; export default Object.freeze(organization_details); diff --git a/packages/phrases/src/locales/es/translation/admin-console/organization-details.ts b/packages/phrases/src/locales/es/translation/admin-console/organization-details.ts index d1b8e56bd60..6673e2ee834 100644 --- a/packages/phrases/src/locales/es/translation/admin-console/organization-details.ts +++ b/packages/phrases/src/locales/es/translation/admin-console/organization-details.ts @@ -22,6 +22,13 @@ const organization_details = { 'Una vez eliminado, el usuario perderá su membresía y roles en esta organización. Esta acción no se puede deshacer.', search_user_placeholder: 'Buscar por nombre, correo electrónico, teléfono o ID de usuario', at_least_one_user: 'Se requiere al menos un usuario.', + /** UNTRANSLATED */ + custom_data: 'Custom data', + /** UNTRANSLATED */ + custom_data_tip: + 'Custom data is a JSON object that can be used to store additional data associated with the organization.', + /** UNTRANSLATED */ + invalid_json_object: 'Invalid JSON object.', }; export default Object.freeze(organization_details); diff --git a/packages/phrases/src/locales/fr/translation/admin-console/organization-details.ts b/packages/phrases/src/locales/fr/translation/admin-console/organization-details.ts index 22a452f7d1c..91941b02bb7 100644 --- a/packages/phrases/src/locales/fr/translation/admin-console/organization-details.ts +++ b/packages/phrases/src/locales/fr/translation/admin-console/organization-details.ts @@ -22,6 +22,13 @@ const organization_details = { "Une fois retiré, l'utilisateur perdra son adhésion et ses rôles dans cette organisation. Cette action ne peut pas être annulée.", search_user_placeholder: "Rechercher par nom, e-mail, téléphone ou identifiant d'utilisateur", at_least_one_user: 'Au moins un utilisateur est requis.', + /** UNTRANSLATED */ + custom_data: 'Custom data', + /** UNTRANSLATED */ + custom_data_tip: + 'Custom data is a JSON object that can be used to store additional data associated with the organization.', + /** UNTRANSLATED */ + invalid_json_object: 'Invalid JSON object.', }; export default Object.freeze(organization_details); diff --git a/packages/phrases/src/locales/it/translation/admin-console/organization-details.ts b/packages/phrases/src/locales/it/translation/admin-console/organization-details.ts index 98ac34e32c3..4700c52b144 100644 --- a/packages/phrases/src/locales/it/translation/admin-console/organization-details.ts +++ b/packages/phrases/src/locales/it/translation/admin-console/organization-details.ts @@ -22,6 +22,13 @@ const organization_details = { "Una volta rimosso, l'utente perderà la sua iscrizione e i ruoli in questa organizzazione. Quest'azione non può essere annullata.", search_user_placeholder: 'Cerca per nome, email, telefono o ID utente', at_least_one_user: 'È richiesto almeno un utente.', + /** UNTRANSLATED */ + custom_data: 'Custom data', + /** UNTRANSLATED */ + custom_data_tip: + 'Custom data is a JSON object that can be used to store additional data associated with the organization.', + /** UNTRANSLATED */ + invalid_json_object: 'Invalid JSON object.', }; export default Object.freeze(organization_details); diff --git a/packages/phrases/src/locales/ja/translation/admin-console/organization-details.ts b/packages/phrases/src/locales/ja/translation/admin-console/organization-details.ts index 271af6c2975..be29978c504 100644 --- a/packages/phrases/src/locales/ja/translation/admin-console/organization-details.ts +++ b/packages/phrases/src/locales/ja/translation/admin-console/organization-details.ts @@ -22,6 +22,13 @@ const organization_details = { '削除すると、ユーザーは組織内のメンバーシップとロールを失います。この操作は元に戻せません。', search_user_placeholder: '名前、メール、電話番号、またはユーザーIDで検索', at_least_one_user: '少なくとも1人のユーザーが必要です。', + /** UNTRANSLATED */ + custom_data: 'Custom data', + /** UNTRANSLATED */ + custom_data_tip: + 'Custom data is a JSON object that can be used to store additional data associated with the organization.', + /** UNTRANSLATED */ + invalid_json_object: 'Invalid JSON object.', }; export default Object.freeze(organization_details); diff --git a/packages/phrases/src/locales/ko/translation/admin-console/organization-details.ts b/packages/phrases/src/locales/ko/translation/admin-console/organization-details.ts index bf4212da66a..862aefaacfa 100644 --- a/packages/phrases/src/locales/ko/translation/admin-console/organization-details.ts +++ b/packages/phrases/src/locales/ko/translation/admin-console/organization-details.ts @@ -22,6 +22,13 @@ const organization_details = { '제거하면 사용자가 이 조직에서 멤버십과 역할을 잃습니다. 이 작업은 취소할 수 없습니다.', search_user_placeholder: '이름, 이메일, 전화 또는 사용자 ID로 검색', at_least_one_user: '최소한 한 명의 사용자가 필요합니다.', + /** UNTRANSLATED */ + custom_data: 'Custom data', + /** UNTRANSLATED */ + custom_data_tip: + 'Custom data is a JSON object that can be used to store additional data associated with the organization.', + /** UNTRANSLATED */ + invalid_json_object: 'Invalid JSON object.', }; export default Object.freeze(organization_details); diff --git a/packages/phrases/src/locales/pl-pl/translation/admin-console/organization-details.ts b/packages/phrases/src/locales/pl-pl/translation/admin-console/organization-details.ts index ae82eb0b208..b751f2a1edd 100644 --- a/packages/phrases/src/locales/pl-pl/translation/admin-console/organization-details.ts +++ b/packages/phrases/src/locales/pl-pl/translation/admin-console/organization-details.ts @@ -23,6 +23,13 @@ const organization_details = { search_user_placeholder: 'Wyszukaj według nazwy, adresu e-mail, numeru telefonu lub identyfikatora użytkownika', at_least_one_user: 'Wymagany jest co najmniej jeden użytkownik.', + /** UNTRANSLATED */ + custom_data: 'Custom data', + /** UNTRANSLATED */ + custom_data_tip: + 'Custom data is a JSON object that can be used to store additional data associated with the organization.', + /** UNTRANSLATED */ + invalid_json_object: 'Invalid JSON object.', }; export default Object.freeze(organization_details); diff --git a/packages/phrases/src/locales/pt-br/translation/admin-console/organization-details.ts b/packages/phrases/src/locales/pt-br/translation/admin-console/organization-details.ts index 3616ab28a79..22e2533abed 100644 --- a/packages/phrases/src/locales/pt-br/translation/admin-console/organization-details.ts +++ b/packages/phrases/src/locales/pt-br/translation/admin-console/organization-details.ts @@ -22,6 +22,13 @@ const organization_details = { 'Uma vez removido, o usuário perderá sua associação e cargos nesta organização. Essa ação não pode ser desfeita.', search_user_placeholder: 'Pesquisar por nome, e-mail, telefone ou ID do usuário', at_least_one_user: 'Pelo menos um usuário é necessário.', + /** UNTRANSLATED */ + custom_data: 'Custom data', + /** UNTRANSLATED */ + custom_data_tip: + 'Custom data is a JSON object that can be used to store additional data associated with the organization.', + /** UNTRANSLATED */ + invalid_json_object: 'Invalid JSON object.', }; export default Object.freeze(organization_details); diff --git a/packages/phrases/src/locales/pt-pt/translation/admin-console/organization-details.ts b/packages/phrases/src/locales/pt-pt/translation/admin-console/organization-details.ts index 207a1143d1d..5255a7b50ab 100644 --- a/packages/phrases/src/locales/pt-pt/translation/admin-console/organization-details.ts +++ b/packages/phrases/src/locales/pt-pt/translation/admin-console/organization-details.ts @@ -22,6 +22,13 @@ const organization_details = { 'Uma vez removido, o utilizador perderá a sua adesão e funções nesta organização. Esta ação não pode ser desfeita.', search_user_placeholder: 'Pesquisar por nome, email, telefone ou ID de utilizador', at_least_one_user: 'Pelo menos um utilizador é necessário.', + /** UNTRANSLATED */ + custom_data: 'Custom data', + /** UNTRANSLATED */ + custom_data_tip: + 'Custom data is a JSON object that can be used to store additional data associated with the organization.', + /** UNTRANSLATED */ + invalid_json_object: 'Invalid JSON object.', }; export default Object.freeze(organization_details); diff --git a/packages/phrases/src/locales/ru/translation/admin-console/organization-details.ts b/packages/phrases/src/locales/ru/translation/admin-console/organization-details.ts index 4a7584a9d7b..de25fb2be3a 100644 --- a/packages/phrases/src/locales/ru/translation/admin-console/organization-details.ts +++ b/packages/phrases/src/locales/ru/translation/admin-console/organization-details.ts @@ -23,6 +23,13 @@ const organization_details = { search_user_placeholder: 'Поиск по имени, электронной почте, телефону или идентификатору пользователя', at_least_one_user: 'Необходимо указать хотя бы одного пользователя.', + /** UNTRANSLATED */ + custom_data: 'Custom data', + /** UNTRANSLATED */ + custom_data_tip: + 'Custom data is a JSON object that can be used to store additional data associated with the organization.', + /** UNTRANSLATED */ + invalid_json_object: 'Invalid JSON object.', }; export default Object.freeze(organization_details); diff --git a/packages/phrases/src/locales/tr-tr/translation/admin-console/organization-details.ts b/packages/phrases/src/locales/tr-tr/translation/admin-console/organization-details.ts index 7db9f15fb69..ab35a49b5fd 100644 --- a/packages/phrases/src/locales/tr-tr/translation/admin-console/organization-details.ts +++ b/packages/phrases/src/locales/tr-tr/translation/admin-console/organization-details.ts @@ -22,6 +22,13 @@ const organization_details = { 'Kaldırıldığında, kullanıcı bu kuruluşta üyeliğini ve rollerini kaybedecek. Bu işlem geri alınamaz.', search_user_placeholder: 'İsim, e-posta, telefon veya kullanıcı kimliği ile ara', at_least_one_user: 'En az bir kullanıcı gereklidir.', + /** UNTRANSLATED */ + custom_data: 'Custom data', + /** UNTRANSLATED */ + custom_data_tip: + 'Custom data is a JSON object that can be used to store additional data associated with the organization.', + /** UNTRANSLATED */ + invalid_json_object: 'Invalid JSON object.', }; export default Object.freeze(organization_details); diff --git a/packages/phrases/src/locales/zh-cn/translation/admin-console/organization-details.ts b/packages/phrases/src/locales/zh-cn/translation/admin-console/organization-details.ts index 9cf6816583d..9a8b58a7e9f 100644 --- a/packages/phrases/src/locales/zh-cn/translation/admin-console/organization-details.ts +++ b/packages/phrases/src/locales/zh-cn/translation/admin-console/organization-details.ts @@ -21,6 +21,13 @@ const organization_details = { '一旦移除,用户将失去他们在这个机构中的成员资格和角色。此操作将无法撤销。', search_user_placeholder: '按名称、电子邮件、电话或用户ID搜索', at_least_one_user: '至少需要一个用户。', + /** UNTRANSLATED */ + custom_data: 'Custom data', + /** UNTRANSLATED */ + custom_data_tip: + 'Custom data is a JSON object that can be used to store additional data associated with the organization.', + /** UNTRANSLATED */ + invalid_json_object: 'Invalid JSON object.', }; export default Object.freeze(organization_details); diff --git a/packages/phrases/src/locales/zh-hk/translation/admin-console/organization-details.ts b/packages/phrases/src/locales/zh-hk/translation/admin-console/organization-details.ts index 2bee6720d02..7e39f50f3c0 100644 --- a/packages/phrases/src/locales/zh-hk/translation/admin-console/organization-details.ts +++ b/packages/phrases/src/locales/zh-hk/translation/admin-console/organization-details.ts @@ -20,6 +20,13 @@ const organization_details = { '移除後,使用者將失去他們在此組織的成員資格和角色。此操作無法撤銷。', search_user_placeholder: '按姓名、電子郵件、電話或使用者 ID 搜尋', at_least_one_user: '至少需要一名使用者。', + /** UNTRANSLATED */ + custom_data: 'Custom data', + /** UNTRANSLATED */ + custom_data_tip: + 'Custom data is a JSON object that can be used to store additional data associated with the organization.', + /** UNTRANSLATED */ + invalid_json_object: 'Invalid JSON object.', }; export default Object.freeze(organization_details); diff --git a/packages/phrases/src/locales/zh-tw/translation/admin-console/organization-details.ts b/packages/phrases/src/locales/zh-tw/translation/admin-console/organization-details.ts index cd0acd5325f..b5f7409361d 100644 --- a/packages/phrases/src/locales/zh-tw/translation/admin-console/organization-details.ts +++ b/packages/phrases/src/locales/zh-tw/translation/admin-console/organization-details.ts @@ -20,6 +20,13 @@ const organization_details = { '刪除後,用戶將失去在這個組織中的成員資格和角色。此操作無法撤銷。', search_user_placeholder: '按名稱、電子郵件、電話或用戶ID搜尋', at_least_one_user: '至少需要一個用戶。', + /** UNTRANSLATED */ + custom_data: 'Custom data', + /** UNTRANSLATED */ + custom_data_tip: + 'Custom data is a JSON object that can be used to store additional data associated with the organization.', + /** UNTRANSLATED */ + invalid_json_object: 'Invalid JSON object.', }; export default Object.freeze(organization_details); diff --git a/packages/schemas/alterations/next-1713942039-add-organization-custom-data.ts b/packages/schemas/alterations/next-1713942039-add-organization-custom-data.ts new file mode 100644 index 00000000000..99c61909040 --- /dev/null +++ b/packages/schemas/alterations/next-1713942039-add-organization-custom-data.ts @@ -0,0 +1,25 @@ +import { sql } from '@silverhand/slonik'; + +import type { AlterationScript } from '../lib/types/alteration.js'; + +/** The alteration script to add the `custom_data` field to the `organizations` table. */ +const alteration: AlterationScript = { + up: async (pool) => { + await pool.query( + sql` + alter table organizations + add column custom_data jsonb not null default '{}'::jsonb; + ` + ); + }, + down: async (pool) => { + await pool.query( + sql` + alter table organizations + drop column custom_data; + ` + ); + }, +}; + +export default alteration; diff --git a/packages/schemas/tables/organizations.sql b/packages/schemas/tables/organizations.sql index e8484634e67..0ac9d020e1a 100644 --- a/packages/schemas/tables/organizations.sql +++ b/packages/schemas/tables/organizations.sql @@ -10,6 +10,8 @@ create table organizations ( name varchar(128) not null, /** A brief description of the organization. */ description varchar(256), + /** Additional data associated with the organization. */ + custom_data jsonb /* @use JsonObject */ not null default '{}'::jsonb, /** When the organization was created. */ created_at timestamptz not null default(now()), primary key (id) From 204e087519a0ee8a1fc7ee13a70a11689c7098e7 Mon Sep 17 00:00:00 2001 From: simeng-li Date: Fri, 26 Apr 2024 10:52:14 +0800 Subject: [PATCH 330/687] chore: add code coverage token (#5792) add code coverage token --- .github/workflows/main.yml | 2 ++ .github/workflows/master-codecov-report.yml | 2 ++ 2 files changed, 4 insertions(+) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index cf4bbafcb65..dcbed207d85 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -66,12 +66,14 @@ jobs: with: flags: core directory: ./packages/core + token: ${{ secrets.CODECOV_TOKEN }} - name: Codecov ui uses: codecov/codecov-action@v4 with: flags: ui directory: ./packages/ui + token: ${{ secrets.CODECOV_TOKEN }} main-dockerize: runs-on: ubuntu-latest diff --git a/.github/workflows/master-codecov-report.yml b/.github/workflows/master-codecov-report.yml index fedeedcd65a..8c8aa00f388 100644 --- a/.github/workflows/master-codecov-report.yml +++ b/.github/workflows/master-codecov-report.yml @@ -27,9 +27,11 @@ jobs: with: flags: core directory: ./packages/core + token: ${{ secrets.CODECOV_TOKEN }} - name: Codecov UI uses: codecov/codecov-action@v4 with: flags: experience directory: ./packages/experience + token: ${{ secrets.CODECOV_TOKEN }} From b80934ac5c054f0f9c149ffdddb3fde50614d330 Mon Sep 17 00:00:00 2001 From: Gao Sun Date: Sat, 27 Apr 2024 23:27:33 +0800 Subject: [PATCH 331/687] fix(experience): use correct callback path for native environments (#5800) --- .changeset/funny-books-sell.md | 9 +++++++++ .../containers/SocialSignInList/use-social.ts | 2 +- .../src/hooks/use-single-sign-on.ts | 2 +- .../SocialSignInWebCallback/index.test.tsx | 20 +++++++++---------- 4 files changed, 21 insertions(+), 12 deletions(-) create mode 100644 .changeset/funny-books-sell.md diff --git a/.changeset/funny-books-sell.md b/.changeset/funny-books-sell.md new file mode 100644 index 00000000000..8a3a3032397 --- /dev/null +++ b/.changeset/funny-books-sell.md @@ -0,0 +1,9 @@ +--- +"@logto/experience": patch +--- + +fix native social sign-in callback + +In a native environment, the social sign-in callback that posts to the native container (e.g. WKWebView in iOS) was wrong. + +This was introduced by a refactor in #5536: It updated the callback path from `/sign-in/social/:connectorId` to `/callback/social/:connectorId`. However, the function to post the message to the native container was not updated accordingly. diff --git a/packages/experience/src/containers/SocialSignInList/use-social.ts b/packages/experience/src/containers/SocialSignInList/use-social.ts index 69733cb8a77..ce70d5ec444 100644 --- a/packages/experience/src/containers/SocialSignInList/use-social.ts +++ b/packages/experience/src/containers/SocialSignInList/use-social.ts @@ -23,7 +23,7 @@ const useSocial = () => { : redirectTo; getLogtoNativeSdk()?.getPostMessage()({ - callbackUri: `${window.location.origin}/sign-in/social/${connectorId}`, + callbackUri: `${window.location.origin}/callback/social/${connectorId}`, redirectTo: redirectUri, }); }, []); diff --git a/packages/experience/src/hooks/use-single-sign-on.ts b/packages/experience/src/hooks/use-single-sign-on.ts index 20c6255f3ff..751ba725f48 100644 --- a/packages/experience/src/hooks/use-single-sign-on.ts +++ b/packages/experience/src/hooks/use-single-sign-on.ts @@ -25,7 +25,7 @@ const useSingleSignOn = () => { ).toString(); getLogtoNativeSdk()?.getPostMessage()({ - callbackUri: `${window.location.origin}/sign-in/social/${connectorId}`, + callbackUri: `${window.location.origin}/callback/social/${connectorId}`, redirectTo: redirectUri, }); }, []); diff --git a/packages/experience/src/pages/SocialSignInWebCallback/index.test.tsx b/packages/experience/src/pages/SocialSignInWebCallback/index.test.tsx index 8f31efccae8..8009817c281 100644 --- a/packages/experience/src/pages/SocialSignInWebCallback/index.test.tsx +++ b/packages/experience/src/pages/SocialSignInWebCallback/index.test.tsx @@ -42,10 +42,10 @@ describe('SocialCallbackPage with code', () => { renderWithPageContext( - } /> + } /> , - { initialEntries: ['/sign-in/social/invalid'] } + { initialEntries: ['/callback/social/invalid'] } ); await waitFor(() => { @@ -69,10 +69,10 @@ describe('SocialCallbackPage with code', () => { renderWithPageContext( - } /> + } /> , - { initialEntries: [`/sign-in/social/${connectorId}`] } + { initialEntries: [`/callback/social/${connectorId}`] } ); await waitFor(() => { @@ -91,10 +91,10 @@ describe('SocialCallbackPage with code', () => { renderWithPageContext( - } /> + } /> , - { initialEntries: [`/sign-in/social/${connectorId}`] } + { initialEntries: [`/callback/social/${connectorId}`] } ); await waitFor(() => { @@ -122,10 +122,10 @@ describe('SocialCallbackPage with code', () => { renderWithPageContext( - } /> + } /> , - { initialEntries: [`/sign-in/social/${connectorId}`] } + { initialEntries: [`/callback/social/${connectorId}`] } ); await waitFor(() => { @@ -144,10 +144,10 @@ describe('SocialCallbackPage with code', () => { renderWithPageContext( - } /> + } /> , - { initialEntries: [`/sign-in/social/${connectorId}`] } + { initialEntries: [`/callback/social/${connectorId}`] } ); await waitFor(() => { From c92acffb75f67297640f088529a2209c38790482 Mon Sep 17 00:00:00 2001 From: simeng-li Date: Sun, 28 Apr 2024 10:24:31 +0800 Subject: [PATCH 332/687] refactor(console): remove useless log title definitions (#5798) remove useless log title definitions --- packages/console/src/consts/logs.ts | 61 ++++------------------------- 1 file changed, 7 insertions(+), 54 deletions(-) diff --git a/packages/console/src/consts/logs.ts b/packages/console/src/consts/logs.ts index 0156bf85266..7bcc1cf74f4 100644 --- a/packages/console/src/consts/logs.ts +++ b/packages/console/src/consts/logs.ts @@ -1,12 +1,12 @@ -import type { AuditLogKey, WebhookLogKey, JwtCustomizerLogKey, LogKey } from '@logto/schemas'; +import type { AuditLogKey, LogKey } from '@logto/schemas'; import { type Optional } from '@silverhand/essentials'; -export const auditLogEventTitle: Record> & - Record> = Object.freeze({ +export const auditLogEventTitle: Record> & { + [key in AuditLogKey]?: string; +} = Object.freeze({ 'ExchangeTokenBy.AuthorizationCode': 'Exchange token by Code', 'ExchangeTokenBy.ClientCredentials': 'Exchange token by Client Credentials', 'ExchangeTokenBy.RefreshToken': 'Exchange token by Refresh Token', - 'ExchangeTokenBy.Unknown': undefined, 'Interaction.Create': 'Interaction started', 'Interaction.End': 'Interaction ended', 'Interaction.ForgotPassword.Identifier.VerificationCode.Create': @@ -18,15 +18,6 @@ export const auditLogEventTitle: Record> & 'Interaction.ForgotPassword.Profile.Update': 'Patch update forgot-password interaction profile', 'Interaction.ForgotPassword.Submit': 'Submit forgot-password interaction', 'Interaction.ForgotPassword.Update': 'Update forgot-password interaction', - 'Interaction.ForgotPassword.BindMfa.Totp.Create': undefined, - 'Interaction.ForgotPassword.BindMfa.Totp.Submit': undefined, - 'Interaction.ForgotPassword.BindMfa.BackupCode.Create': undefined, - 'Interaction.ForgotPassword.BindMfa.BackupCode.Submit': undefined, - 'Interaction.ForgotPassword.BindMfa.WebAuthn.Create': undefined, - 'Interaction.ForgotPassword.BindMfa.WebAuthn.Submit': undefined, - 'Interaction.Register.Identifier.Password.Submit': undefined, - 'Interaction.Register.Identifier.Social.Create': undefined, - 'Interaction.Register.Identifier.Social.Submit': undefined, 'Interaction.Register.Identifier.VerificationCode.Create': 'Create and send register identifier with verification code', 'Interaction.Register.Identifier.VerificationCode.Submit': @@ -36,14 +27,6 @@ export const auditLogEventTitle: Record> & 'Interaction.Register.Profile.Update': 'Patch update register interaction profile', 'Interaction.Register.Submit': 'Submit register interaction', 'Interaction.Register.Update': 'Update register interaction', - 'Interaction.Register.BindMfa.Totp.Create': undefined, - 'Interaction.Register.BindMfa.Totp.Submit': undefined, - 'Interaction.Register.BindMfa.BackupCode.Create': undefined, - 'Interaction.Register.BindMfa.BackupCode.Submit': undefined, - 'Interaction.Register.BindMfa.WebAuthn.Create': undefined, - 'Interaction.Register.BindMfa.WebAuthn.Submit': undefined, - 'Interaction.Register.SingleSignOn.Create': undefined, - 'Interaction.Register.SingleSignOn.Submit': undefined, 'Interaction.SignIn.Identifier.Password.Submit': 'Submit sign-in identifier with password', 'Interaction.SignIn.Identifier.Social.Create': 'Create social sign-in authorization-url', 'Interaction.SignIn.Identifier.Social.Submit': 'Authenticate and submit social identifier', @@ -56,44 +39,14 @@ export const auditLogEventTitle: Record> & 'Interaction.SignIn.Profile.Update': 'Patch Update sign-in interaction profile', 'Interaction.SignIn.Submit': 'Submit sign-in interaction', 'Interaction.SignIn.Update': 'Update sign-in interaction', - 'Interaction.SignIn.BindMfa.Totp.Create': undefined, - 'Interaction.SignIn.BindMfa.Totp.Submit': undefined, - 'Interaction.SignIn.BindMfa.BackupCode.Create': undefined, - 'Interaction.SignIn.BindMfa.BackupCode.Submit': undefined, - 'Interaction.SignIn.BindMfa.WebAuthn.Create': undefined, - 'Interaction.SignIn.BindMfa.WebAuthn.Submit': undefined, - 'Interaction.SignIn.Mfa.Totp.Create': undefined, - 'Interaction.SignIn.Mfa.Totp.Submit': undefined, - 'Interaction.SignIn.Mfa.BackupCode.Create': undefined, - 'Interaction.SignIn.Mfa.BackupCode.Submit': undefined, - 'Interaction.SignIn.Mfa.WebAuthn.Create': undefined, - 'Interaction.SignIn.Mfa.WebAuthn.Submit': undefined, 'Interaction.SignIn.Identifier.SingleSignOn.Create': 'Create single-sign-on authentication session', 'Interaction.SignIn.Identifier.SingleSignOn.Submit': 'Submit single-sign-on authentication interaction', - 'Interaction.Register.Identifier.SingleSignOn.Create': undefined, - 'Interaction.Register.Identifier.SingleSignOn.Submit': undefined, - RevokeToken: undefined, - Unknown: undefined, }); -// `webhookLogEventTitle` and `logEventTitle` are not used yet, keep them just in case. -const webhookLogEventTitle: Record> & - Record> = Object.freeze({ - 'TriggerHook.PostRegister': undefined, - 'TriggerHook.PostResetPassword': undefined, - 'TriggerHook.PostSignIn': undefined, -}); - -const jwtCustomizerLogEventTitle: Record> & - Record> = Object.freeze({ - 'JwtCustomizer.AccessToken': undefined, - 'JwtCustomizer.ClientCredentials': undefined, -}); - -export const logEventTitle: Record> & Record> = { +export const logEventTitle: Record> & { + [key in LogKey]?: string; +} = { ...auditLogEventTitle, - ...webhookLogEventTitle, - ...jwtCustomizerLogEventTitle, }; From aec6c779b2e4f4ccf535a35f9b685ef5bcbd1880 Mon Sep 17 00:00:00 2001 From: wangsijie Date: Sun, 28 Apr 2024 11:06:37 +0800 Subject: [PATCH 333/687] fix(core): fix status code of create new user api (#5735) --- packages/core/src/routes/admin-user/basics.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/core/src/routes/admin-user/basics.ts b/packages/core/src/routes/admin-user/basics.ts index 7c7065a28f9..710bbfe149b 100644 --- a/packages/core/src/routes/admin-user/basics.ts +++ b/packages/core/src/routes/admin-user/basics.ts @@ -153,7 +153,7 @@ export default function adminUserBasicsRoutes( profile: userProfileGuard, }).partial(), response: userProfileResponseGuard, - status: [200, 404, 422], + status: [200, 400, 404, 422], }), async (ctx, next) => { const { From bbd399e157b53125d084da15149d505822285f1f Mon Sep 17 00:00:00 2001 From: simeng-li Date: Sun, 28 Apr 2024 11:24:15 +0800 Subject: [PATCH 334/687] fix(experience,core): fix SSO register hook event not triggering bug (#5796) * fix(experience,core): fix SSO register hook event not triggering bug fix the SSO register hook event not triggering bug * chore: update changeset content update changeset content --- .changeset/nine-turtles-learn.md | 29 +++++++++++++++++++ .../src/routes/interaction/single-sign-on.ts | 10 +------ packages/experience/src/apis/interaction.ts | 9 +++--- .../experience/src/apis/single-sign-on.ts | 16 ++++++++-- 4 files changed, 48 insertions(+), 16 deletions(-) create mode 100644 .changeset/nine-turtles-learn.md diff --git a/.changeset/nine-turtles-learn.md b/.changeset/nine-turtles-learn.md new file mode 100644 index 00000000000..fe141d1fa67 --- /dev/null +++ b/.changeset/nine-turtles-learn.md @@ -0,0 +1,29 @@ +--- +"@logto/experience": patch +"@logto/core": patch +--- + +fix the new user from SSO register hook event not triggering bug + +### Issue + +When a new user registers via SSO, the `PostRegister` interaction hook event is not triggered. `PostSignIn` event is mistakenly triggered instead. + +### Root Cause + +In the SSO `post /api/interaction/sso/:connectionId/registration` API, we update the interaction event to `Register`. +However, the hook middleware reads the event from interaction session ahead of the API logic, and the event is not updated resulting in the wrong event being triggered. + +In the current interaction API design, we should mutate the interaction event by calling the `PUT /api/interaction/event` API, instead of updating the event directly in the submit interaction APIs. (Just like the no direct mutation rule for a react state). So we can ensure the correct side effect like logs and hooks are triggered properly. + +All the other sign-in methods are using the `PUT /api/interaction/event` API to update the event. But when implementing the SSO registration API, we were trying to reduce the API requests and directly updated the event in the registration API which will submit the interaction directly. + +### Solution + +Remove the event update logic in the SSO registration API and call the `PUT /api/interaction/event` API to update the event. +This will ensure the correct event is triggered in the hook middleware. + +### Action Items + +Align the current interaction API design for now. +Need to improve the session/interaction API logic to simplify the whole process. diff --git a/packages/core/src/routes/interaction/single-sign-on.ts b/packages/core/src/routes/interaction/single-sign-on.ts index 99faf43e1db..e02dac16031 100644 --- a/packages/core/src/routes/interaction/single-sign-on.ts +++ b/packages/core/src/routes/interaction/single-sign-on.ts @@ -18,8 +18,8 @@ import { getInteractionStorage, storeInteractionResult } from './utils/interacti import { getSingleSignOnAuthenticationResult } from './utils/single-sign-on-session.js'; import { authorizationUrlPayloadGuard, - getSsoAuthorizationUrl, getSsoAuthentication, + getSsoAuthorizationUrl, handleSsoAuthentication, registerWithSsoAuthentication, } from './utils/single-sign-on.js'; @@ -134,7 +134,6 @@ export default function singleSignOnRoutes( koaInteractionHooks(libraries), async (ctx, next) => { const { - createLog, assignInteractionHookResult, guard: { params }, } = ctx; @@ -147,13 +146,6 @@ export default function singleSignOnRoutes( new RequestError({ code: 'auth.forbidden', status: 403 }) ); - const registerEventUpdateLog = createLog(`Interaction.Register.Update`); - registerEventUpdateLog.append({ event: 'register' }); - - // Update the interaction session event to register if no related user account found. - // Set the merge flag to true to merge the register event with the existing sso interaction session - await storeInteractionResult({ event: InteractionEvent.Register }, ctx, provider, true); - // Throw 404 if no related session found const authenticationResult = await getSingleSignOnAuthenticationResult( ctx, diff --git a/packages/experience/src/apis/interaction.ts b/packages/experience/src/apis/interaction.ts index 1763ce40fd0..35470c2db59 100644 --- a/packages/experience/src/apis/interaction.ts +++ b/packages/experience/src/apis/interaction.ts @@ -2,22 +2,23 @@ import { InteractionEvent, - type SignInIdentifier, + type BindMfaPayload, type EmailVerificationCodePayload, type PhoneVerificationCodePayload, + type SignInIdentifier, type SocialConnectorPayload, type SocialEmailPayload, type SocialPhonePayload, - type BindMfaPayload, type VerifyMfaPayload, - type WebAuthnRegistrationOptions, type WebAuthnAuthenticationOptions, + type WebAuthnRegistrationOptions, } from '@logto/schemas'; import { conditional } from '@silverhand/essentials'; import api from './api'; -const interactionPrefix = '/api/interaction'; +export const interactionPrefix = '/api/interaction'; + const verificationPath = `verification`; type Response = { diff --git a/packages/experience/src/apis/single-sign-on.ts b/packages/experience/src/apis/single-sign-on.ts index d8a2eab282d..12d5c80e2fc 100644 --- a/packages/experience/src/apis/single-sign-on.ts +++ b/packages/experience/src/apis/single-sign-on.ts @@ -1,6 +1,9 @@ +import { InteractionEvent } from '@logto/schemas'; + import api from './api'; +import { interactionPrefix } from './interaction'; -const ssoPrefix = '/api/interaction/single-sign-on'; +const ssoPrefix = `${interactionPrefix}/single-sign-on`; type Response = { redirectTo: string; @@ -39,5 +42,12 @@ export const singleSignOnAuthorization = async (connectorId: string, payload: un }) .json(); -export const singleSignOnRegistration = async (connectorId: string) => - api.post(`${ssoPrefix}/${connectorId}/registration`).json(); +export const singleSignOnRegistration = async (connectorId: string) => { + await api.put(`${interactionPrefix}/event`, { + json: { + event: InteractionEvent.Register, + }, + }); + + return api.post(`${ssoPrefix}/${connectorId}/registration`).json(); +}; From 24acae8709b821e1694c22b2c259eef51a2f4e69 Mon Sep 17 00:00:00 2001 From: wangsijie Date: Mon, 29 Apr 2024 10:48:02 +0800 Subject: [PATCH 335/687] feat(schemas): add table for app org resource scope consent (#5803) feat(schemas): add table application_user_consent_organization_resource_scopes --- ...14270244-application-org-resource-scope.ts | 32 +++++++++++++++++++ ...r_consent_organization_resource_scopes.sql | 18 +++++++++++ 2 files changed, 50 insertions(+) create mode 100644 packages/schemas/alterations/next-1714270244-application-org-resource-scope.ts create mode 100644 packages/schemas/tables/application_user_consent_organization_resource_scopes.sql diff --git a/packages/schemas/alterations/next-1714270244-application-org-resource-scope.ts b/packages/schemas/alterations/next-1714270244-application-org-resource-scope.ts new file mode 100644 index 00000000000..ceede1619c8 --- /dev/null +++ b/packages/schemas/alterations/next-1714270244-application-org-resource-scope.ts @@ -0,0 +1,32 @@ +import { sql } from '@silverhand/slonik'; + +import type { AlterationScript } from '../lib/types/alteration.js'; + +import { applyTableRls, dropTableRls } from './utils/1704934999-tables.js'; + +const alteration: AlterationScript = { + up: async (pool) => { + await pool.query(sql` + create table application_user_consent_organization_resource_scopes ( + tenant_id varchar(21) not null + references tenants (id) on update cascade on delete cascade, + /** The globally unique identifier of the application. */ + application_id varchar(21) not null + references applications (id) on update cascade on delete cascade, + /** The globally unique identifier of the resource scope. */ + scope_id varchar(21) not null + references scopes (id) on update cascade on delete cascade, + primary key (application_id, scope_id) + ); + `); + await applyTableRls(pool, 'application_user_consent_organization_resource_scopes'); + }, + down: async (pool) => { + await dropTableRls(pool, 'application_user_consent_organization_resource_scopes'); + await pool.query(sql` + drop table application_user_consent_organization_resource_scopes + `); + }, +}; + +export default alteration; diff --git a/packages/schemas/tables/application_user_consent_organization_resource_scopes.sql b/packages/schemas/tables/application_user_consent_organization_resource_scopes.sql new file mode 100644 index 00000000000..c72b9338663 --- /dev/null +++ b/packages/schemas/tables/application_user_consent_organization_resource_scopes.sql @@ -0,0 +1,18 @@ +/* init_order = 3 */ + +/** + The organization resource scopes (permissions) assigned to an application's consent request. + This is different from the application_user_consent_resource_scopes table, scopes in this table + is granted by the organization roles. +*/ +create table application_user_consent_organization_resource_scopes ( + tenant_id varchar(21) not null + references tenants (id) on update cascade on delete cascade, + /** The globally unique identifier of the application. */ + application_id varchar(21) not null + references applications (id) on update cascade on delete cascade, + /** The globally unique identifier of the resource scope. */ + scope_id varchar(21) not null + references scopes (id) on update cascade on delete cascade, + primary key (application_id, scope_id) +); From 224723413a9e190fe57027fc8a76204830a58546 Mon Sep 17 00:00:00 2001 From: Kamto Date: Mon, 29 Apr 2024 15:35:25 +0800 Subject: [PATCH 336/687] fix: remove the plus sign in front of the phone number (#5801) --- packages/connectors/connector-feishu-web/src/index.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/connectors/connector-feishu-web/src/index.ts b/packages/connectors/connector-feishu-web/src/index.ts index a2b25b2f929..56ed8cccc99 100644 --- a/packages/connectors/connector-feishu-web/src/index.ts +++ b/packages/connectors/connector-feishu-web/src/index.ts @@ -153,7 +153,7 @@ export function getUserInfo(getConfig: GetConnectorConfig): GetUserInfo { avatar, email: conditional(email), userId: conditional(user_id), - phone: conditional(mobile), + phone: conditional(mobile?.replace('+', '')), rawData: jsonGuard.parse(response.body), }; } catch (error: unknown) { From 3486b12e8618d3e2f7e558bffe8e89bb5f1dfea0 Mon Sep 17 00:00:00 2001 From: wangsijie Date: Tue, 30 Apr 2024 11:40:05 +0800 Subject: [PATCH 337/687] fix(core): fix upload file guard (#5810) fix: remove the plus sign in front of the phone number (#5801) Co-authored-by: Kamto --- .changeset/smart-melons-shop.md | 10 ++++++++++ packages/core/src/routes/user-assets.ts | 6 ++++-- 2 files changed, 14 insertions(+), 2 deletions(-) create mode 100644 .changeset/smart-melons-shop.md diff --git a/.changeset/smart-melons-shop.md b/.changeset/smart-melons-shop.md new file mode 100644 index 00000000000..e998cdef549 --- /dev/null +++ b/.changeset/smart-melons-shop.md @@ -0,0 +1,10 @@ +--- +"@logto/phrases": patch +"@logto/core": patch +--- + +Fix file upload API. + +The `koa-body` has been upgraded to the latest version, which caused the file upload API to break. This change fixes the issue. + +The `ctx.request.files.file` in the new version is an array, so the code has been updated to pick the first one. diff --git a/packages/core/src/routes/user-assets.ts b/packages/core/src/routes/user-assets.ts index 9eb0c054597..19c155bccb1 100644 --- a/packages/core/src/routes/user-assets.ts +++ b/packages/core/src/routes/user-assets.ts @@ -52,13 +52,15 @@ export default function userAssetsRoutes( '/user-assets', koaGuard({ files: object({ - file: uploadFileGuard, + file: uploadFileGuard.array().min(1), }), response: userAssetsGuard, }), async (ctx, next) => { - const { file } = ctx.guard.files; + const { file: bodyFiles } = ctx.guard.files; + const file = bodyFiles[0]; + assertThat(file, 'guard.invalid_input'); assertThat(file.size <= maxUploadFileSize, 'guard.file_size_exceeded'); assertThat( allowUploadMimeTypes.map(String).includes(file.mimetype), From 2e96eea60c77a2f6f6b3c07fe8a82c0313047bca Mon Sep 17 00:00:00 2001 From: Gao Sun Date: Tue, 30 Apr 2024 14:51:14 +0800 Subject: [PATCH 338/687] refactor: update plausible domain (#5799) refactor: update plausible domain --- packages/console/src/components/Conversion/utils.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/console/src/components/Conversion/utils.ts b/packages/console/src/components/Conversion/utils.ts index d63b052daba..d74ee5f38db 100644 --- a/packages/console/src/components/Conversion/utils.ts +++ b/packages/console/src/components/Conversion/utils.ts @@ -13,7 +13,7 @@ export enum GtagConversionId { } export const redditPixelId = 't2_ggt11omdo'; -export const plausibleDataDomain = 'cloud.logto.io'; +export const plausibleDataDomain = 'logto.io'; const logtoProductionHostname = 'logto.io'; From 5adf3dfad795d3a0a06dbb32cfeb7bf50b5ba223 Mon Sep 17 00:00:00 2001 From: wangsijie Date: Tue, 30 Apr 2024 15:09:13 +0800 Subject: [PATCH 339/687] feat(core,schemas): add CRUD for consent organization resource scopes (#5804) feat(core,schemas): add crud for user consent organization resource scopes --- .../constants.ts | 5 ++ .../use-application-scopes-assignment.ts | 2 + packages/core/src/libraries/application.ts | 53 +++++++++++++--- .../application-user-consent-scopes.ts | 10 +++ packages/core/src/queries/application.ts | 3 + ...pplication-user-consent-scope.openapi.json | 6 ++ .../application-user-consent-scope.ts | 46 +++++++++----- .../src/api/application-user-consent-scope.ts | 1 + .../application-user-consent-scope.test.ts | 62 +++++++++++++++++++ packages/schemas/src/types/application.ts | 16 +++-- 10 files changed, 177 insertions(+), 27 deletions(-) diff --git a/packages/console/src/pages/ApplicationDetails/ApplicationDetailsContent/Permissions/ApplicationScopesAssignmentModal/constants.ts b/packages/console/src/pages/ApplicationDetails/ApplicationDetailsContent/Permissions/ApplicationScopesAssignmentModal/constants.ts index 87854264f22..b9cc89f6f5f 100644 --- a/packages/console/src/pages/ApplicationDetails/ApplicationDetailsContent/Permissions/ApplicationScopesAssignmentModal/constants.ts +++ b/packages/console/src/pages/ApplicationDetails/ApplicationDetailsContent/Permissions/ApplicationScopesAssignmentModal/constants.ts @@ -10,6 +10,11 @@ export const permissionTabs = Object.freeze({ title: 'application_details.permissions.api_resource', key: ApplicationUserConsentScopeType.ResourceScopes, }, + [ApplicationUserConsentScopeType.OrganizationResourceScopes]: { + // TODO @xiaoyijun: update the title + title: 'application_details.permissions.api_resource', + key: ApplicationUserConsentScopeType.OrganizationResourceScopes, + }, [ApplicationUserConsentScopeType.OrganizationScopes]: { title: 'application_details.permissions.organization', key: ApplicationUserConsentScopeType.OrganizationScopes, diff --git a/packages/console/src/pages/ApplicationDetails/ApplicationDetailsContent/Permissions/ApplicationScopesAssignmentModal/use-application-scopes-assignment.ts b/packages/console/src/pages/ApplicationDetails/ApplicationDetailsContent/Permissions/ApplicationScopesAssignmentModal/use-application-scopes-assignment.ts index 516aa1008dc..6f32c9dface 100644 --- a/packages/console/src/pages/ApplicationDetails/ApplicationDetailsContent/Permissions/ApplicationScopesAssignmentModal/use-application-scopes-assignment.ts +++ b/packages/console/src/pages/ApplicationDetails/ApplicationDetailsContent/Permissions/ApplicationScopesAssignmentModal/use-application-scopes-assignment.ts @@ -72,6 +72,8 @@ const useApplicationScopesAssignment = (applicationId: string) => { [ApplicationUserConsentScopeType.UserScopes]: userScopesAssignment, [ApplicationUserConsentScopeType.OrganizationScopes]: organizationScopesAssignment, [ApplicationUserConsentScopeType.ResourceScopes]: resourceScopesAssignment, + // TODO @xiaoyijun: Replace with correct scopes + [ApplicationUserConsentScopeType.OrganizationResourceScopes]: resourceScopesAssignment, }), [organizationScopesAssignment, resourceScopesAssignment, userScopesAssignment] ); diff --git a/packages/core/src/libraries/application.ts b/packages/core/src/libraries/application.ts index e58cdbad0e9..048cb0a659c 100644 --- a/packages/core/src/libraries/application.ts +++ b/packages/core/src/libraries/application.ts @@ -32,6 +32,7 @@ export const createApplicationLibrary = (queries: Queries) => { applications: { findApplicationById, userConsentOrganizationScopes, + userConsentOrganizationResourceScopes, userConsentResourceScopes, userConsentUserScopes, }, @@ -76,16 +77,20 @@ export const createApplicationLibrary = (queries: Queries) => { { organizationScopes = [], resourceScopes = [], + organizationResourceScopes = [], }: { organizationScopes?: string[]; resourceScopes?: string[]; + organizationResourceScopes?: string[]; }, tenantId: string ) => { - const [organizationScopesData, resourceScopesData] = await Promise.all([ - organizationScopesQuery.findByIds(organizationScopes), - findScopesByIds(resourceScopes), - ]); + const [organizationScopesData, resourceScopesData, organizationResourceScopesData] = + await Promise.all([ + organizationScopesQuery.findByIds(organizationScopes), + findScopesByIds(resourceScopes), + findScopesByIds(organizationResourceScopes), + ]); const invalidOrganizationScopes = organizationScopes.filter( (scope) => !organizationScopesData.some(({ id }) => id === scope) @@ -95,22 +100,28 @@ export const createApplicationLibrary = (queries: Queries) => { (scope) => !resourceScopesData.some(({ id }) => id === scope) ); + const invalidOrganizationResourceScopes = organizationResourceScopes.filter( + (scope) => !organizationResourceScopesData.some(({ id }) => id === scope) + ); + // Assert that all scopes exist, return the missing ones assertThat( - invalidOrganizationScopes.length === 0 && invalidResourceScopes.length === 0, + invalidOrganizationScopes.length === 0 && + invalidResourceScopes.length === 0 && + invalidOrganizationResourceScopes.length === 0, new RequestError( { code: 'application.user_consent_scopes_not_found', status: 422, }, - { invalidOrganizationScopes, invalidResourceScopes } + { invalidOrganizationScopes, invalidResourceScopes, invalidOrganizationResourceScopes } ) ); const managementApiResourceIndicator = getManagementApiResourceIndicator(tenantId); const managementApiScopes = await findScopesByIdsAndResourceIndicator( - resourceScopes, + [...resourceScopes, ...organizationResourceScopes], managementApiResourceIndicator ); @@ -129,10 +140,12 @@ export const createApplicationLibrary = (queries: Queries) => { { organizationScopes, resourceScopes, + organizationResourceScopes, userScopes, }: { organizationScopes?: string[]; resourceScopes?: string[]; + organizationResourceScopes?: string[]; userScopes?: string[]; } ) => { @@ -148,6 +161,12 @@ export const createApplicationLibrary = (queries: Queries) => { ); } + if (organizationResourceScopes) { + await userConsentOrganizationResourceScopes.insert( + ...organizationResourceScopes.map<[string, string]>((scope) => [applicationId, scope]) + ); + } + if (userScopes) { await Promise.all( userScopes.map(async (userScope) => @@ -181,6 +200,21 @@ export const createApplicationLibrary = (queries: Queries) => { ); }; + const getApplicationUserConsentOrganizationResourceScopes = async (applicationId: string) => { + const [, scopes] = await userConsentOrganizationResourceScopes.getEntities(Scopes, { + applicationId, + }); + + const groupedScopes = groupResourceScopesByResourceId(scopes); + + return Promise.all( + groupedScopes.map(async ({ resourceId, scopes }) => ({ + resource: await findResourceById(resourceId), + scopes, + })) + ); + }; + const getApplicationUserConsentScopes = async (applicationId: string) => userConsentUserScopes.findAllByApplicationId(applicationId); @@ -198,6 +232,10 @@ export const createApplicationLibrary = (queries: Queries) => { await userConsentResourceScopes.delete({ applicationId, scopeId }); break; } + case ApplicationUserConsentScopeType.OrganizationResourceScopes: { + await userConsentOrganizationResourceScopes.delete({ applicationId, scopeId }); + break; + } case ApplicationUserConsentScopeType.UserScopes: { await userConsentUserScopes.deleteByApplicationIdAndScopeId(applicationId, scopeId); break; @@ -250,6 +288,7 @@ export const createApplicationLibrary = (queries: Queries) => { assignApplicationUserConsentScopes, getApplicationUserConsentOrganizationScopes, getApplicationUserConsentResourceScopes, + getApplicationUserConsentOrganizationResourceScopes, getApplicationUserConsentScopes, deleteApplicationUserConsentScopesByTypeAndScopeId, validateUserConsentOrganizationMembership, diff --git a/packages/core/src/queries/application-user-consent-scopes.ts b/packages/core/src/queries/application-user-consent-scopes.ts index 394be6c71ed..e03e0c4f33c 100644 --- a/packages/core/src/queries/application-user-consent-scopes.ts +++ b/packages/core/src/queries/application-user-consent-scopes.ts @@ -2,6 +2,7 @@ import { type UserScope } from '@logto/core-kit'; import { ApplicationUserConsentOrganizationScopes, ApplicationUserConsentResourceScopes, + ApplicationUserConsentOrganizationResourceScopes, ApplicationUserConsentUserScopes, Applications, OrganizationScopes, @@ -32,6 +33,15 @@ export class ApplicationUserConsentResourceScopeQueries extends TwoRelationsQuer } } +export class ApplicationUserConsentOrganizationResourceScopeQueries extends TwoRelationsQueries< + typeof Applications, + typeof Scopes +> { + constructor(pool: CommonQueryMethods) { + super(pool, ApplicationUserConsentOrganizationResourceScopes.table, Applications, Scopes); + } +} + export const createApplicationUserConsentUserScopeQueries = (pool: CommonQueryMethods) => { const insert = buildInsertIntoWithPool(pool)(ApplicationUserConsentUserScopes, { onConflict: { ignore: true }, diff --git a/packages/core/src/queries/application.ts b/packages/core/src/queries/application.ts index 31f7dbf4289..d0915388379 100644 --- a/packages/core/src/queries/application.ts +++ b/packages/core/src/queries/application.ts @@ -15,6 +15,7 @@ import type { OmitAutoSetFields } from '#src/utils/sql.js'; import ApplicationUserConsentOrganizationsQuery from './application-user-consent-organizations.js'; import { + ApplicationUserConsentOrganizationResourceScopeQueries, ApplicationUserConsentOrganizationScopeQueries, ApplicationUserConsentResourceScopeQueries, createApplicationUserConsentUserScopeQueries, @@ -253,6 +254,8 @@ export const createApplicationQueries = (pool: CommonQueryMethods) => { deleteApplicationById, userConsentOrganizationScopes: new ApplicationUserConsentOrganizationScopeQueries(pool), userConsentResourceScopes: new ApplicationUserConsentResourceScopeQueries(pool), + userConsentOrganizationResourceScopes: + new ApplicationUserConsentOrganizationResourceScopeQueries(pool), userConsentUserScopes: createApplicationUserConsentUserScopeQueries(pool), userConsentOrganizations: new ApplicationUserConsentOrganizationsQuery(pool), }; diff --git a/packages/core/src/routes/applications/application-user-consent-scope.openapi.json b/packages/core/src/routes/applications/application-user-consent-scope.openapi.json index a0de2d9c638..7ca52a7dbe3 100644 --- a/packages/core/src/routes/applications/application-user-consent-scope.openapi.json +++ b/packages/core/src/routes/applications/application-user-consent-scope.openapi.json @@ -15,6 +15,9 @@ "resourceScopes": { "description": "A list of resource scope id to assign to the application. Throws error if any given resource scope is not found." }, + "organizationResourceScopes": { + "description": "A list of organization resource scope id to assign to the application. Throws error if any given resource scope is not found." + }, "userScopes": { "description": "A list of user scope enum value to assign to the application." } @@ -51,6 +54,9 @@ "resourceScopes": { "description": "A list of resource scope details grouped by resource id assigned to the application." }, + "organizationResourceScopes": { + "description": "A list of organization resource scope details grouped by resource id assigned to the application." + }, "userScopes": { "description": "A list of user scope enum value assigned to the application." } diff --git a/packages/core/src/routes/applications/application-user-consent-scope.ts b/packages/core/src/routes/applications/application-user-consent-scope.ts index cbb11a89ac7..22ee94c5590 100644 --- a/packages/core/src/routes/applications/application-user-consent-scope.ts +++ b/packages/core/src/routes/applications/application-user-consent-scope.ts @@ -5,6 +5,7 @@ import { } from '@logto/schemas'; import { object, string, nativeEnum } from 'zod'; +import { EnvSet } from '#src/env-set/index.js'; import koaGuard from '#src/middleware/koa-guard.js'; import type { ManagementApiRouter, RouterInitArgs } from '../types.js'; @@ -24,6 +25,7 @@ export default function applicationUserConsentScopeRoutes { @@ -77,17 +86,26 @@ export default function applicationUserConsentScopeRoutes authedAdminApi.post(`applications/${applicationId}/user-consent-scopes`, { json: payload }); diff --git a/packages/integration-tests/src/tests/api/application/application-user-consent-scope.test.ts b/packages/integration-tests/src/tests/api/application/application-user-consent-scope.test.ts index cf574493654..fb44d4adaaa 100644 --- a/packages/integration-tests/src/tests/api/application/application-user-consent-scope.test.ts +++ b/packages/integration-tests/src/tests/api/application/application-user-consent-scope.test.ts @@ -16,6 +16,7 @@ describe('assign user consent scopes to application', () => { const applicationIds = new Map(); const organizationScopes = new Map(); const resourceScopes = new Map(); + const organizationResourceScopes = new Map(); const resourceIds = new Set(); const organizationScopeApi = new OrganizationScopeApi(); @@ -52,6 +53,12 @@ describe('assign user consent scopes to application', () => { resourceScopes.set('resourceScope1', resourceScope1.id); resourceScopes.set('resourceScope2', resourceScope2.id); + + const resourceScope3 = await createScope(resource.id); + const resourceScope4 = await createScope(resource.id); + + organizationResourceScopes.set('resourceScope1', resourceScope3.id); + organizationResourceScopes.set('resourceScope2', resourceScope4.id); }); afterAll(async () => { @@ -75,6 +82,7 @@ describe('assign user consent scopes to application', () => { assignUserConsentScopes(applicationIds.get('firstPartyApp')!, { organizationScopes: Array.from(organizationScopes.values()), resourceScopes: Array.from(resourceScopes.values()), + organizationResourceScopes: Array.from(organizationResourceScopes.values()), }), { code: 'application.third_party_application_only', @@ -107,11 +115,24 @@ describe('assign user consent scopes to application', () => { ); }); + it('should throw error when trying to assign a non-existing organization resource scope', async () => { + await expectRejects( + assignUserConsentScopes(applicationIds.get('thirdPartyApp')!, { + organizationResourceScopes: ['non-existing-resource-scope'], + }), + { + code: 'application.user_consent_scopes_not_found', + status: 422, + } + ); + }); + it('should assign scopes to third-party application successfully', async () => { await expect( assignUserConsentScopes(applicationIds.get('thirdPartyApp')!, { organizationScopes: Array.from(organizationScopes.values()), resourceScopes: Array.from(resourceScopes.values()), + organizationResourceScopes: Array.from(organizationResourceScopes.values()), userScopes: [UserScope.Profile, UserScope.Email, UserScope.OrganizationRoles], }) ).resolves.not.toThrow(); @@ -122,6 +143,7 @@ describe('assign user consent scopes to application', () => { assignUserConsentScopes(applicationIds.get('thirdPartyApp')!, { organizationScopes: [organizationScopes.get('organizationScope1')!], resourceScopes: [resourceScopes.get('resourceScope1')!], + organizationResourceScopes: [organizationResourceScopes.get('resourceScope1')!], userScopes: [UserScope.Profile], }) ).resolves.not.toThrow(); @@ -154,6 +176,18 @@ describe('assign user consent scopes to application', () => { ).toBeTruthy(); } + expect(result.organizationResourceScopes.length).toBe(1); + expect(result.organizationResourceScopes[0]!.resource.id).toBe(Array.from(resourceIds)[0]); + expect(result.organizationResourceScopes[0]!.scopes.length).toBe( + organizationResourceScopes.size + ); + + for (const resourceScopeId of organizationResourceScopes.values()) { + expect( + result.organizationResourceScopes[0]!.scopes.some(({ id }) => id === resourceScopeId) + ).toBeTruthy(); + } + expect(result.userScopes.length).toBe(3); for (const userScope of [UserScope.Profile, UserScope.Email, UserScope.OrganizationRoles]) { @@ -170,6 +204,7 @@ describe('assign user consent scopes to application', () => { expect(result.organizationScopes.length).toBe(0); expect(result.resourceScopes.length).toBe(0); + expect(result.organizationResourceScopes.length).toBe(0); expect(result.userScopes.length).toBe(0); await deleteApplication(newApp.id); @@ -214,6 +249,18 @@ describe('assign user consent scopes to application', () => { } ); + await expectRejects( + deleteUserConsentScopes( + applicationIds.get('thirdPartyApp')!, + ApplicationUserConsentScopeType.OrganizationResourceScopes, + 'non-existing-resource-scope' + ), + { + code: 'entity.not_found', + status: 404, + } + ); + await expectRejects( deleteUserConsentScopes( applicationIds.get('thirdPartyApp')!, @@ -232,6 +279,7 @@ describe('assign user consent scopes to application', () => { assignUserConsentScopes(applicationIds.get('thirdPartyApp')!, { organizationScopes: Array.from(organizationScopes.values()), resourceScopes: Array.from(resourceScopes.values()), + organizationResourceScopes: Array.from(organizationResourceScopes.values()), userScopes: [UserScope.Profile, UserScope.Email, UserScope.OrganizationRoles], }) ).resolves.not.toThrow(); @@ -252,6 +300,14 @@ describe('assign user consent scopes to application', () => { ) ).resolves.not.toThrow(); + await expect( + deleteUserConsentScopes( + applicationIds.get('thirdPartyApp')!, + ApplicationUserConsentScopeType.OrganizationResourceScopes, + organizationResourceScopes.get('resourceScope1')! + ) + ).resolves.not.toThrow(); + await expect( deleteUserConsentScopes( applicationIds.get('thirdPartyApp')!, @@ -274,6 +330,12 @@ describe('assign user consent scopes to application', () => { ) ).toBeUndefined(); + expect( + result.organizationResourceScopes[0]!.scopes.find( + ({ id }) => id === organizationResourceScopes.get('resourceScope1')! + ) + ).toBeUndefined(); + expect(result.userScopes.includes(UserScope.OrganizationRoles)).toBeFalsy(); }); }); diff --git a/packages/schemas/src/types/application.ts b/packages/schemas/src/types/application.ts index 138dab7b144..4ffcd20f92c 100644 --- a/packages/schemas/src/types/application.ts +++ b/packages/schemas/src/types/application.ts @@ -40,22 +40,26 @@ export const applicationPatchGuard = applicationCreateGuard.partial().omit({ isThirdParty: true, }); +const resourceScopesGuard = z.array( + z.object({ + resource: Resources.guard.pick({ id: true, name: true, indicator: true }), + scopes: z.array(Scopes.guard.pick({ id: true, name: true, description: true })), + }) +); + export const applicationUserConsentScopesResponseGuard = z.object({ organizationScopes: z.array( OrganizationScopes.guard.pick({ id: true, name: true, description: true }) ), - resourceScopes: z.array( - z.object({ - resource: Resources.guard.pick({ id: true, name: true, indicator: true }), - scopes: z.array(Scopes.guard.pick({ id: true, name: true, description: true })), - }) - ), + resourceScopes: resourceScopesGuard, + organizationResourceScopes: resourceScopesGuard, userScopes: z.array(z.nativeEnum(UserScope)), }); export enum ApplicationUserConsentScopeType { OrganizationScopes = 'organization-scopes', ResourceScopes = 'resource-scopes', + OrganizationResourceScopes = 'organization-resource-scopes', UserScopes = 'user-scopes', } From a9ccfc738db9a5354e3401de48c494aca295215e Mon Sep 17 00:00:00 2001 From: Gao Sun Date: Wed, 1 May 2024 23:49:01 +0800 Subject: [PATCH 340/687] refactor: implement request id (#5813) * refactor: implement request id * refactor: fix tests * refactor: add unit tests --- .changeset/green-phones-visit.md | 5 ++ .changeset/grumpy-cougars-perform.md | 8 ++ packages/app-insights/src/node.ts | 14 ++- packages/core/src/app/init.ts | 26 +++++- packages/core/src/caches/index.ts | 8 +- packages/core/src/caches/utils.ts | 4 + packages/core/src/caches/well-known.ts | 4 +- .../src/env-set/check-alteration-state.ts | 3 +- packages/core/src/env-set/index.ts | 6 +- packages/core/src/event-listeners/index.ts | 7 +- packages/core/src/index.ts | 44 +--------- .../core/src/libraries/hook/index.test.ts | 2 + packages/core/src/libraries/hook/index.ts | 4 +- packages/core/src/libraries/jwt-customizer.ts | 23 +++-- packages/core/src/libraries/logto-config.ts | 6 +- packages/core/src/main.ts | 44 ++++++++++ .../core/src/middleware/koa-auth/index.ts | 4 +- .../core/src/middleware/koa-error-handler.ts | 14 ++- packages/core/src/middleware/koa-guard.ts | 15 +++- .../src/middleware/koa-oidc-error-handler.ts | 6 +- .../src/routes/interaction/actions/helpers.ts | 4 +- .../interaction/actions/submit-interaction.ts | 7 +- .../middleware/koa-interaction-hooks.ts | 8 +- .../core/src/routes/logto-config/index.ts | 7 +- .../logto-config/jwt-customizer.test.ts | 41 +++++---- .../src/routes/logto-config/jwt-customizer.ts | 11 +-- packages/core/src/routes/swagger/index.ts | 4 +- .../core/src/routes/swagger/utils/general.ts | 4 +- packages/core/src/routes/user-assets.ts | 4 +- packages/core/src/tenants/SystemContext.ts | 4 +- packages/core/src/tenants/Tenant.test.ts | 10 +-- packages/core/src/tenants/Tenant.ts | 14 ++- packages/core/src/tenants/index.ts | 9 +- packages/core/src/utils/cloudflare/utils.ts | 5 +- packages/core/src/utils/connectors/index.ts | 2 +- packages/core/src/utils/console.test.ts | 47 ++++++++++ packages/core/src/utils/console.ts | 55 +++++++++++- packages/core/src/utils/request.ts | 21 +++++ packages/core/src/utils/tenant.ts | 5 +- .../src/tests/api/health-check.test.ts | 5 ++ .../src/tests/api/well-known.test.ts | 5 ++ .../shared/src/node/env/ConsoleLog.test.ts | 87 +++++++++++++++++++ packages/shared/src/node/env/ConsoleLog.ts | 33 +++++-- 43 files changed, 499 insertions(+), 140 deletions(-) create mode 100644 .changeset/green-phones-visit.md create mode 100644 .changeset/grumpy-cougars-perform.md create mode 100644 packages/core/src/caches/utils.ts create mode 100644 packages/core/src/main.ts create mode 100644 packages/core/src/utils/console.test.ts create mode 100644 packages/core/src/utils/request.ts create mode 100644 packages/shared/src/node/env/ConsoleLog.test.ts diff --git a/.changeset/green-phones-visit.md b/.changeset/green-phones-visit.md new file mode 100644 index 00000000000..2fc47bddbc2 --- /dev/null +++ b/.changeset/green-phones-visit.md @@ -0,0 +1,5 @@ +--- +"@logto/app-insights": patch +--- + +allow additional telemetry for `trackException()` diff --git a/.changeset/grumpy-cougars-perform.md b/.changeset/grumpy-cougars-perform.md new file mode 100644 index 00000000000..acc72b4b63a --- /dev/null +++ b/.changeset/grumpy-cougars-perform.md @@ -0,0 +1,8 @@ +--- +"@logto/core": patch +--- + +implement request ID for API requests + +- All requests will now include a request ID in the headers (`Logto-Core-Request-Id`) +- Terminal logs will now include the request ID as the prefix diff --git a/packages/app-insights/src/node.ts b/packages/app-insights/src/node.ts index 5ea63fb74bc..d9511880974 100644 --- a/packages/app-insights/src/node.ts +++ b/packages/app-insights/src/node.ts @@ -1,8 +1,11 @@ import { trySafe } from '@silverhand/essentials'; import type { TelemetryClient } from 'applicationinsights'; +import { type ExceptionTelemetry } from 'applicationinsights/out/Declarations/Contracts/index.js'; import { normalizeError } from './normalize-error.js'; +export { type ExceptionTelemetry } from 'applicationinsights/out/Declarations/Contracts/index.js'; + class AppInsights { client?: TelemetryClient; @@ -29,9 +32,14 @@ class AppInsights { return true; } - /** The function is async to avoid blocking the main script and force the use of `await` or `void`. */ - async trackException(error: unknown) { - this.client?.trackException({ exception: normalizeError(error) }); + /** + * The function is async to avoid blocking the main script and force the use of `await` or `void`. + * + * @param error The error to track. It will be normalized for better telemetry. + * @param telemetry Additional telemetry to include in the exception. + */ + async trackException(error: unknown, telemetry?: Partial) { + this.client?.trackException({ exception: normalizeError(error), ...telemetry }); } } diff --git a/packages/core/src/app/init.ts b/packages/core/src/app/init.ts index 5ac044affee..642868071f3 100644 --- a/packages/core/src/app/init.ts +++ b/packages/core/src/app/init.ts @@ -2,17 +2,21 @@ import fs from 'node:fs/promises'; import http2 from 'node:http2'; import { appInsights } from '@logto/app-insights/node'; +import { ConsoleLog } from '@logto/shared'; import { toTitle, trySafe } from '@silverhand/essentials'; import chalk from 'chalk'; import type Koa from 'koa'; +import koaLogger from 'koa-logger'; +import { nanoid } from 'nanoid'; import { EnvSet } from '#src/env-set/index.js'; import { TenantNotFoundError, tenantPool } from '#src/tenants/index.js'; -import { consoleLog } from '#src/utils/console.js'; +import { buildAppInsightsTelemetry } from '#src/utils/request.js'; import { getTenantId } from '#src/utils/tenant.js'; const logListening = (type: 'core' | 'admin' = 'core') => { const urlSet = type === 'core' ? EnvSet.values.urlSet : EnvSet.values.adminUrlSet; + const consoleLog = new ConsoleLog(chalk.magenta(type)); for (const url of urlSet.deduplicated()) { consoleLog.info(chalk.bold(`${toTitle(type)} app is running at ${url.toString()}`)); @@ -22,6 +26,22 @@ const logListening = (type: 'core' | 'admin' = 'core') => { const serverTimeout = 120_000; export default async function initApp(app: Koa): Promise { + app.use(async (ctx, next) => { + const requestId = nanoid(16); + const consoleLog = new ConsoleLog(chalk.blue(requestId)); + ctx.requestId = requestId; + ctx.console = consoleLog; + + await koaLogger({ + transporter: (string) => { + consoleLog.plain(string); + }, + })(ctx, next); + + // Set the header in the end to avoid other middleware from overwriting it + ctx.set('Logto-Core-Request-Id', requestId); + }); + app.use(async (ctx, next) => { if (EnvSet.values.isDomainBasedMultiTenancy && ['/status', '/'].includes(ctx.URL.pathname)) { ctx.status = 204; @@ -43,7 +63,7 @@ export default async function initApp(app: Koa): Promise { const tenant = await trySafe(tenantPool.get(tenantId, customEndpoint), (error) => { ctx.status = error instanceof TenantNotFoundError ? 404 : 500; - void appInsights.trackException(error); + void appInsights.trackException(error, buildAppInsightsTelemetry(ctx)); }); if (!tenant) { @@ -56,7 +76,7 @@ export default async function initApp(app: Koa): Promise { tenant.requestEnd(); } catch (error: unknown) { tenant.requestEnd(); - void appInsights.trackException(error); + void appInsights.trackException(error, buildAppInsightsTelemetry(ctx)); throw error; } diff --git a/packages/core/src/caches/index.ts b/packages/core/src/caches/index.ts index 9e9e6bc5ec6..c9d0fdaa196 100644 --- a/packages/core/src/caches/index.ts +++ b/packages/core/src/caches/index.ts @@ -5,9 +5,9 @@ import { type Optional, conditional, yes, trySafe } from '@silverhand/essentials import { createClient, createCluster, type RedisClientType, type RedisClusterType } from 'redis'; import { EnvSet } from '#src/env-set/index.js'; -import { consoleLog } from '#src/utils/console.js'; import { type CacheStore } from './types.js'; +import { cacheConsole } from './utils.js'; abstract class RedisCacheBase implements CacheStore { readonly client?: RedisClientType | RedisClusterType; @@ -32,17 +32,17 @@ abstract class RedisCacheBase implements CacheStore { const pong = await this.ping(); if (pong === 'PONG') { - consoleLog.info('[CACHE] Connected to Redis'); + cacheConsole.info('Connected to Redis'); return; } } - consoleLog.warn('[CACHE] No Redis client initialized, skipping'); + cacheConsole.warn('No Redis client initialized, skipping'); } async disconnect() { if (this.client) { await this.client.disconnect(); - consoleLog.info('[CACHE] Disconnected from Redis'); + cacheConsole.info('Disconnected from Redis'); } } diff --git a/packages/core/src/caches/utils.ts b/packages/core/src/caches/utils.ts new file mode 100644 index 00000000000..98c61d5ed50 --- /dev/null +++ b/packages/core/src/caches/utils.ts @@ -0,0 +1,4 @@ +import { ConsoleLog } from '@logto/shared'; +import chalk from 'chalk'; + +export const cacheConsole = new ConsoleLog(chalk.magenta('cache')); diff --git a/packages/core/src/caches/well-known.ts b/packages/core/src/caches/well-known.ts index 4686643d00f..044d99b5eed 100644 --- a/packages/core/src/caches/well-known.ts +++ b/packages/core/src/caches/well-known.ts @@ -3,9 +3,9 @@ import { type Optional, trySafe } from '@silverhand/essentials'; import { type ZodType, z } from 'zod'; import { type ConnectorWellKnown, connectorWellKnownGuard } from '#src/utils/connectors/types.js'; -import { consoleLog } from '#src/utils/console.js'; import { type CacheStore } from './types.js'; +import { cacheConsole } from './utils.js'; type WellKnownMap = { sie: SignInExperience; @@ -177,7 +177,7 @@ export class WellKnownCache { const cachedValue = await trySafe(kvCache.get(type, promiseKey)); if (cachedValue) { - consoleLog.info('[CACHE] Well-known cache hit for', type, promiseKey); + cacheConsole.info('Well-known cache hit for', type, promiseKey); return cachedValue; } diff --git a/packages/core/src/env-set/check-alteration-state.ts b/packages/core/src/env-set/check-alteration-state.ts index 42eaad7c163..4fc8d3c73cc 100644 --- a/packages/core/src/env-set/check-alteration-state.ts +++ b/packages/core/src/env-set/check-alteration-state.ts @@ -1,8 +1,9 @@ import { getAvailableAlterations } from '@logto/cli/lib/commands/database/alteration/index.js'; +import { ConsoleLog } from '@logto/shared'; import type { DatabasePool } from '@silverhand/slonik'; import chalk from 'chalk'; -import { consoleLog } from '#src/utils/console.js'; +const consoleLog = new ConsoleLog(chalk.magenta('db-alt')); export const checkAlterationState = async (pool: DatabasePool) => { const alterations = await getAvailableAlterations(pool); diff --git a/packages/core/src/env-set/index.ts b/packages/core/src/env-set/index.ts index 20b395fd530..1aa82b48b44 100644 --- a/packages/core/src/env-set/index.ts +++ b/packages/core/src/env-set/index.ts @@ -1,7 +1,8 @@ -import { GlobalValues } from '@logto/shared'; +import { ConsoleLog, GlobalValues } from '@logto/shared'; import type { Optional } from '@silverhand/essentials'; import { appendPath } from '@silverhand/essentials'; import type { DatabasePool } from '@silverhand/slonik'; +import chalk from 'chalk'; import { createLogtoConfigLibrary } from '#src/libraries/logto-config.js'; import { createLogtoConfigQueries } from '#src/queries/logto-config.js'; @@ -72,11 +73,12 @@ export class EnvSet { this.#pool = pool; + const consoleLog = new ConsoleLog(chalk.magenta('env-set')); const { getOidcConfigs } = createLogtoConfigLibrary({ logtoConfigs: createLogtoConfigQueries(pool), }); - const oidcConfigs = await getOidcConfigs(); + const oidcConfigs = await getOidcConfigs(consoleLog); const endpoint = customDomain ? new URL(customDomain) : getTenantEndpoint(this.tenantId, EnvSet.values); diff --git a/packages/core/src/event-listeners/index.ts b/packages/core/src/event-listeners/index.ts index 04790fd3cff..402d1c92930 100644 --- a/packages/core/src/event-listeners/index.ts +++ b/packages/core/src/event-listeners/index.ts @@ -1,12 +1,15 @@ +import { ConsoleLog } from '@logto/shared'; +import chalk from 'chalk'; import type Provider from 'oidc-provider'; import type Queries from '#src/tenants/Queries.js'; -import { consoleLog } from '#src/utils/console.js'; import { grantListener, grantRevocationListener } from './grant.js'; import { interactionEndedListener, interactionStartedListener } from './interaction.js'; import { recordActiveUsers } from './record-active-users.js'; +const consoleLog = new ConsoleLog(chalk.magenta('oidc')); + /** * @see {@link https://github.com/panva/node-oidc-provider/blob/v7.x/docs/README.md#im-getting-a-client-authentication-failed-error-with-no-details Getting auth error with no details?} * @see {@link https://github.com/panva/node-oidc-provider/blob/v7.x/docs/events.md OIDC Provider events} @@ -27,7 +30,7 @@ export const addOidcEventListeners = (provider: Provider, queries: Queries) => { provider.addListener('interaction.started', interactionStartedListener); provider.addListener('interaction.ended', interactionEndedListener); provider.addListener('server_error', (_, error) => { - consoleLog.error('OIDC Provider server_error:', error); + consoleLog.error('server_error:', error); }); // Record token usage. diff --git a/packages/core/src/index.ts b/packages/core/src/index.ts index b06f4d14caf..93813a75d18 100644 --- a/packages/core/src/index.ts +++ b/packages/core/src/index.ts @@ -1,48 +1,6 @@ -import { trySafe } from '@silverhand/essentials'; import dotenv from 'dotenv'; import { findUp } from 'find-up'; -import Koa from 'koa'; - -import { checkAlterationState } from './env-set/check-alteration-state.js'; -import SystemContext from './tenants/SystemContext.js'; -import { consoleLog } from './utils/console.js'; dotenv.config({ path: await findUp('.env', {}) }); -const { appInsights } = await import('@logto/app-insights/node'); - -if (await appInsights.setup('core')) { - consoleLog.info('Initialized ApplicationInsights'); -} - -// Import after env has been configured -const { loadConnectorFactories } = await import('./utils/connectors/index.js'); -const { EnvSet } = await import('./env-set/index.js'); -const { redisCache } = await import('./caches/index.js'); -const { default: initI18n } = await import('./i18n/init.js'); -const { tenantPool, checkRowLevelSecurity } = await import('./tenants/index.js'); - -try { - const app = new Koa({ - proxy: EnvSet.values.trustProxyHeader, - }); - const sharedAdminPool = await EnvSet.sharedPool; - - await Promise.all([ - initI18n(), - redisCache.connect(), - loadConnectorFactories(), - checkRowLevelSecurity(sharedAdminPool), - checkAlterationState(sharedAdminPool), - SystemContext.shared.loadProviderConfigs(sharedAdminPool), - ]); - - // Import last until init completed - const { default: initApp } = await import('./app/init.js'); - await initApp(app); -} catch (error: unknown) { - consoleLog.error('Error while initializing app:'); - consoleLog.error(error); - - void Promise.all([trySafe(tenantPool.endAll()), trySafe(redisCache.disconnect())]); -} +await import('./main.js'); diff --git a/packages/core/src/libraries/hook/index.test.ts b/packages/core/src/libraries/hook/index.test.ts index 06155d02484..033aec1d6bc 100644 --- a/packages/core/src/libraries/hook/index.test.ts +++ b/packages/core/src/libraries/hook/index.test.ts @@ -1,5 +1,6 @@ import type { Hook } from '@logto/schemas'; import { HookEvent, InteractionEvent, LogResult } from '@logto/schemas'; +import { ConsoleLog } from '@logto/shared'; import { createMockUtils } from '@logto/shared/esm'; import RequestError from '#src/errors/RequestError/index.js'; @@ -73,6 +74,7 @@ describe('triggerInteractionHooks()', () => { jest.useFakeTimers().setSystemTime(100_000); await triggerInteractionHooks( + new ConsoleLog(), { event: InteractionEvent.SignIn, sessionId: 'some_jti', applicationId: 'some_client' }, { userId: '123' } ); diff --git a/packages/core/src/libraries/hook/index.ts b/packages/core/src/libraries/hook/index.ts index 0689fd7bfe4..c6a88960795 100644 --- a/packages/core/src/libraries/hook/index.ts +++ b/packages/core/src/libraries/hook/index.ts @@ -7,14 +7,13 @@ import { type HookConfig, type HookTestErrorResponseData, } from '@logto/schemas'; -import { generateStandardId } from '@logto/shared'; +import { type ConsoleLog, generateStandardId } from '@logto/shared'; import { conditional, pick, trySafe } from '@silverhand/essentials'; import { HTTPError } from 'ky'; import RequestError from '#src/errors/RequestError/index.js'; import { LogEntry } from '#src/middleware/koa-audit-log.js'; import type Queries from '#src/tenants/Queries.js'; -import { consoleLog } from '#src/utils/console.js'; import { generateHookTestPayload, parseResponse, sendWebhookRequest } from './utils.js'; @@ -55,6 +54,7 @@ export const createHookLibrary = (queries: Queries) => { } = queries; const triggerInteractionHooks = async ( + consoleLog: ConsoleLog, interactionContext: InteractionHookContext, interactionResult: InteractionHookResult, userAgent?: string diff --git a/packages/core/src/libraries/jwt-customizer.ts b/packages/core/src/libraries/jwt-customizer.ts index fae9698cd9e..d8be39a7612 100644 --- a/packages/core/src/libraries/jwt-customizer.ts +++ b/packages/core/src/libraries/jwt-customizer.ts @@ -5,6 +5,7 @@ import { type JwtCustomizerType, type JwtCustomizerUserContext, } from '@logto/schemas'; +import { type ConsoleLog } from '@logto/shared'; import { deduplicate, pick, pickState, assert } from '@silverhand/essentials'; import deepmerge from 'deepmerge'; @@ -94,14 +95,17 @@ export const createJwtCustomizerLibrary = ( * @params payload.value - JWT customizer value * @params payload.useCase - The use case of JWT customizer script, can be either `test` or `production`. */ - const deployJwtCustomizerScript = async (payload: { - key: T; - value: JwtCustomizerType[T]; - useCase: 'test' | 'production'; - }) => { + const deployJwtCustomizerScript = async ( + consoleLog: ConsoleLog, + payload: { + key: T; + value: JwtCustomizerType[T]; + useCase: 'test' | 'production'; + } + ) => { const [client, jwtCustomizers] = await Promise.all([ cloudConnection.getClient(), - getJwtCustomizers(), + getJwtCustomizers(consoleLog), ]); const customizerScriptsFromDatabase = getJwtCustomizerScripts(jwtCustomizers); @@ -127,10 +131,13 @@ export const createJwtCustomizerLibrary = ( }); }; - const undeployJwtCustomizerScript = async (key: T) => { + const undeployJwtCustomizerScript = async ( + consoleLog: ConsoleLog, + key: T + ) => { const [client, jwtCustomizers] = await Promise.all([ cloudConnection.getClient(), - getJwtCustomizers(), + getJwtCustomizers(consoleLog), ]); assert(jwtCustomizers[key], new RequestError({ code: 'entity.not_exists', key })); diff --git a/packages/core/src/libraries/logto-config.ts b/packages/core/src/libraries/logto-config.ts index 54fed67a668..2f7a55a9256 100644 --- a/packages/core/src/libraries/logto-config.ts +++ b/packages/core/src/libraries/logto-config.ts @@ -8,12 +8,12 @@ import { jwtCustomizerConfigGuard, logtoOidcConfigGuard, } from '@logto/schemas'; +import { type ConsoleLog } from '@logto/shared'; import chalk from 'chalk'; import { ZodError, z } from 'zod'; import RequestError from '#src/errors/RequestError/index.js'; import type Queries from '#src/tenants/Queries.js'; -import { consoleLog } from '#src/utils/console.js'; export type LogtoConfigLibrary = ReturnType; @@ -24,7 +24,7 @@ export const createLogtoConfigLibrary = ({ upsertJwtCustomizer: queryUpsertJwtCustomizer, }, }: Pick) => { - const getOidcConfigs = async (): Promise => { + const getOidcConfigs = async (consoleLog: ConsoleLog): Promise => { try { const { rows } = await getRowsByKeys(Object.values(LogtoOidcConfigKey)); @@ -96,7 +96,7 @@ export const createLogtoConfigLibrary = ({ return z.object({ value: jwtCustomizerConfigGuard[key] }).parse(rows[0]).value; }; - const getJwtCustomizers = async (): Promise> => { + const getJwtCustomizers = async (consoleLog: ConsoleLog): Promise> => { try { const { rows } = await getRowsByKeys(Object.values(LogtoJwtTokenKey)); diff --git a/packages/core/src/main.ts b/packages/core/src/main.ts new file mode 100644 index 00000000000..3144800d6f2 --- /dev/null +++ b/packages/core/src/main.ts @@ -0,0 +1,44 @@ +import { ConsoleLog } from '@logto/shared'; +import { trySafe } from '@silverhand/essentials'; +import chalk from 'chalk'; +import Koa from 'koa'; + +import { redisCache } from './caches/index.js'; +import { checkAlterationState } from './env-set/check-alteration-state.js'; +import { EnvSet } from './env-set/index.js'; +import initI18n from './i18n/init.js'; +import SystemContext from './tenants/SystemContext.js'; +import { checkRowLevelSecurity, tenantPool } from './tenants/index.js'; +import { loadConnectorFactories } from './utils/connectors/index.js'; + +const { appInsights } = await import('@logto/app-insights/node'); +const consoleLog = new ConsoleLog(chalk.magenta('index')); + +if (await appInsights.setup('core')) { + consoleLog.info('Initialized ApplicationInsights'); +} + +try { + const app = new Koa({ + proxy: EnvSet.values.trustProxyHeader, + }); + const sharedAdminPool = await EnvSet.sharedPool; + + await Promise.all([ + initI18n(), + redisCache.connect(), + loadConnectorFactories(), + checkRowLevelSecurity(sharedAdminPool), + checkAlterationState(sharedAdminPool), + SystemContext.shared.loadProviderConfigs(sharedAdminPool), + ]); + + // Import last until init completed + const { default: initApp } = await import('./app/init.js'); + await initApp(app); +} catch (error: unknown) { + consoleLog.error('Error while initializing app:'); + consoleLog.error(error); + + void Promise.all([trySafe(tenantPool.endAll()), trySafe(redisCache.disconnect())]); +} diff --git a/packages/core/src/middleware/koa-auth/index.ts b/packages/core/src/middleware/koa-auth/index.ts index 1cb89457016..826e784ef07 100644 --- a/packages/core/src/middleware/koa-auth/index.ts +++ b/packages/core/src/middleware/koa-auth/index.ts @@ -11,7 +11,7 @@ import { z } from 'zod'; import { EnvSet } from '#src/env-set/index.js'; import RequestError from '#src/errors/RequestError/index.js'; import assertThat from '#src/utils/assert-that.js'; -import { consoleLog } from '#src/utils/console.js'; +import { devConsole } from '#src/utils/console.js'; import { getAdminTenantTokenValidationSet } from './utils.js'; @@ -60,7 +60,7 @@ export const verifyBearerTokenFromRequest = async ( if ((!isProduction || isIntegrationTest) && userId) { // This log is distracting in integration tests. if (!isIntegrationTest) { - consoleLog.warn(`Found dev user ID ${userId}, skip token validation.`); + devConsole.warn(`Found dev user ID ${userId}, skip token validation.`); } return { diff --git a/packages/core/src/middleware/koa-error-handler.ts b/packages/core/src/middleware/koa-error-handler.ts index 28925f5658f..24a54770f6b 100644 --- a/packages/core/src/middleware/koa-error-handler.ts +++ b/packages/core/src/middleware/koa-error-handler.ts @@ -5,14 +5,22 @@ import { HttpError } from 'koa'; import { EnvSet } from '#src/env-set/index.js'; import RequestError from '#src/errors/RequestError/index.js'; -import { consoleLog } from '#src/utils/console.js'; - +import { getConsoleLogFromContext } from '#src/utils/console.js'; +import { buildAppInsightsTelemetry } from '#src/utils/request.js'; + +/** + * The middleware to handle errors. + * + * Note: A context-aware console log is required to be present in the context (i.e. `ctx.console`). + */ export default function koaErrorHandler(): Middleware< StateT, ContextT, BodyT | RequestErrorBody | { message: string } > { return async (ctx, next) => { + const consoleLog = getConsoleLogFromContext(ctx); + try { await next(); } catch (error: unknown) { @@ -21,7 +29,7 @@ export default function koaErrorHandler(): Middleware< } // Report all exceptions to ApplicationInsights - void appInsights.trackException(error); + void appInsights.trackException(error, buildAppInsightsTelemetry(ctx)); if (error instanceof RequestError) { ctx.status = error.status; diff --git a/packages/core/src/middleware/koa-guard.ts b/packages/core/src/middleware/koa-guard.ts index 3395381034b..75e87aa2a69 100644 --- a/packages/core/src/middleware/koa-guard.ts +++ b/packages/core/src/middleware/koa-guard.ts @@ -9,7 +9,8 @@ import type { ZodType, ZodTypeDef } from 'zod'; import { EnvSet } from '#src/env-set/index.js'; import RequestError from '#src/errors/RequestError/index.js'; import { ResponseBodyError, StatusCodeError } from '#src/errors/ServerError/index.js'; -import { consoleLog } from '#src/utils/console.js'; +import { getConsoleLogFromContext } from '#src/utils/console.js'; +import { buildAppInsightsTelemetry } from '#src/utils/request.js'; /** Configure what and how to guard. */ export type GuardConfig = { @@ -121,6 +122,11 @@ const tryParse = ( return parse(type, guard, data); }; +/** + * Guard middleware factory for request and response. + * + * Note: A context-aware console log is required to be present in the context (i.e. `ctx.console`). + */ export default function koaGuard< StateT, ContextT extends IRouterParamContext, @@ -170,6 +176,8 @@ export default function koaGuard< GuardResponseT > > = async function (ctx, next) { + const consoleLog = getConsoleLogFromContext(ctx); + /** * Assert the status code matches the value(s) in the config. If the config does not * specify a status code, it will not assert anything. @@ -191,7 +199,10 @@ export default function koaGuard< if (EnvSet.values.isProduction) { consoleLog.warn('Unexpected status code:', value, 'expected:', status); - void appInsights.trackException(new StatusCodeError(status, value)); + void appInsights.trackException( + new StatusCodeError(status, value), + buildAppInsightsTelemetry(ctx) + ); return; } diff --git a/packages/core/src/middleware/koa-oidc-error-handler.ts b/packages/core/src/middleware/koa-oidc-error-handler.ts index c208fa83efd..91138185264 100644 --- a/packages/core/src/middleware/koa-oidc-error-handler.ts +++ b/packages/core/src/middleware/koa-oidc-error-handler.ts @@ -5,7 +5,7 @@ import { errors } from 'oidc-provider'; import { z } from 'zod'; import { EnvSet } from '#src/env-set/index.js'; -import { consoleLog } from '#src/utils/console.js'; +import { getConsoleLogFromContext } from '#src/utils/console.js'; /** * Supplementary URIs for oidc-provider errors. @@ -18,6 +18,8 @@ const errorUris: Record = Object.freeze({ * Transform oidc-provider error to a format for the client. This is edited from oidc-provider's * own implementation. * + * Note: A context-aware console log is required to be present in the context (i.e. `ctx.console`). + * * @see {@link https://github.com/panva/node-oidc-provider/blob/37d0a6cfb3c618141a44cbb904ce45659438f821/lib/helpers/err_out.js | oidc-provider/lib/helpers/err_out.js} */ export const errorOut = ({ @@ -92,7 +94,7 @@ export default function koaOidcErrorHandler(): Middleware= 500)) { - consoleLog.error(error); + getConsoleLogFromContext(ctx).error(error); } } diff --git a/packages/core/src/routes/interaction/actions/helpers.ts b/packages/core/src/routes/interaction/actions/helpers.ts index d64a4a44db0..9bc5629a5f5 100644 --- a/packages/core/src/routes/interaction/actions/helpers.ts +++ b/packages/core/src/routes/interaction/actions/helpers.ts @@ -1,5 +1,4 @@ import { defaults, parseAffiliateData } from '@logto/affiliate'; -import { consoleLog } from '@logto/cli/lib/utils.js'; import { type CreateUser, type User, adminTenantId } from '@logto/schemas'; import { conditional, trySafe } from '@silverhand/essentials'; import { type IRouterContext } from 'koa-router'; @@ -10,6 +9,7 @@ import { type ConnectorLibrary } from '#src/libraries/connector.js'; import { encryptUserPassword } from '#src/libraries/user.js'; import type Queries from '#src/tenants/Queries.js'; import type TenantContext from '#src/tenants/TenantContext.js'; +import { getConsoleLogFromContext } from '#src/utils/console.js'; import { type OmitAutoSetFields } from '#src/utils/sql.js'; import { @@ -146,6 +146,6 @@ export const postAffiliateLogs = async ( await client.post('/api/affiliate-logs', { body: { userId, ...affiliateData }, }); - consoleLog.info('Affiliate logs posted', userId); + getConsoleLogFromContext(ctx).info('Affiliate logs posted', userId); } }; diff --git a/packages/core/src/routes/interaction/actions/submit-interaction.ts b/packages/core/src/routes/interaction/actions/submit-interaction.ts index 7f4583c5679..0abf8690c14 100644 --- a/packages/core/src/routes/interaction/actions/submit-interaction.ts +++ b/packages/core/src/routes/interaction/actions/submit-interaction.ts @@ -24,7 +24,8 @@ import { assignInteractionResults } from '#src/libraries/session.js'; import { encryptUserPassword } from '#src/libraries/user.js'; import type { LogEntry, WithLogContext } from '#src/middleware/koa-audit-log.js'; import type TenantContext from '#src/tenants/TenantContext.js'; -import { consoleLog } from '#src/utils/console.js'; +import { getConsoleLogFromContext } from '#src/utils/console.js'; +import { buildAppInsightsTelemetry } from '#src/utils/request.js'; import { getTenantId } from '#src/utils/tenant.js'; import type { WithInteractionDetailsContext } from '../middleware/koa-interaction-details.js'; @@ -180,8 +181,8 @@ async function handleSubmitRegister( log?.append({ userId: id }); appInsights.client?.trackEvent({ name: getEventName(Component.Core, CoreEvent.Register) }); void trySafe(postAffiliateLogs(ctx, cloudConnection, id, tenantId), (error) => { - consoleLog.warn('Failed to post affiliate logs', error); - void appInsights.trackException(error); + getConsoleLogFromContext(ctx).warn('Failed to post affiliate logs', error); + void appInsights.trackException(error, buildAppInsightsTelemetry(ctx)); }); } diff --git a/packages/core/src/routes/interaction/middleware/koa-interaction-hooks.ts b/packages/core/src/routes/interaction/middleware/koa-interaction-hooks.ts index c1e3446514b..c8e7424f290 100644 --- a/packages/core/src/routes/interaction/middleware/koa-interaction-hooks.ts +++ b/packages/core/src/routes/interaction/middleware/koa-interaction-hooks.ts @@ -7,6 +7,7 @@ import { type InteractionHookResult, } from '#src/libraries/hook/index.js'; import type Libraries from '#src/tenants/Libraries.js'; +import { getConsoleLogFromContext } from '#src/utils/console.js'; import { getInteractionStorage } from '../utils/interaction.js'; @@ -64,7 +65,12 @@ export default function koaInteractionHooks< if (interactionHookResult) { // Hooks should not crash the app void trySafe( - triggerInteractionHooks(interactionHookContext, interactionHookResult, userAgent) + triggerInteractionHooks( + getConsoleLogFromContext(ctx), + interactionHookContext, + interactionHookResult, + userAgent + ) ); } }; diff --git a/packages/core/src/routes/logto-config/index.ts b/packages/core/src/routes/logto-config/index.ts index b7dabb4934b..7111fbce735 100644 --- a/packages/core/src/routes/logto-config/index.ts +++ b/packages/core/src/routes/logto-config/index.ts @@ -17,6 +17,7 @@ import { z } from 'zod'; import RequestError from '#src/errors/RequestError/index.js'; import koaGuard from '#src/middleware/koa-guard.js'; +import { getConsoleLogFromContext } from '#src/utils/console.js'; import { exportJWK } from '#src/utils/jwks.js'; import type { ManagementApiRouter, RouterInitArgs } from '../types.js'; @@ -104,7 +105,7 @@ export default function logtoConfigRoutes( async (ctx, next) => { const { keyType } = ctx.guard.params; const configKey = getOidcConfigKeyDatabaseColumnName(keyType); - const configs = await getOidcConfigs(); + const configs = await getOidcConfigs(getConsoleLogFromContext(ctx)); // Remove actual values of the private keys from response ctx.body = await getRedactedOidcKeyResponse(configKey, configs[configKey]); @@ -125,7 +126,7 @@ export default function logtoConfigRoutes( async (ctx, next) => { const { keyType, keyId } = ctx.guard.params; const configKey = getOidcConfigKeyDatabaseColumnName(keyType); - const configs = await getOidcConfigs(); + const configs = await getOidcConfigs(getConsoleLogFromContext(ctx)); const existingKeys = configs[configKey]; if (existingKeys.length <= 1) { @@ -163,7 +164,7 @@ export default function logtoConfigRoutes( const { keyType } = ctx.guard.params; const { signingKeyAlgorithm } = ctx.guard.body; const configKey = getOidcConfigKeyDatabaseColumnName(keyType); - const configs = await getOidcConfigs(); + const configs = await getOidcConfigs(getConsoleLogFromContext(ctx)); const existingKeys = configs[configKey]; const newPrivateKey = diff --git a/packages/core/src/routes/logto-config/jwt-customizer.test.ts b/packages/core/src/routes/logto-config/jwt-customizer.test.ts index 56d560c505f..0c5e3428cab 100644 --- a/packages/core/src/routes/logto-config/jwt-customizer.test.ts +++ b/packages/core/src/routes/logto-config/jwt-customizer.test.ts @@ -3,6 +3,7 @@ import { LogtoJwtTokenKeyType, type JwtCustomizerTestRequestBody, } from '@logto/schemas'; +import { ConsoleLog } from '@logto/shared'; import { pickDefault } from '@logto/shared/esm'; import { pick } from '@silverhand/essentials'; @@ -60,11 +61,14 @@ describe('configs JWT customizer routes', () => { .put(`/configs/jwt-customizer/access-token`) .send(mockJwtCustomizerConfigForAccessToken.value); - expect(tenantContext.libraries.jwtCustomizers.deployJwtCustomizerScript).toHaveBeenCalledWith({ - key: LogtoJwtTokenKey.AccessToken, - value: mockJwtCustomizerConfigForAccessToken.value, - useCase: 'production', - }); + expect(tenantContext.libraries.jwtCustomizers.deployJwtCustomizerScript).toHaveBeenCalledWith( + expect.any(ConsoleLog), + { + key: LogtoJwtTokenKey.AccessToken, + value: mockJwtCustomizerConfigForAccessToken.value, + useCase: 'production', + } + ); expect(mockLogtoConfigsLibrary.upsertJwtCustomizer).toHaveBeenCalledWith( LogtoJwtTokenKey.AccessToken, @@ -102,11 +106,14 @@ describe('configs JWT customizer routes', () => { .patch('/configs/jwt-customizer/access-token') .send(mockJwtCustomizerConfigForAccessToken.value); - expect(tenantContext.libraries.jwtCustomizers.deployJwtCustomizerScript).toHaveBeenCalledWith({ - key: LogtoJwtTokenKey.AccessToken, - value: mockJwtCustomizerConfigForAccessToken.value, - useCase: 'production', - }); + expect(tenantContext.libraries.jwtCustomizers.deployJwtCustomizerScript).toHaveBeenCalledWith( + expect.any(ConsoleLog), + { + key: LogtoJwtTokenKey.AccessToken, + value: mockJwtCustomizerConfigForAccessToken.value, + useCase: 'production', + } + ); expect(mockLogtoConfigsLibrary.updateJwtCustomizer).toHaveBeenCalledWith( LogtoJwtTokenKey.AccessToken, @@ -141,6 +148,7 @@ describe('configs JWT customizer routes', () => { it('DELETE /configs/jwt-customizer/:tokenType should delete the record', async () => { const response = await routeRequester.delete('/configs/jwt-customizer/client-credentials'); expect(tenantContext.libraries.jwtCustomizers.undeployJwtCustomizerScript).toHaveBeenCalledWith( + expect.any(ConsoleLog), LogtoJwtTokenKey.ClientCredentials ); expect(logtoConfigQueries.deleteJwtCustomizer).toHaveBeenCalledWith( @@ -163,11 +171,14 @@ describe('configs JWT customizer routes', () => { const response = await routeRequester.post('/configs/jwt-customizer/test').send(payload); - expect(tenantContext.libraries.jwtCustomizers.deployJwtCustomizerScript).toHaveBeenCalledWith({ - key: LogtoJwtTokenKey.ClientCredentials, - value: payload, - useCase: 'test', - }); + expect(tenantContext.libraries.jwtCustomizers.deployJwtCustomizerScript).toHaveBeenCalledWith( + expect.any(ConsoleLog), + { + key: LogtoJwtTokenKey.ClientCredentials, + value: payload, + useCase: 'test', + } + ); expect(mockCloudClient.post).toHaveBeenCalledWith('/api/services/custom-jwt', { body: payload, diff --git a/packages/core/src/routes/logto-config/jwt-customizer.ts b/packages/core/src/routes/logto-config/jwt-customizer.ts index ac8bd2473d2..f69cadaa630 100644 --- a/packages/core/src/routes/logto-config/jwt-customizer.ts +++ b/packages/core/src/routes/logto-config/jwt-customizer.ts @@ -15,6 +15,7 @@ import { EnvSet } from '#src/env-set/index.js'; import RequestError, { formatZodError } from '#src/errors/RequestError/index.js'; import koaGuard, { parse } from '#src/middleware/koa-guard.js'; import koaQuotaGuard from '#src/middleware/koa-quota-guard.js'; +import { getConsoleLogFromContext } from '#src/utils/console.js'; import type { ManagementApiRouter, RouterInitArgs } from '../types.js'; @@ -78,7 +79,7 @@ export default function logtoConfigJwtCustomizerRoutes { - const jwtCustomizer = await getJwtCustomizers(); + const jwtCustomizer = await getJwtCustomizers(getConsoleLogFromContext(ctx)); ctx.body = Object.values(LogtoJwtTokenKey) .filter((key) => jwtCustomizer[key]) .map((key) => ({ key, value: jwtCustomizer[key] })); @@ -194,7 +195,7 @@ export default function logtoConfigJwtCustomizerRoutes value.charAt(0).toUpperCase() + value.slice(1); @@ -166,7 +166,7 @@ export const validateSupplement = ( export const validateSwaggerDocument = (document: OpenAPIV3.Document) => { for (const [path, operations] of Object.entries(document.paths)) { if (path.startsWith('/api/interaction')) { - consoleLog.warn(`Path \`${path}\` is not documented. Do something!`); + devConsole.warn(`Path \`${path}\` is not documented. Do something!`); continue; } diff --git a/packages/core/src/routes/user-assets.ts b/packages/core/src/routes/user-assets.ts index 19c155bccb1..cf1f7e637fd 100644 --- a/packages/core/src/routes/user-assets.ts +++ b/packages/core/src/routes/user-assets.ts @@ -15,7 +15,7 @@ import RequestError from '#src/errors/RequestError/index.js'; import koaGuard from '#src/middleware/koa-guard.js'; import SystemContext from '#src/tenants/SystemContext.js'; import assertThat from '#src/utils/assert-that.js'; -import { consoleLog } from '#src/utils/console.js'; +import { getConsoleLogFromContext } from '#src/utils/console.js'; import { uploadFileGuard } from '#src/utils/storage/consts.js'; import { buildUploadFile } from '#src/utils/storage/index.js'; import { getTenantId } from '#src/utils/tenant.js'; @@ -92,7 +92,7 @@ export default function userAssetsRoutes( ctx.body = result; } catch (error: unknown) { - consoleLog.error(error); + getConsoleLogFromContext(ctx).error(error); throw new RequestError({ code: 'storage.upload_error', status: 500, diff --git a/packages/core/src/tenants/SystemContext.ts b/packages/core/src/tenants/SystemContext.ts index 2c9661aa9f9..49bd393ca13 100644 --- a/packages/core/src/tenants/SystemContext.ts +++ b/packages/core/src/tenants/SystemContext.ts @@ -13,7 +13,7 @@ import type { CommonQueryMethods } from '@silverhand/slonik'; import { type ZodType } from 'zod'; import { createSystemsQuery } from '#src/queries/system.js'; -import { consoleLog } from '#src/utils/console.js'; +import { devConsole } from '#src/utils/console.js'; export default class SystemContext { static shared = new SystemContext(); @@ -70,7 +70,7 @@ export default class SystemContext { const result = guard.safeParse(record.value); if (!result.success) { - consoleLog.error(`Failed to parse ${key} config:`, result.error); + devConsole.error(`Failed to parse ${key} config:`, result.error); return; } diff --git a/packages/core/src/tenants/Tenant.test.ts b/packages/core/src/tenants/Tenant.test.ts index f549b55a57a..c250a4de6e2 100644 --- a/packages/core/src/tenants/Tenant.test.ts +++ b/packages/core/src/tenants/Tenant.test.ts @@ -54,7 +54,7 @@ describe('Tenant', () => { }); it('should call middleware factories for user tenants', async () => { - await Tenant.create(defaultTenantId, new RedisCache()); + await Tenant.create({ id: defaultTenantId, redisCache: new RedisCache() }); for (const [, middleware, shouldCall] of userMiddlewareList) { if (shouldCall) { @@ -66,7 +66,7 @@ describe('Tenant', () => { }); it('should call middleware factories for the admin tenant', async () => { - await Tenant.create(adminTenantId, new RedisCache()); + await Tenant.create({ id: adminTenantId, redisCache: new RedisCache() }); for (const [, middleware, shouldCall] of adminMiddlewareList) { if (shouldCall) { @@ -80,7 +80,7 @@ describe('Tenant', () => { describe('Tenant `.run()`', () => { it('should return a function ', async () => { - const tenant = await Tenant.create(defaultTenantId, new RedisCache()); + const tenant = await Tenant.create({ id: defaultTenantId, redisCache: new RedisCache() }); expect(typeof tenant.run).toBe('function'); }); }); @@ -88,7 +88,7 @@ describe('Tenant `.run()`', () => { describe('Tenant cache health check', () => { it('should set expiration timestamp in redis', async () => { const redisCache = new RedisCache(); - const tenant = await Tenant.create(defaultTenantId, redisCache); + const tenant = await Tenant.create({ id: defaultTenantId, redisCache }); expect(typeof tenant.invalidateCache).toBe('function'); Sinon.stub(tenant.wellKnownCache, 'set').value(jest.fn()); @@ -102,7 +102,7 @@ describe('Tenant cache health check', () => { }); it('should be able to check the health of tenant cache', async () => { - const tenant = await Tenant.create(defaultTenantId, new RedisCache()); + const tenant = await Tenant.create({ id: defaultTenantId, redisCache: new RedisCache() }); expect(typeof tenant.checkHealth).toBe('function'); expect(await tenant.checkHealth()).toBe(true); diff --git a/packages/core/src/tenants/Tenant.ts b/packages/core/src/tenants/Tenant.ts index ece5ed4e408..5fb45590af4 100644 --- a/packages/core/src/tenants/Tenant.ts +++ b/packages/core/src/tenants/Tenant.ts @@ -3,7 +3,6 @@ import type { MiddlewareType } from 'koa'; import Koa from 'koa'; import compose from 'koa-compose'; import koaCompress from 'koa-compress'; -import koaLogger from 'koa-logger'; import mount from 'koa-mount'; import type Provider from 'oidc-provider'; @@ -34,8 +33,18 @@ import Queries from './Queries.js'; import type TenantContext from './TenantContext.js'; import { getTenantDatabaseDsn } from './utils.js'; +/** Data for creating a tenant instance. */ +type CreateTenant = { + /** The unique identifier of the tenant. */ + id: string; + /** The cache store for the tenant. */ + redisCache: CacheStore; + /** The custom domain of the tenant, if applicable. */ + customDomain?: string; +}; + export default class Tenant implements TenantContext { - static async create(id: string, redisCache: CacheStore, customDomain?: string): Promise { + static async create({ id, redisCache, customDomain }: CreateTenant): Promise { // Treat the default database URL as the management URL const envSet = new EnvSet(id, await getTenantDatabaseDsn(id)); // Custom endpoint is used for building OIDC issuer URL when the request is a custom domain @@ -82,7 +91,6 @@ export default class Tenant implements TenantContext { // Init app const app = new Koa(); - app.use(koaLogger()); app.use(koaErrorHandler()); app.use(koaOidcErrorHandler()); app.use(koaSlonikErrorHandler()); diff --git a/packages/core/src/tenants/index.ts b/packages/core/src/tenants/index.ts index 5225a2d6cbd..cb39c2b443b 100644 --- a/packages/core/src/tenants/index.ts +++ b/packages/core/src/tenants/index.ts @@ -1,12 +1,15 @@ +import { ConsoleLog } from '@logto/shared'; +import chalk from 'chalk'; import { LRUCache } from 'lru-cache'; import { redisCache } from '#src/caches/index.js'; import { EnvSet } from '#src/env-set/index.js'; -import { consoleLog } from '#src/utils/console.js'; import Tenant from './Tenant.js'; -export class TenantPool { +const consoleLog = new ConsoleLog(chalk.magenta('tenant')); + +class TenantPool { protected cache = new LRUCache>({ max: EnvSet.values.tenantPoolSize, dispose: async (entry) => { @@ -29,7 +32,7 @@ export class TenantPool { } consoleLog.info('Init tenant:', tenantId, customDomain); - const newTenantPromise = Tenant.create(tenantId, redisCache, customDomain); + const newTenantPromise = Tenant.create({ id: tenantId, redisCache, customDomain }); this.cache.set(cacheKey, newTenantPromise); return newTenantPromise; diff --git a/packages/core/src/utils/cloudflare/utils.ts b/packages/core/src/utils/cloudflare/utils.ts index 4a58bfce36c..b6111d3e10f 100644 --- a/packages/core/src/utils/cloudflare/utils.ts +++ b/packages/core/src/utils/cloudflare/utils.ts @@ -1,13 +1,16 @@ import { parseJson } from '@logto/connector-kit'; import { type CloudflareData, DomainStatus } from '@logto/schemas'; +import { ConsoleLog } from '@logto/shared'; +import chalk from 'chalk'; import { type Response } from 'got'; import { type ZodType } from 'zod'; import assertThat from '../assert-that.js'; -import { consoleLog } from '../console.js'; import { type HandleResponse, cloudflareResponseGuard } from './types.js'; +const consoleLog = new ConsoleLog(chalk.magenta('cf')); + const parseCloudflareResponse = (body: string) => { const result = cloudflareResponseGuard.safeParse(parseJson(body)); diff --git a/packages/core/src/utils/connectors/index.ts b/packages/core/src/utils/connectors/index.ts index 30d0e4070fb..868bbfb9140 100644 --- a/packages/core/src/utils/connectors/index.ts +++ b/packages/core/src/utils/connectors/index.ts @@ -22,7 +22,7 @@ import RequestError from '#src/errors/RequestError/index.js'; import { type LogtoConnector } from './types.js'; -export const isPasswordlessLogtoConnector = ( +const isPasswordlessLogtoConnector = ( connector: LogtoConnector ): connector is LogtoConnector => connector.type !== ConnectorType.Social; diff --git a/packages/core/src/utils/console.test.ts b/packages/core/src/utils/console.test.ts new file mode 100644 index 00000000000..4a98aafe411 --- /dev/null +++ b/packages/core/src/utils/console.test.ts @@ -0,0 +1,47 @@ +import { ConsoleLog } from '@logto/shared'; +import Sinon from 'sinon'; + +import { EnvSet } from '#src/env-set/index.js'; + +import { SilentConsoleLog, getConsoleLogFromContext, unknownConsole } from './console.js'; + +describe('console', () => { + afterEach(() => { + Sinon.restore(); + }); + + describe('getConsoleLogFromContext', () => { + it('should return the console log from the context', () => { + const context = { + console: new ConsoleLog('test'), + }; + const result = getConsoleLogFromContext(context); + + expect(result).toBe(context.console); + }); + + it('should throw an error if the context does not have a console log in development', () => { + Sinon.stub(EnvSet, 'values').get(() => ({ isProduction: false, isUnitTest: false })); + const context = {}; + const act = () => getConsoleLogFromContext(context); + + expect(act).toThrowError( + 'Failed to get console log from context, please provide a valid context.' + ); + }); + + it('should return a silent console log in unit test', () => { + const context = {}; + const result = getConsoleLogFromContext(context); + + expect(result).toBeInstanceOf(SilentConsoleLog); + }); + + it('should return the unknown console log in production', () => { + Sinon.stub(EnvSet, 'values').get(() => ({ isProduction: true, isUnitTest: false })); + const context = {}; + const result = getConsoleLogFromContext(context); + expect(result).toBe(unknownConsole); + }); + }); +}); diff --git a/packages/core/src/utils/console.ts b/packages/core/src/utils/console.ts index 3970eb77282..fe593227701 100644 --- a/packages/core/src/utils/console.ts +++ b/packages/core/src/utils/console.ts @@ -1,3 +1,56 @@ import { ConsoleLog } from '@logto/shared'; +import { noop } from '@silverhand/essentials'; +import chalk from 'chalk'; -export const consoleLog: ConsoleLog = new ConsoleLog(); +import { EnvSet } from '#src/env-set/index.js'; + +export class SilentConsoleLog extends ConsoleLog { + plain = noop; + info = noop; + succeed = noop; + warn = noop; + error = noop; + fatal = () => { + // eslint-disable-next-line unicorn/no-process-exit + process.exit(1); + }; +} + +/** The fallback console log with `unknown` prefix. */ +export const unknownConsole: ConsoleLog = new ConsoleLog(chalk.yellow('unknown')); + +/** + * The development console log with `dev` prefix. Usually you should use context-aware console log + * instead of this. + */ +export const devConsole: ConsoleLog = new ConsoleLog(chalk.magenta('dev')); + +/** + * Try to get the `ConsoleLog` instance from the context by checking if the `console` property is + * an instance of `ConsoleLog`. If it is not: + * + * - In production, return the default console log with `unknown` prefix. + * - In development or testing, throw an error. + * + * The in-context console log is used to provide a more context-aware logging experience. + */ +// eslint-disable-next-line @typescript-eslint/ban-types -- We need to accept any object as context +export const getConsoleLogFromContext = (context: object): ConsoleLog => { + if ('console' in context && context.console instanceof ConsoleLog) { + return context.console; + } + + // In production or unit testing, we should safely return an instance of `ConsoleLog` + if (!EnvSet.values.isProduction && !EnvSet.values.isUnitTest) { + throw new Error('Failed to get console log from context, please provide a valid context.'); + } + + if (EnvSet.values.isUnitTest) { + return new SilentConsoleLog(); + } + + unknownConsole.warn( + 'Failed to get console log from context, returning the unknown-prefixed `ConsoleLog`.' + ); + return unknownConsole; +}; diff --git a/packages/core/src/utils/request.ts b/packages/core/src/utils/request.ts new file mode 100644 index 00000000000..73c27ed8c13 --- /dev/null +++ b/packages/core/src/utils/request.ts @@ -0,0 +1,21 @@ +import { type ExceptionTelemetry } from '@logto/app-insights/node'; + +// eslint-disable-next-line @typescript-eslint/ban-types +const getRequestIdFromContext = (context: object): string | undefined => { + if ('requestId' in context && typeof context.requestId === 'string') { + return context.requestId; + } + + return undefined; +}; + +// eslint-disable-next-line @typescript-eslint/ban-types +export const buildAppInsightsTelemetry = (context: object): Partial => { + const requestId = getRequestIdFromContext(context); + + if (requestId) { + return { properties: { requestId } }; + } + + return {}; +}; diff --git a/packages/core/src/utils/tenant.ts b/packages/core/src/utils/tenant.ts index 9ac387c0a23..b53402908bc 100644 --- a/packages/core/src/utils/tenant.ts +++ b/packages/core/src/utils/tenant.ts @@ -6,7 +6,8 @@ import { type CommonQueryMethods } from '@silverhand/slonik'; import { redisCache } from '#src/caches/index.js'; import { EnvSet, getTenantEndpoint } from '#src/env-set/index.js'; import { createDomainsQueries } from '#src/queries/domains.js'; -import { consoleLog } from '#src/utils/console.js'; + +import { devConsole } from './console.js'; const normalizePathname = (pathname: string) => pathname + conditionalString(!pathname.endsWith('/') && '/'); @@ -105,7 +106,7 @@ export const getTenantId = async ( } if ((!isProduction || isIntegrationTest) && developmentTenantId) { - consoleLog.warn(`Found dev tenant ID ${developmentTenantId}.`); + devConsole.warn(`Found dev tenant ID ${developmentTenantId}.`); return [developmentTenantId, false]; } diff --git a/packages/integration-tests/src/tests/api/health-check.test.ts b/packages/integration-tests/src/tests/api/health-check.test.ts index f5577a91e36..1172cd48c72 100644 --- a/packages/integration-tests/src/tests/api/health-check.test.ts +++ b/packages/integration-tests/src/tests/api/health-check.test.ts @@ -4,4 +4,9 @@ describe('health check', () => { it('should have a health state', async () => { expect(await api.get('status')).toHaveProperty('status', 204); }); + + it('should return request id in headers', async () => { + const { headers } = await api.get('status'); + expect(headers.has('logto-core-request-id')).toBe(true); + }); }); diff --git a/packages/integration-tests/src/tests/api/well-known.test.ts b/packages/integration-tests/src/tests/api/well-known.test.ts index 4aaf7ce7589..d26f3f46ac5 100644 --- a/packages/integration-tests/src/tests/api/well-known.test.ts +++ b/packages/integration-tests/src/tests/api/well-known.test.ts @@ -18,6 +18,11 @@ describe('.well-known api', () => { expect(response instanceof HTTPError && response.response.status === 404).toBe(true); }); + it('should return request id in headers', async () => { + const { headers } = await adminTenantApi.get(`.well-known/endpoints/123`); + expect(headers.has('logto-core-request-id')).toBe(true); + }); + it('get /.well-known/sign-in-exp for console', async () => { const response = await adminTenantApi.get('.well-known/sign-in-exp').json(); diff --git a/packages/shared/src/node/env/ConsoleLog.test.ts b/packages/shared/src/node/env/ConsoleLog.test.ts new file mode 100644 index 00000000000..ec38104c13c --- /dev/null +++ b/packages/shared/src/node/env/ConsoleLog.test.ts @@ -0,0 +1,87 @@ +import { noop } from '@silverhand/essentials'; +import { describe, expect, it, vi } from 'vitest'; + +import ConsoleLog from './ConsoleLog.js'; + +describe('ConsoleLog', () => { + it('logs the plain message as is', () => { + const logSpy = vi.spyOn(console, 'log').mockImplementation(noop); + new ConsoleLog().plain('message', 1, undefined, null); + + expect(logSpy).toHaveBeenCalledWith('message', 1, undefined, null); + }); + + it('logs the info message with an info prefix', () => { + const logSpy = vi.spyOn(console, 'log').mockImplementation(noop); + new ConsoleLog().info('message', 1, null); + + expect(logSpy).toHaveBeenCalledWith(expect.stringMatching(/info/), 'message', 1, null); + }); + + it('logs the success message with an info and checkmark prefix', () => { + const logSpy = vi.spyOn(console, 'log').mockImplementation(noop); + new ConsoleLog().succeed('message', 1, undefined, null); + + expect(logSpy).toHaveBeenCalledWith( + expect.stringMatching(/info/), + expect.stringMatching(/✔/), + 'message', + 1, + undefined, + null + ); + }); + + it('logs the warn message with a warn prefix', () => { + const warnSpy = vi.spyOn(console, 'warn').mockImplementation(noop); + new ConsoleLog().warn('message', { a: 1 }); + + expect(warnSpy).toHaveBeenCalledWith(expect.stringMatching(/warn/), 'message', { a: 1 }); + }); + + it('logs the error message with a error prefix', () => { + const errorSpy = vi.spyOn(console, 'error').mockImplementation(noop); + new ConsoleLog().error('message', { a: 1 }); + + expect(errorSpy).toHaveBeenCalledWith(expect.stringMatching(/error/), 'message', { + a: 1, + }); + }); + + it('logs the fatal message with a fatal prefix and exits the process', () => { + const errorSpy = vi.spyOn(console, 'error').mockImplementation(noop); + // @ts-expect-error process exit is mocked + const exitSpy = vi.spyOn(process, 'exit').mockImplementation(noop); + new ConsoleLog().fatal('message', { a: 1 }); + + expect(errorSpy).toHaveBeenCalledWith(expect.stringMatching(/fatal/), 'message', { a: 1 }); + expect(exitSpy).toHaveBeenCalledWith(1); + }); + + it('logs the message with a custom prefix', () => { + const logSpy = vi.spyOn(console, 'log').mockImplementation(noop); + new ConsoleLog('custom').plain('message', 1, null); + + expect(logSpy).toHaveBeenCalledWith('custom ', 'message', 1, null); + }); + + it('logs the message with a custom prefix and an info prefix', () => { + const logSpy = vi.spyOn(console, 'log').mockImplementation(noop); + new ConsoleLog('custom').info('message', 1, null); + + expect(logSpy).toHaveBeenCalledWith( + 'custom ', + expect.stringMatching(/info/), + 'message', + 1, + null + ); + }); + + it('logs the message with a custom prefix and padding', () => { + const logSpy = vi.spyOn(console, 'log').mockImplementation(noop); + new ConsoleLog('custom', 10).plain('message', 1, null); + + expect(logSpy).toHaveBeenCalledWith('custom ', 'message', 1, null); + }); +}); diff --git a/packages/shared/src/node/env/ConsoleLog.ts b/packages/shared/src/node/env/ConsoleLog.ts index 71e469520d0..4e5fe89d756 100644 --- a/packages/shared/src/node/env/ConsoleLog.ts +++ b/packages/shared/src/node/env/ConsoleLog.ts @@ -8,10 +8,24 @@ export default class ConsoleLog { fatal: chalk.bold(chalk.red('fatal')), }); - plain = console.log; + constructor( + /** A prefix to prepend to all log messages. */ + public readonly prefix?: string, + /** + * The number of spaces to pad the prefix. For example, if the prefix is `custom` and the + * padding is 8, the output will be `custom `. + * + * @default 8 + */ + public readonly padding = 8 + ) {} + + plain: typeof console.log = (...args) => { + console.log(...this.getArgs(args)); + }; info: typeof console.log = (...args) => { - console.log(ConsoleLog.prefixes.info, ...args); + this.plain(ConsoleLog.prefixes.info, ...args); }; succeed: typeof console.log = (...args) => { @@ -19,16 +33,25 @@ export default class ConsoleLog { }; warn: typeof console.log = (...args) => { - console.warn(ConsoleLog.prefixes.warn, ...args); + console.warn(...this.getArgs([ConsoleLog.prefixes.warn, ...args])); }; error: typeof console.log = (...args) => { - console.error(ConsoleLog.prefixes.error, ...args); + console.error(...this.getArgs([ConsoleLog.prefixes.error, ...args])); }; fatal: (...args: Parameters) => never = (...args) => { - console.error(ConsoleLog.prefixes.fatal, ...args); + console.error(...this.getArgs([ConsoleLog.prefixes.fatal, ...args])); // eslint-disable-next-line unicorn/no-process-exit process.exit(1); }; + + protected getArgs(args: Parameters) { + if (this.prefix) { + // eslint-disable-next-line @typescript-eslint/no-unsafe-return + return [this.prefix.padEnd(this.padding), ...args]; + } + + return args; + } } From ac3575a02383f26b800077b38e01727cfc827812 Mon Sep 17 00:00:00 2001 From: Gao Sun Date: Wed, 1 May 2024 23:49:30 +0800 Subject: [PATCH 341/687] refactor: remove app insights domains from security headers (#5814) --- packages/core/src/middleware/koa-security-headers.ts | 11 ++--------- 1 file changed, 2 insertions(+), 9 deletions(-) diff --git a/packages/core/src/middleware/koa-security-headers.ts b/packages/core/src/middleware/koa-security-headers.ts index 5444fba618e..e43312114c9 100644 --- a/packages/core/src/middleware/koa-security-headers.ts +++ b/packages/core/src/middleware/koa-security-headers.ts @@ -37,7 +37,6 @@ export default function koaSecurityHeaders( const adminOrigins = isCloud ? cloudUrlSet.origins : adminUrlSet.origins; const coreOrigins = urlSet.origins; const developmentOrigins = conditionalArray(!isProduction && 'ws:'); - const appInsightsOrigins = ['https://*.applicationinsights.azure.com']; // We use react-monaco-editor for code editing in the admin console. It loads the monaco editor asynchronously from a CDN. // Allow the CDN src in the CSP. @@ -92,7 +91,7 @@ export default function koaSecurityHeaders( "'unsafe-inline'", ...conditionalArray(!isProduction && "'unsafe-eval'"), ], - connectSrc: ["'self'", tenantEndpointOrigin, ...developmentOrigins, ...appInsightsOrigins], + connectSrc: ["'self'", tenantEndpointOrigin, ...developmentOrigins], // WARNING: high risk Need to allow self hosted terms of use page loaded in an iframe frameSrc: ["'self'", 'https:'], // Alow loaded by console preview iframe @@ -117,13 +116,7 @@ export default function koaSecurityHeaders( ...conditionalArray(!isProduction && ["'unsafe-eval'", "'unsafe-inline'"]), ...monacoEditorCDNSource, ], - connectSrc: [ - "'self'", - ...adminOrigins, - ...coreOrigins, - ...developmentOrigins, - ...appInsightsOrigins, - ], + connectSrc: ["'self'", ...adminOrigins, ...coreOrigins, ...developmentOrigins], // Allow Main Flow origin loaded in preview iframe frameSrc: ["'self'", ...adminOrigins, ...coreOrigins], }, From 3e5ffc499116546b876d76064e55ac029f6fa2cb Mon Sep 17 00:00:00 2001 From: Xiao Yijun Date: Mon, 6 May 2024 09:54:48 +0800 Subject: [PATCH 342/687] feat(connector): add hugging face connector (#5797) --- .changeset/nasty-dots-lie.md | 5 + .vscode/settings.json | 7 +- .../connector-huggingface/README.md | 64 +++ .../connectors/connector-huggingface/logo.svg | 19 + .../connector-huggingface/package.json | 74 +++ .../connector-huggingface/src/constant.ts | 33 ++ .../connector-huggingface/src/index.test.ts | 133 +++++ .../connector-huggingface/src/index.ts | 154 ++++++ .../connector-huggingface/src/types.ts | 36 ++ pnpm-lock.yaml | 475 +++++++++++++----- 10 files changed, 884 insertions(+), 116 deletions(-) create mode 100644 .changeset/nasty-dots-lie.md create mode 100644 packages/connectors/connector-huggingface/README.md create mode 100644 packages/connectors/connector-huggingface/logo.svg create mode 100644 packages/connectors/connector-huggingface/package.json create mode 100644 packages/connectors/connector-huggingface/src/constant.ts create mode 100644 packages/connectors/connector-huggingface/src/index.test.ts create mode 100644 packages/connectors/connector-huggingface/src/index.ts create mode 100644 packages/connectors/connector-huggingface/src/types.ts diff --git a/.changeset/nasty-dots-lie.md b/.changeset/nasty-dots-lie.md new file mode 100644 index 00000000000..dc7d517c3d3 --- /dev/null +++ b/.changeset/nasty-dots-lie.md @@ -0,0 +1,5 @@ +--- +"@logto/connector-huggingface": minor +--- + +add Hugging Face social connector diff --git a/.vscode/settings.json b/.vscode/settings.json index d69e1c7202c..b83dc8dfa43 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -39,20 +39,21 @@ "CIAM", "codecov", "hasura", + "huggingface", "Logto", + "mailgun", "oidc", "passcode", "passcodes", "Passwordless", "pnpm", + "sendgrid", "silverhand", "slonik", "stylelint", "timestamptz", "topbar", - "withtyped", - "sendgrid", - "mailgun", "upsell", + "withtyped" ] } diff --git a/packages/connectors/connector-huggingface/README.md b/packages/connectors/connector-huggingface/README.md new file mode 100644 index 00000000000..4a0b20234d8 --- /dev/null +++ b/packages/connectors/connector-huggingface/README.md @@ -0,0 +1,64 @@ +# Hugging Face connector + +The official Logto connector for Hugging Face social sign-in. + +**Table of contents** + +- [Hugging Face connector](#hugging-face-connector) + - [Get started](#get-started) + - [Sign in with Hugging Face account](#sign-in-with-hugging-face-account) + - [Create an OAuth app in the Hugging Face](#create-an-oauth-app-in-the-hugging-face) + - [Managing Hugging Face OAuth apps](#managing-hugging-face-oauth-apps) + - [Configure your connector](#configure-your-connector) + - [Config types](#config-types) + - [Test Hugging Face connector](#test-hugging-face-connector) + - [Reference](#reference) + + +## Get started + +The Hugging Face connector enables end-users to sign in to your application using their own Hugging Face accounts via Hugging Face OAuth / OpenID connect flow. + +## Sign in with Hugging Face account + +Go to the [Hugging Face website](https://huggingface.co/) and sign in with your Hugging Face account. You may register a new account if you don't have one. + +## Create an OAuth app in the Hugging Face + +Follow the [Creating an oauth app](https://huggingface.co/docs/hub/en/oauth#creating-an-oauth-app) guide, and register a new application. + +In the creation process, you will need to provide the following information: + +- **Application Name**: The name of your application. +- **Homepage URL**: The URL of your application's homepage or landing page. +- **Logo URL**: The URL of your application's logo. +- **Scopes**: The scopes allowed for the OAuth app. For Hugging Face connector, usually use `profile` to get the user's profile information and `email` to get the user's email address. Ensure these scopes are allowed in your Hugging Face OAuth app if you want to use them. +- **Redirect URI**: The URL to redirect the user to after they have authenticated. You can find the redirect URI in the Logto Admin Console when you're creating a Hugging Face connector or in the created Hugging Face connector details page. + +## Managing Hugging Face OAuth apps + +Go to the [Connected Applications](https://huggingface.co/settings/connected-applications) page, you can add, edit or delete existing OAuth apps. +You can also find `Client ID` and generate `App secrets` in corresponding OAuth app settings pages. + +## Configure your connector + +Fill out the `clientId` and `clientSecret` field with _Client ID_ and _App Secret_ you've got from OAuth app detail pages mentioned in the previous section. + +`scope` is a space-delimited list of [Hugging Face supported scopes](https://huggingface.co/docs/hub/en/oauth#currently-supported-scopes). If not provided, scope defaults to be `profile`. For Hugging Face connector, the scope you may want to use is `profile` and `email`. `profile` scope is required to get the user's profile information, and `email` scope is required to get the user's email address. Ensure you have allowed these scopes in your Hugging Face OAuth app (configured in [Create an OAuth app in the Hugging Face](#create-an-oauth-app-in-the-hugging-face) section). + +### Config types + +| Name | Type | +|--------------|--------| +| clientId | string | +| clientSecret | string | +| scope | string | + + +## Test Hugging Face connector + +That's it. The Hugging Face connector should be available now. Don't forget to [Enable connector in sign-in experience](https://docs.logto.io/docs/recipes/configure-connectors/social-connector/enable-social-sign-in/). + +## Reference + +- [Hugging Face - Sign in with Hugging Face](https://huggingface.co/docs/hub/en/oauth#sign-in-with-hugging-face) diff --git a/packages/connectors/connector-huggingface/logo.svg b/packages/connectors/connector-huggingface/logo.svg new file mode 100644 index 00000000000..954043a4e4e --- /dev/null +++ b/packages/connectors/connector-huggingface/logo.svg @@ -0,0 +1,19 @@ + + + + + + + + + + + + + + + + + + + diff --git a/packages/connectors/connector-huggingface/package.json b/packages/connectors/connector-huggingface/package.json new file mode 100644 index 00000000000..10841e88466 --- /dev/null +++ b/packages/connectors/connector-huggingface/package.json @@ -0,0 +1,74 @@ +{ + "name": "@logto/connector-huggingface", + "version": "0.0.0", + "description": "Hugging Face connector implementation.", + "author": "Silverhand Inc. ", + "dependencies": { + "@logto/connector-kit": "workspace:^3.0.0", + "@logto/connector-oauth": "workspace:^1.2.0", + "@silverhand/essentials": "^2.9.0", + "ky": "^1.2.3", + "zod": "^3.22.4" + }, + "main": "./lib/index.js", + "module": "./lib/index.js", + "exports": "./lib/index.js", + "license": "MPL-2.0", + "type": "module", + "files": [ + "lib", + "docs", + "logo.svg", + "logo-dark.svg" + ], + "scripts": { + "precommit": "lint-staged", + "build:test": "rm -rf lib/ && tsc -p tsconfig.test.json --sourcemap", + "build": "rm -rf lib/ && tsc -p tsconfig.build.json --noEmit && rollup -c", + "dev": "tsc -p tsconfig.build.json --watch --preserveWatchOutput --incremental", + "lint": "eslint --ext .ts src", + "lint:report": "pnpm lint --format json --output-file report.json", + "test": "vitest src", + "test:ci": "pnpm run test --silent --coverage", + "prepublishOnly": "pnpm build" + }, + "engines": { + "node": "^20.9.0" + }, + "eslintConfig": { + "extends": "@silverhand", + "settings": { + "import/core-modules": [ + "@silverhand/essentials", + "got", + "nock", + "snakecase-keys", + "zod" + ] + } + }, + "prettier": "@silverhand/eslint-config/.prettierrc", + "publishConfig": { + "access": "public" + }, + "devDependencies": { + "@rollup/plugin-commonjs": "^25.0.7", + "@rollup/plugin-json": "^6.1.0", + "@rollup/plugin-node-resolve": "^15.2.3", + "@rollup/plugin-typescript": "^11.1.6", + "@silverhand/eslint-config": "6.0.1", + "@silverhand/ts-config": "6.0.0", + "@types/node": "^20.11.20", + "@types/supertest": "^6.0.2", + "@vitest/coverage-v8": "^1.4.0", + "eslint": "^8.56.0", + "lint-staged": "^15.0.2", + "nock": "14.0.0-beta.6", + "prettier": "^3.0.0", + "rollup": "^4.12.0", + "rollup-plugin-output-size": "^1.3.0", + "supertest": "^7.0.0", + "typescript": "^5.3.3", + "vitest": "^1.4.0" + } +} diff --git a/packages/connectors/connector-huggingface/src/constant.ts b/packages/connectors/connector-huggingface/src/constant.ts new file mode 100644 index 00000000000..0d33191a6f3 --- /dev/null +++ b/packages/connectors/connector-huggingface/src/constant.ts @@ -0,0 +1,33 @@ +import type { ConnectorMetadata } from '@logto/connector-kit'; +import { ConnectorPlatform } from '@logto/connector-kit'; +import { clientIdFormItem, clientSecretFormItem, scopeFormItem } from '@logto/connector-oauth'; + +export const authorizationEndpoint = 'https://huggingface.co/oauth/authorize'; +export const tokenEndpoint = 'https://huggingface.co/oauth/token'; +export const userInfoEndpoint = 'https://huggingface.co/oauth/userinfo'; + +export const defaultMetadata: ConnectorMetadata = { + id: 'huggingface-universal', + target: 'huggingface', + platform: ConnectorPlatform.Universal, + name: { + en: 'Hugging Face', + }, + logo: './logo.svg', + logoDark: null, + description: { + en: 'Hugging Face is a machine learning (ML) and data science platform and community that helps users build, deploy and train machine learning models.', + }, + readme: './README.md', + formItems: [ + clientIdFormItem, + clientSecretFormItem, + { + ...scopeFormItem, + description: + "`profile` is required to get user's profile information, `email` is required to get user's email address. These scopes can be used individually or in combination; if no scopes are specified, `profile` will be used by default.", + }, + ], +}; + +export const defaultTimeout = 5000; diff --git a/packages/connectors/connector-huggingface/src/index.test.ts b/packages/connectors/connector-huggingface/src/index.test.ts new file mode 100644 index 00000000000..e0b79e4904c --- /dev/null +++ b/packages/connectors/connector-huggingface/src/index.test.ts @@ -0,0 +1,133 @@ +import nock from 'nock'; + +import { ConnectorError, ConnectorErrorCodes } from '@logto/connector-kit'; + +import { authorizationEndpoint, tokenEndpoint, userInfoEndpoint } from './constant.js'; +import createConnector from './index.js'; + +const getConfig = vi.fn().mockResolvedValue({ + clientId: '', + clientSecret: '', + scope: 'profile email', +}); + +const getSessionMock = vi.fn().mockResolvedValue({ redirectUri: 'http://localhost:3000/callback' }); + +describe('Hugging Face connector', () => { + beforeEach(() => { + nock(tokenEndpoint).post('').reply(200, { + access_token: 'access_token', + scope: 'scope', + token_type: 'token_type', + }); + }); + + afterEach(() => { + nock.cleanAll(); + vi.clearAllMocks(); + }); + + it('should get a valid uri by redirectUri and state', async () => { + const connector = await createConnector({ getConfig }); + const authorizationUri = await connector.getAuthorizationUri( + { + state: 'some_state', + redirectUri: 'http://localhost:3000/callback', + connectorId: 'some_connector_id', + connectorFactoryId: 'some_connector_factory_id', + jti: 'some_jti', + headers: {}, + }, + vi.fn() + ); + + expect(authorizationUri).toEqual( + `${authorizationEndpoint}?${new URLSearchParams({ + response_type: 'code', + client_id: '', + scope: 'profile email', + redirect_uri: 'http://localhost:3000/callback', + state: 'some_state', + }).toString()}` + ); + }); + + it('should get valid SocialUserInfo', async () => { + nock(userInfoEndpoint).get('').reply(200, { + sub: 'id', + name: 'name', + email: 'email', + picture: 'picture', + }); + + const connector = await createConnector({ getConfig }); + const socialUserInfo = await connector.getUserInfo({ code: 'code' }, getSessionMock); + + expect(socialUserInfo).toStrictEqual({ + id: 'id', + avatar: 'picture', + name: 'name', + email: 'email', + rawData: { + sub: 'id', + name: 'name', + email: 'email', + picture: 'picture', + }, + }); + }); + + it('throws AuthorizationFailed error if authentication failed', async () => { + const connector = await createConnector({ getConfig }); + await expect( + connector.getUserInfo({ error: 'some error' }, getSessionMock) + ).rejects.toStrictEqual( + new ConnectorError(ConnectorErrorCodes.AuthorizationFailed, { error: 'some error' }) + ); + }); + + it('throws InvalidResponse error if token response is invalid', async () => { + // Clear token response mock + nock.cleanAll(); + + nock(tokenEndpoint).post('').reply(200, { + invalid_filed: true, + }); + + const connector = await createConnector({ getConfig }); + await expect(connector.getUserInfo({ code: 'code' }, getSessionMock)).rejects.toSatisfy( + (connectorError) => + (connectorError as ConnectorError).code === ConnectorErrorCodes.InvalidResponse + ); + }); + + it('throws InvalidResponse error if userinfo response is invalid', async () => { + nock(userInfoEndpoint).get('').reply(200, { + id: 'id', + }); + + const connector = await createConnector({ getConfig }); + await expect(connector.getUserInfo({ code: 'code' }, getSessionMock)).rejects.toSatisfy( + (connectorError) => + (connectorError as ConnectorError).code === ConnectorErrorCodes.InvalidResponse + ); + }); + + it('throws SocialAccessTokenInvalid error if user info responded with 401', async () => { + nock(userInfoEndpoint).get('').reply(401); + + const connector = await createConnector({ getConfig }); + await expect(connector.getUserInfo({ code: 'code' }, getSessionMock)).rejects.toStrictEqual( + new ConnectorError(ConnectorErrorCodes.SocialAccessTokenInvalid) + ); + }); + + it('throws General error if user info responded with a non-401 error', async () => { + nock(userInfoEndpoint).get('').reply(422); + + const connector = await createConnector({ getConfig }); + await expect(connector.getUserInfo({ code: 'code' }, getSessionMock)).rejects.toStrictEqual( + new ConnectorError(ConnectorErrorCodes.General) + ); + }); +}); diff --git a/packages/connectors/connector-huggingface/src/index.ts b/packages/connectors/connector-huggingface/src/index.ts new file mode 100644 index 00000000000..398b166f7fa --- /dev/null +++ b/packages/connectors/connector-huggingface/src/index.ts @@ -0,0 +1,154 @@ +import { conditional, assert } from '@silverhand/essentials'; + +import type { + GetAuthorizationUri, + GetUserInfo, + SocialConnector, + CreateConnector, + GetConnectorConfig, +} from '@logto/connector-kit'; +import { + ConnectorError, + ConnectorErrorCodes, + validateConfig, + ConnectorType, + parseJson, +} from '@logto/connector-kit'; +import { + constructAuthorizationUri, + oauth2AuthResponseGuard, + requestTokenEndpoint, + TokenEndpointAuthMethod, +} from '@logto/connector-oauth'; +import ky, { HTTPError } from 'ky'; + +import { + authorizationEndpoint, + userInfoEndpoint, + defaultMetadata, + defaultTimeout, + tokenEndpoint, +} from './constant.js'; +import { + accessTokenResponseGuard, + huggingfaceConnectorConfigGuard, + userInfoResponseGuard, +} from './types.js'; + +const getAuthorizationUri = + (getConfig: GetConnectorConfig): GetAuthorizationUri => + async ({ state, redirectUri }, setSession) => { + const config = await getConfig(defaultMetadata.id); + validateConfig(config, huggingfaceConnectorConfigGuard); + + const { clientId, scope } = config; + + await setSession({ redirectUri }); + + return constructAuthorizationUri(authorizationEndpoint, { + responseType: 'code', + clientId, + scope: scope ?? 'profile', // Defaults to 'profile' if not provided + redirectUri, + state, + }); + }; + +const getUserInfo = + (getConfig: GetConnectorConfig): GetUserInfo => + async (data, getSession) => { + const authResponseResult = oauth2AuthResponseGuard.safeParse(data); + + if (!authResponseResult.success) { + throw new ConnectorError(ConnectorErrorCodes.AuthorizationFailed, data); + } + + const { code } = authResponseResult.data; + + const config = await getConfig(defaultMetadata.id); + validateConfig(config, huggingfaceConnectorConfigGuard); + + const { clientId, clientSecret } = config; + const { redirectUri } = await getSession(); + + if (!redirectUri) { + throw new ConnectorError(ConnectorErrorCodes.General, { + message: 'Cannot find `redirectUri` from connector session.', + }); + } + + const tokenResponse = await requestTokenEndpoint({ + tokenEndpoint, + tokenEndpointAuthOptions: { + method: TokenEndpointAuthMethod.ClientSecretBasic, + }, + tokenRequestBody: { + grantType: 'authorization_code', + code, + redirectUri, + clientId, + clientSecret, + }, + }); + + const parsedTokenResponse = accessTokenResponseGuard.safeParse(await tokenResponse.json()); + + if (!parsedTokenResponse.success) { + throw new ConnectorError(ConnectorErrorCodes.InvalidResponse, parsedTokenResponse.error); + } + + const { access_token: accessToken, token_type: tokenType } = parsedTokenResponse.data; + + assert(accessToken, new ConnectorError(ConnectorErrorCodes.SocialAuthCodeInvalid)); + + try { + const userInfoResponse = await ky.get(userInfoEndpoint, { + headers: { + authorization: `${tokenType} ${accessToken}`, + }, + timeout: defaultTimeout, + }); + + const rawData = parseJson(await userInfoResponse.text()); + + const parsedUserInfoResponse = userInfoResponseGuard.safeParse(rawData); + + if (!parsedUserInfoResponse.success) { + throw new ConnectorError(ConnectorErrorCodes.InvalidResponse, parsedUserInfoResponse.error); + } + + const { sub, picture, email, name } = parsedUserInfoResponse.data; + + return { + id: sub, + avatar: conditional(picture), + email: conditional(email), + name: conditional(name), + rawData, + }; + } catch (error: unknown) { + if (error instanceof HTTPError) { + const { response } = error; + + if (response.status === 401) { + throw new ConnectorError(ConnectorErrorCodes.SocialAccessTokenInvalid); + } + + throw new ConnectorError(ConnectorErrorCodes.General, await response.text()); + } + + throw error; + } + }; + +const createHuggingfaceConnector: CreateConnector = async ({ getConfig }) => { + return { + metadata: defaultMetadata, + type: ConnectorType.Social, + configGuard: huggingfaceConnectorConfigGuard, + getAuthorizationUri: getAuthorizationUri(getConfig), + getUserInfo: getUserInfo(getConfig), + }; +}; + +export default createHuggingfaceConnector; diff --git a/packages/connectors/connector-huggingface/src/types.ts b/packages/connectors/connector-huggingface/src/types.ts new file mode 100644 index 00000000000..3a6a066443a --- /dev/null +++ b/packages/connectors/connector-huggingface/src/types.ts @@ -0,0 +1,36 @@ +import { z } from 'zod'; + +import { oauth2ConfigGuard } from '@logto/connector-oauth'; + +export const huggingfaceConnectorConfigGuard = oauth2ConfigGuard.pick({ + clientId: true, + clientSecret: true, + scope: true, +}); + +export type HuggingfaceConnectorConfigGuard = z.infer; + +export const accessTokenResponseGuard = z.object({ + access_token: z.string(), + scope: z.string(), + token_type: z.string(), +}); + +export type AccessTokenResponse = z.infer; + +export const userInfoResponseGuard = z.object({ + sub: z.string(), + name: z.string().optional().nullable(), + picture: z.string().optional().nullable(), + email: z.string().optional().nullable(), +}); + +export type UserInfoResponse = z.infer; + +export const authorizationCallbackErrorGuard = z.object({ + error: z.string(), + error_description: z.string(), + error_uri: z.string(), +}); + +export const authResponseGuard = z.object({ code: z.string() }); diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index b8e4f967a40..206291d5b4c 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -1122,6 +1122,79 @@ importers: specifier: ^1.4.0 version: 1.4.0(@types/node@20.11.20) + packages/connectors/connector-huggingface: + dependencies: + '@logto/connector-kit': + specifier: workspace:^3.0.0 + version: link:../../toolkit/connector-kit + '@logto/connector-oauth': + specifier: workspace:^1.2.0 + version: link:../connector-oauth2 + '@silverhand/essentials': + specifier: ^2.9.0 + version: 2.9.0 + ky: + specifier: ^1.2.3 + version: 1.2.3 + zod: + specifier: ^3.22.4 + version: 3.22.4 + devDependencies: + '@rollup/plugin-commonjs': + specifier: ^25.0.7 + version: 25.0.7(rollup@4.14.3) + '@rollup/plugin-json': + specifier: ^6.1.0 + version: 6.1.0(rollup@4.14.3) + '@rollup/plugin-node-resolve': + specifier: ^15.2.3 + version: 15.2.3(rollup@4.14.3) + '@rollup/plugin-typescript': + specifier: ^11.1.6 + version: 11.1.6(rollup@4.14.3)(typescript@5.3.3) + '@silverhand/eslint-config': + specifier: 6.0.1 + version: 6.0.1(eslint@8.57.0)(prettier@3.0.0)(typescript@5.3.3) + '@silverhand/ts-config': + specifier: 6.0.0 + version: 6.0.0(typescript@5.3.3) + '@types/node': + specifier: ^20.11.20 + version: 20.12.7 + '@types/supertest': + specifier: ^6.0.2 + version: 6.0.2 + '@vitest/coverage-v8': + specifier: ^1.4.0 + version: 1.4.0(vitest@1.4.0) + eslint: + specifier: ^8.56.0 + version: 8.57.0 + lint-staged: + specifier: ^15.0.2 + version: 15.0.2 + nock: + specifier: 14.0.0-beta.6 + version: 14.0.0-beta.6 + prettier: + specifier: ^3.0.0 + version: 3.0.0 + rollup: + specifier: ^4.12.0 + version: 4.14.3 + rollup-plugin-output-size: + specifier: ^1.3.0 + version: 1.3.0(rollup@4.14.3) + supertest: + specifier: ^7.0.0 + version: 7.0.0 + typescript: + specifier: ^5.3.3 + version: 5.3.3 + vitest: + specifier: ^1.4.0 + version: 1.4.0(@types/node@20.12.7) + packages/connectors/connector-kakao: dependencies: '@logto/connector-kit': @@ -4967,7 +5040,7 @@ packages: gensync: 1.0.0-beta.2 json5: 2.2.3 lodash: 4.17.21 - resolve: 1.22.2 + resolve: 1.22.8 semver: 5.7.2 source-map: 0.5.7 transitivePeerDependencies: @@ -5160,14 +5233,6 @@ packages: picocolors: 1.0.0 dev: true - /@babel/parser@7.20.3: - resolution: {integrity: sha512-OP/s5a94frIPXwjzEcv5S/tpQfc6XhxYUnmWpgdqMWGgYCuErA3SzozaRAMQgSZWKeTJxht9aWAkUY+0UzvOFg==} - engines: {node: '>=6.0.0'} - hasBin: true - dependencies: - '@babel/types': 7.24.0 - dev: true - /@babel/parser@7.24.0: resolution: {integrity: sha512-QuP/FxEAzMSjXygs8v4N9dvdXzEHN4W1oF3PxuWAtPo08UdM17u89RDMgjLn/mlc56iM0HlLmVkO/wgR+rDgHg==} engines: {node: '>=6.0.0'} @@ -5384,7 +5449,7 @@ packages: engines: {node: '>=6.9.0'} dependencies: '@babel/code-frame': 7.22.5 - '@babel/parser': 7.24.0 + '@babel/parser': 7.24.4 '@babel/types': 7.24.0 dev: true @@ -6244,7 +6309,7 @@ packages: engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} dependencies: '@jest/types': 29.6.3 - '@types/node': 20.11.20 + '@types/node': 20.12.7 chalk: 4.1.2 jest-message-util: 29.7.0 jest-util: 29.7.0 @@ -6256,7 +6321,7 @@ packages: engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} dependencies: '@jest/types': 29.6.3 - '@types/node': 20.11.20 + '@types/node': 20.12.7 chalk: 4.1.2 jest-message-util: 29.7.0 jest-util: 29.7.0 @@ -6277,14 +6342,14 @@ packages: '@jest/test-result': 29.7.0 '@jest/transform': 29.7.0 '@jest/types': 29.6.3 - '@types/node': 20.11.20 + '@types/node': 20.12.7 ansi-escapes: 4.3.2 chalk: 4.1.2 ci-info: 3.8.0 exit: 0.1.2 graceful-fs: 4.2.11 jest-changed-files: 29.7.0 - jest-config: 29.7.0(@types/node@20.11.20)(ts-node@10.9.2) + jest-config: 29.7.0(@types/node@20.12.7)(ts-node@10.9.2) jest-haste-map: 29.7.0 jest-message-util: 29.7.0 jest-regex-util: 29.6.3 @@ -6319,7 +6384,7 @@ packages: dependencies: '@jest/fake-timers': 29.5.0 '@jest/types': 29.6.3 - '@types/node': 20.11.20 + '@types/node': 20.12.7 jest-mock: 29.5.0 dev: true @@ -6329,7 +6394,7 @@ packages: dependencies: '@jest/fake-timers': 29.7.0 '@jest/types': 29.6.3 - '@types/node': 20.11.20 + '@types/node': 20.12.7 jest-mock: 29.7.0 dev: true @@ -6356,7 +6421,7 @@ packages: dependencies: '@jest/types': 29.6.3 '@sinonjs/fake-timers': 10.3.0 - '@types/node': 20.11.20 + '@types/node': 20.12.7 jest-message-util: 29.5.0 jest-mock: 29.5.0 jest-util: 29.5.0 @@ -6368,7 +6433,7 @@ packages: dependencies: '@jest/types': 29.6.3 '@sinonjs/fake-timers': 10.3.0 - '@types/node': 20.11.20 + '@types/node': 20.12.7 jest-message-util: 29.7.0 jest-mock: 29.7.0 jest-util: 29.7.0 @@ -6401,7 +6466,7 @@ packages: '@jest/transform': 29.7.0 '@jest/types': 29.6.3 '@jridgewell/trace-mapping': 0.3.18 - '@types/node': 20.11.20 + '@types/node': 20.12.7 chalk: 4.1.2 collect-v8-coverage: 1.0.1 exit: 0.1.2 @@ -6448,7 +6513,7 @@ packages: resolution: {integrity: sha512-MHjT95QuipcPrpLM+8JMSzFx6eHp5Bm+4XeFDJlwsvVBjmKNiIAvasGK2fxz2WbGRlnvqehFbh07MMa7n3YJnw==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} dependencies: - '@jridgewell/trace-mapping': 0.3.18 + '@jridgewell/trace-mapping': 0.3.25 callsites: 3.1.0 graceful-fs: 4.2.11 dev: true @@ -6522,7 +6587,7 @@ packages: dependencies: '@types/istanbul-lib-coverage': 2.0.4 '@types/istanbul-reports': 3.0.1 - '@types/node': 20.11.20 + '@types/node': 20.12.7 '@types/yargs': 16.0.4 chalk: 4.1.2 dev: true @@ -6534,7 +6599,7 @@ packages: '@jest/schemas': 29.0.0 '@types/istanbul-lib-coverage': 2.0.4 '@types/istanbul-reports': 3.0.1 - '@types/node': 20.11.20 + '@types/node': 20.12.7 '@types/yargs': 17.0.13 chalk: 4.1.2 dev: true @@ -6546,7 +6611,7 @@ packages: '@jest/schemas': 29.4.3 '@types/istanbul-lib-coverage': 2.0.4 '@types/istanbul-reports': 3.0.1 - '@types/node': 20.11.20 + '@types/node': 20.12.7 '@types/yargs': 17.0.13 chalk: 4.1.2 dev: true @@ -6558,7 +6623,7 @@ packages: '@jest/schemas': 29.6.3 '@types/istanbul-lib-coverage': 2.0.4 '@types/istanbul-reports': 3.0.1 - '@types/node': 20.11.20 + '@types/node': 20.12.7 '@types/yargs': 17.0.13 chalk: 4.1.2 dev: true @@ -7959,6 +8024,24 @@ packages: rollup: 4.12.0 dev: true + /@rollup/plugin-commonjs@25.0.7(rollup@4.14.3): + resolution: {integrity: sha512-nEvcR+LRjEjsaSsc4x3XZfCCvZIaSMenZu/OiwOKGN2UhQpAYI7ru7czFvyWbErlpoGjnSX3D5Ch5FcMA3kRWQ==} + engines: {node: '>=14.0.0'} + peerDependencies: + rollup: ^2.68.0||^3.0.0||^4.0.0 + peerDependenciesMeta: + rollup: + optional: true + dependencies: + '@rollup/pluginutils': 5.1.0(rollup@4.14.3) + commondir: 1.0.1 + estree-walker: 2.0.2 + glob: 8.1.0 + is-reference: 1.2.1 + magic-string: 0.30.7 + rollup: 4.14.3 + dev: true + /@rollup/plugin-json@6.1.0(rollup@4.12.0): resolution: {integrity: sha512-EGI2te5ENk1coGeADSIwZ7G2Q8CJS2sF120T7jLw4xFw9n7wIOXHo+kIYRAoVpJAN+kmqZSoO3Fp4JtoNF4ReA==} engines: {node: '>=14.0.0'} @@ -7972,6 +8055,19 @@ packages: rollup: 4.12.0 dev: true + /@rollup/plugin-json@6.1.0(rollup@4.14.3): + resolution: {integrity: sha512-EGI2te5ENk1coGeADSIwZ7G2Q8CJS2sF120T7jLw4xFw9n7wIOXHo+kIYRAoVpJAN+kmqZSoO3Fp4JtoNF4ReA==} + engines: {node: '>=14.0.0'} + peerDependencies: + rollup: ^1.20.0||^2.0.0||^3.0.0||^4.0.0 + peerDependenciesMeta: + rollup: + optional: true + dependencies: + '@rollup/pluginutils': 5.1.0(rollup@4.14.3) + rollup: 4.14.3 + dev: true + /@rollup/plugin-node-resolve@15.2.3(rollup@4.12.0): resolution: {integrity: sha512-j/lym8nf5E21LwBT4Df1VD6hRO2L2iwUeUmP7litikRsVp1H6NWx20NEp0Y7su+7XGc476GnXXc4kFeZNGmaSQ==} engines: {node: '>=14.0.0'} @@ -7990,6 +8086,24 @@ packages: rollup: 4.12.0 dev: true + /@rollup/plugin-node-resolve@15.2.3(rollup@4.14.3): + resolution: {integrity: sha512-j/lym8nf5E21LwBT4Df1VD6hRO2L2iwUeUmP7litikRsVp1H6NWx20NEp0Y7su+7XGc476GnXXc4kFeZNGmaSQ==} + engines: {node: '>=14.0.0'} + peerDependencies: + rollup: ^2.78.0||^3.0.0||^4.0.0 + peerDependenciesMeta: + rollup: + optional: true + dependencies: + '@rollup/pluginutils': 5.1.0(rollup@4.14.3) + '@types/resolve': 1.20.2 + deepmerge: 4.3.1 + is-builtin-module: 3.2.1 + is-module: 1.0.0 + resolve: 1.22.2 + rollup: 4.14.3 + dev: true + /@rollup/plugin-typescript@11.1.6(rollup@4.12.0)(typescript@5.3.3): resolution: {integrity: sha512-R92yOmIACgYdJ7dJ97p4K69I8gg6IEHt8M7dUBxN3W6nrO8uUxX5ixl0yU/N3aZTi8WhPuICvOHXQvF6FaykAA==} engines: {node: '>=14.0.0'} @@ -8004,11 +8118,30 @@ packages: optional: true dependencies: '@rollup/pluginutils': 5.1.0(rollup@4.12.0) - resolve: 1.22.2 + resolve: 1.22.8 rollup: 4.12.0 typescript: 5.3.3 dev: true + /@rollup/plugin-typescript@11.1.6(rollup@4.14.3)(typescript@5.3.3): + resolution: {integrity: sha512-R92yOmIACgYdJ7dJ97p4K69I8gg6IEHt8M7dUBxN3W6nrO8uUxX5ixl0yU/N3aZTi8WhPuICvOHXQvF6FaykAA==} + engines: {node: '>=14.0.0'} + peerDependencies: + rollup: ^2.14.0||^3.0.0||^4.0.0 + tslib: '*' + typescript: '>=3.7.0' + peerDependenciesMeta: + rollup: + optional: true + tslib: + optional: true + dependencies: + '@rollup/pluginutils': 5.1.0(rollup@4.14.3) + resolve: 1.22.8 + rollup: 4.14.3 + typescript: 5.3.3 + dev: true + /@rollup/pluginutils@5.1.0(rollup@4.12.0): resolution: {integrity: sha512-XTIWOPPcpvyKI6L1NHo0lFlCyznUEyPmPY1mc3KpPVDYulHSTvyeLNVW00QTLIAFNhR3kYnJTQHeGqU4M3n09g==} engines: {node: '>=14.0.0'} @@ -8024,6 +8157,21 @@ packages: rollup: 4.12.0 dev: true + /@rollup/pluginutils@5.1.0(rollup@4.14.3): + resolution: {integrity: sha512-XTIWOPPcpvyKI6L1NHo0lFlCyznUEyPmPY1mc3KpPVDYulHSTvyeLNVW00QTLIAFNhR3kYnJTQHeGqU4M3n09g==} + engines: {node: '>=14.0.0'} + peerDependencies: + rollup: ^1.20.0||^2.0.0||^3.0.0||^4.0.0 + peerDependenciesMeta: + rollup: + optional: true + dependencies: + '@types/estree': 1.0.5 + estree-walker: 2.0.2 + picomatch: 2.3.1 + rollup: 4.14.3 + dev: true + /@rollup/rollup-android-arm-eabi@4.12.0: resolution: {integrity: sha512-+ac02NL/2TCKRrJu2wffk1kZ+RyqxVUlbjSagNgPm94frxtr+XDL12E5Ll1enWskLrtrZ2r8L3wED1orIibV/w==} cpu: [arm] @@ -9293,7 +9441,7 @@ packages: /@types/accepts@1.3.5: resolution: {integrity: sha512-jOdnI/3qTpHABjM5cx1Hc0sKsPoYCp+DP/GJRGtDlPd7fiV9oXGGIcjW/ZOxLIvjGz8MA+uMZI9metHlgqbgwQ==} dependencies: - '@types/node': 20.11.20 + '@types/node': 20.12.7 /@types/aria-query@5.0.1: resolution: {integrity: sha512-XTIieEY+gvJ39ChLcB4If5zHtPxt3Syj5rgZR+e1ctpmK8NjPf0zFqsz4JpLJT0xla9GFDKjy8Cpu331nrmE1Q==} @@ -9302,8 +9450,8 @@ packages: /@types/babel__core@7.1.19: resolution: {integrity: sha512-WEOTgRsbYkvA/KCsDwVEGkd7WAr1e3g31VHQ8zy5gul/V1qKullU/BU5I68X5v7V3GnB9eotmom4v5a5gjxorw==} dependencies: - '@babel/parser': 7.20.3 - '@babel/types': 7.20.2 + '@babel/parser': 7.24.4 + '@babel/types': 7.24.0 '@types/babel__generator': 7.6.4 '@types/babel__template': 7.4.1 '@types/babel__traverse': 7.18.2 @@ -9312,27 +9460,27 @@ packages: /@types/babel__generator@7.6.4: resolution: {integrity: sha512-tFkciB9j2K755yrTALxD44McOrk+gfpIpvC3sxHjRawj6PfnQxrse4Clq5y/Rq+G3mrBurMax/lG8Qn2t9mSsg==} dependencies: - '@babel/types': 7.20.2 + '@babel/types': 7.24.0 dev: true /@types/babel__template@7.4.1: resolution: {integrity: sha512-azBFKemX6kMg5Io+/rdGT0dkGreboUVR0Cdm3fz9QJWpaQGJRQXl7C+6hOTCZcMll7KFyEQpgbYI2lHdsS4U7g==} dependencies: - '@babel/parser': 7.20.3 - '@babel/types': 7.20.2 + '@babel/parser': 7.24.4 + '@babel/types': 7.24.0 dev: true /@types/babel__traverse@7.18.2: resolution: {integrity: sha512-FcFaxOr2V5KZCviw1TnutEMVUVsGt4D2hP1TAfXZAMKuHYW3xQhe3jTxNPWutgCJ3/X1c5yX8ZoGVEItxKbwBg==} dependencies: - '@babel/types': 7.20.2 + '@babel/types': 7.24.0 dev: true /@types/body-parser@1.19.2: resolution: {integrity: sha512-ALYone6pm6QmwZoAgeyNksccT9Q4AWZQ6PvfwR37GT6r6FWUPguq6sUmNGSMV2Wr761oQoBxwGGa6DR5o1DC9g==} dependencies: '@types/connect': 3.4.35 - '@types/node': 20.11.20 + '@types/node': 20.12.7 /@types/caseless@0.12.5: resolution: {integrity: sha512-hWtVTC2q7hc7xZ/RLbxapMvDMgUnDvKvMOpKal4DrMyfGBUfB1oKaZlIRr6mJL+If3bAP6sV/QneGzF6tJjZDg==} @@ -9364,7 +9512,7 @@ packages: /@types/connect@3.4.35: resolution: {integrity: sha512-cdeYyv4KWoEgpBISTxWvqYsVy444DOqehiF3fM3ne10AmJ62RSyNkUnxMJXHQWRQQX2eR94m5y1IZyDwBjV9FQ==} dependencies: - '@types/node': 20.11.20 + '@types/node': 20.12.7 /@types/content-disposition@0.5.4: resolution: {integrity: sha512-0mPF08jn9zYI0n0Q/Pnz7C4kThdSt+6LD4amsrYDDpgBfrVWa3TcCOxKX1zkGgYniGagRv8heN2cbh+CAn+uuQ==} @@ -9372,7 +9520,7 @@ packages: /@types/conventional-commits-parser@5.0.0: resolution: {integrity: sha512-loB369iXNmAZglwWATL+WRe+CRMmmBPtpolYzIebFaX4YA3x+BEfLqhUAV9WanycKI3TG1IMr5bMJDajDKLlUQ==} dependencies: - '@types/node': 20.11.20 + '@types/node': 20.12.7 dev: true /@types/cookiejar@2.1.5: @@ -9385,7 +9533,7 @@ packages: '@types/connect': 3.4.35 '@types/express': 4.17.13 '@types/keygrip': 1.0.2 - '@types/node': 20.11.20 + '@types/node': 20.12.7 /@types/debug@4.1.7: resolution: {integrity: sha512-9AonUzyTjXXhEOa0DnqpzZi6VHlqKMswga9EXjpXnnqxwLtdvPPtlO8evrI5D9S6asFRCQ6v+wpiUKbw+vKqyg==} @@ -9400,13 +9548,13 @@ packages: /@types/etag@1.8.1: resolution: {integrity: sha512-bsKkeSqN7HYyYntFRAmzcwx/dKW4Wa+KVMTInANlI72PWLQmOpZu96j0OqHZGArW4VQwCmJPteQlXaUDeOB0WQ==} dependencies: - '@types/node': 20.11.20 + '@types/node': 20.12.7 dev: true /@types/express-serve-static-core@4.17.26: resolution: {integrity: sha512-zeu3tpouA043RHxW0gzRxwCHchMgftE8GArRsvYT0ByDMbn19olQHx5jLue0LxWY6iYtXb7rXmuVtSkhy9YZvQ==} dependencies: - '@types/node': 20.11.20 + '@types/node': 20.12.7 '@types/qs': 6.9.7 '@types/range-parser': 1.2.4 @@ -9495,7 +9643,7 @@ packages: /@types/jsdom@20.0.0: resolution: {integrity: sha512-YfAchFs0yM1QPDrLm2VHe+WHGtqms3NXnXAMolrgrVP6fgBHHXy1ozAbo/dFtPNtZC/m66bPiCTWYmqp1F14gA==} dependencies: - '@types/node': 20.11.20 + '@types/node': 20.12.7 '@types/tough-cookie': 4.0.2 parse5: 7.1.1 dev: true @@ -9520,7 +9668,7 @@ packages: resolution: {integrity: sha512-nJSII/tOSvYCwk3yDEBJLHd8ctkt5CQFZ0j8ZBnHZ2x0hg24z9H1i38lWXA/5z0Ix0uitMW1jov+kVbQI1aNPQ==} dependencies: '@types/koa': 2.13.4 - '@types/node': 20.11.20 + '@types/node': 20.12.7 dev: true /@types/koa-logger@3.1.2: @@ -9551,7 +9699,7 @@ packages: '@types/http-errors': 1.8.2 '@types/keygrip': 1.0.2 '@types/koa-compose': 3.2.5 - '@types/node': 20.11.20 + '@types/node': 20.12.7 /@types/koa@2.15.0: resolution: {integrity: sha512-7QFsywoE5URbuVnG3loe03QXuGajrnotr3gQkXcEBShORai23MePfFYdhz90FEtBBpkyIYQbVD+evKtloCgX3g==} @@ -9630,6 +9778,7 @@ packages: resolution: {integrity: sha512-7/rR21OS+fq8IyHTgtLkDK949uzsa6n8BkziAKtPVpugIkO6D+/ooXMvzXxDnZrmtXVfjb1bKQafYpb8s89LOg==} dependencies: undici-types: 5.26.5 + dev: true /@types/node@20.12.7: resolution: {integrity: sha512-wq0cICSkRLVaf3UGLMGItu/PtdY7oaXaI/RVU+xliKVOtRna3PRY57ZDfztpDL0n11vfymMUnXv8QwYCO7L1wg==} @@ -9639,7 +9788,7 @@ packages: /@types/nodemailer@6.4.7: resolution: {integrity: sha512-f5qCBGAn/f0qtRcd4SEn88c8Fp3Swct1731X4ryPKqS61/A3LmmzN8zaEz7hneJvpjFbUUgY7lru/B/7ODTazg==} dependencies: - '@types/node': 20.11.20 + '@types/node': 20.12.7 dev: true /@types/normalize-package-data@2.4.1: @@ -9664,14 +9813,14 @@ packages: /@types/pg@8.11.2: resolution: {integrity: sha512-G2Mjygf2jFMU/9hCaTYxJrwdObdcnuQde1gndooZSOHsNSaCehAuwc7EIuSA34Do8Jx2yZ19KtvW8P0j4EuUXw==} dependencies: - '@types/node': 20.11.20 + '@types/node': 20.12.7 pg-protocol: 1.6.0 pg-types: 4.0.2 /@types/pg@8.6.6: resolution: {integrity: sha512-O2xNmXebtwVekJDD+02udOncjVcMZQuTEQEMpKJ0ZRf5E7/9JJX3izhKUcUifBkyKpljyUM6BTgy2trmviKlpw==} dependencies: - '@types/node': 20.11.20 + '@types/node': 20.12.7 pg-protocol: 1.6.0 pg-types: 2.2.0 dev: true @@ -9687,7 +9836,7 @@ packages: /@types/qrcode@1.5.2: resolution: {integrity: sha512-W4KDz75m7rJjFbyCctzCtRzZUj+PrUHV+YjqDp50sSRezTbrtEAIq2iTzC6lISARl3qw+8IlcCyljdcVJE0Wug==} dependencies: - '@types/node': 20.11.20 + '@types/node': 20.12.7 dev: true /@types/qs@6.9.7: @@ -9793,7 +9942,7 @@ packages: resolution: {integrity: sha512-nCkHGI4w7ZgAdNkrEu0bv+4xNV/XDqW+DydknebMOQwkpDGx8G+HTlj7R7ABI8i8nKxVw0wtKPi1D+lPOkh4YQ==} dependencies: '@types/mime': 1.3.2 - '@types/node': 20.11.20 + '@types/node': 20.12.7 /@types/shimmer@1.0.2: resolution: {integrity: sha512-dKkr1bTxbEsFlh2ARpKzcaAmsYixqt9UyCdoEZk8rHyE4iQYcDCyvSjDSf7JUWJHlJiTtbIoQjxKh6ViywqDAg==} @@ -9838,7 +9987,7 @@ packages: /@types/through@0.0.30: resolution: {integrity: sha512-FvnCJljyxhPM3gkRgWmxmDZyAQSiBQQWLI0A0VFL0K7W1oRUrPJSqNO0NvTnLkBcotdlp3lKvaT0JrnyRDkzOg==} dependencies: - '@types/node': 20.11.20 + '@types/node': 20.12.7 dev: true /@types/tough-cookie@4.0.2: @@ -10037,7 +10186,7 @@ packages: strip-literal: 2.0.0 test-exclude: 6.0.0 v8-to-istanbul: 9.2.0 - vitest: 1.4.0(@types/node@20.10.4) + vitest: 1.4.0(@types/node@20.12.7) transitivePeerDependencies: - supports-color dev: true @@ -10645,7 +10794,7 @@ packages: engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} dependencies: '@babel/template': 7.18.10 - '@babel/types': 7.20.2 + '@babel/types': 7.24.0 '@types/babel__core': 7.1.19 '@types/babel__traverse': 7.18.2 dev: true @@ -11781,6 +11930,17 @@ packages: /dayjs@1.11.6: resolution: {integrity: sha512-zZbY5giJAinCG+7AGaw0wIhNZ6J8AhWuSXKvuc1KAyMiRsvGQWqh4L+MomvhdAYjN+lqvVCMq1I41e3YHvXkyQ==} + /debug@3.2.7: + resolution: {integrity: sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==} + peerDependencies: + supports-color: '*' + peerDependenciesMeta: + supports-color: + optional: true + dependencies: + ms: 2.1.3 + dev: true + /debug@3.2.7(supports-color@5.5.0): resolution: {integrity: sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==} peerDependencies: @@ -12545,7 +12705,7 @@ packages: /eslint-import-resolver-node@0.3.9: resolution: {integrity: sha512-WFj2isz22JahUv+B788TlO3N6zL3nNJGU8CcZbPZvVEkBPaJdCV4vy5wyghty5ROFbCRnm132v8BScu5/1BQ8g==} dependencies: - debug: 3.2.7(supports-color@5.5.0) + debug: 3.2.7 is-core-module: 2.13.1 resolve: 1.22.8 transitivePeerDependencies: @@ -12597,7 +12757,7 @@ packages: optional: true dependencies: '@typescript-eslint/parser': 7.7.0(eslint@8.57.0)(typescript@5.3.3) - debug: 3.2.7(supports-color@5.5.0) + debug: 3.2.7 eslint: 8.57.0 eslint-import-resolver-node: 0.3.9 eslint-import-resolver-typescript: 3.6.1(@typescript-eslint/parser@7.7.0)(eslint-plugin-import@2.29.1)(eslint@8.57.0) @@ -12651,7 +12811,7 @@ packages: array.prototype.findlastindex: 1.2.5 array.prototype.flat: 1.3.2 array.prototype.flatmap: 1.3.2 - debug: 3.2.7(supports-color@5.5.0) + debug: 3.2.7 doctrine: 2.1.0 eslint: 8.57.0 eslint-import-resolver-node: 0.3.9 @@ -13420,6 +13580,7 @@ packages: /function-bind@1.1.1: resolution: {integrity: sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==} + dev: true /function-bind@1.1.2: resolution: {integrity: sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==} @@ -13882,6 +14043,7 @@ packages: engines: {node: '>= 0.4.0'} dependencies: function-bind: 1.1.1 + dev: true /hash-wasm@4.9.0: resolution: {integrity: sha512-7SW7ejyfnRxuOc7ptQHSf4LDoZaWOivfzqw+5rpcQku0nHfmicPKE51ra9BiRLAmT8+gGLestr1XroUkqdjL6w==} @@ -14517,12 +14679,12 @@ packages: resolution: {integrity: sha512-Q4ZuBAe2FUsKtyQJoQHlvP8OvBERxO3jEmy1I7hcRXcJBGGHFh/aJBswbXuS9sgrDH2QUO8ilkwNPHvHMd8clg==} dependencies: has: 1.0.3 + dev: true /is-core-module@2.13.1: resolution: {integrity: sha512-hHrIjvZsftOsvKSn2TRYl63zvxsgE0K+0mYMoH6gD4omR5IWB2KynivBQczo3+wF1cCkjzvptnI9Q0sPU66ilw==} dependencies: hasown: 2.0.2 - dev: true /is-data-view@1.0.1: resolution: {integrity: sha512-AHkaJrsUVW6wq6JS8y3JnM/GJF/9cf+k20+iDzlSaJrinEo5+7vRiteOSwBhHRiAyQATN1AmY4hwzxJKPmYf+w==} @@ -14831,7 +14993,7 @@ packages: engines: {node: '>=8'} dependencies: '@babel/core': 7.24.4 - '@babel/parser': 7.24.0 + '@babel/parser': 7.24.4 '@istanbuljs/schema': 0.1.3 istanbul-lib-coverage: 3.2.2 semver: 6.3.1 @@ -14844,7 +15006,7 @@ packages: engines: {node: '>=10'} dependencies: '@babel/core': 7.24.4 - '@babel/parser': 7.24.0 + '@babel/parser': 7.24.4 '@istanbuljs/schema': 0.1.3 istanbul-lib-coverage: 3.2.2 semver: 7.6.0 @@ -14927,7 +15089,7 @@ packages: '@jest/expect': 29.7.0 '@jest/test-result': 29.7.0 '@jest/types': 29.6.3 - '@types/node': 20.11.20 + '@types/node': 20.12.7 chalk: 4.1.2 co: 4.6.0 dedent: 1.5.1 @@ -15072,47 +15234,6 @@ packages: - supports-color dev: true - /jest-config@29.7.0(@types/node@20.11.20)(ts-node@10.9.2): - resolution: {integrity: sha512-uXbpfeQ7R6TZBqI3/TxCU4q4ttk3u0PJeC+E0zbfSoSjq6bJ7buBPxzQPL0ifrkY4DNu4JUdk0ImlBUYi840eQ==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - peerDependencies: - '@types/node': '*' - ts-node: '>=9.0.0' - peerDependenciesMeta: - '@types/node': - optional: true - ts-node: - optional: true - dependencies: - '@babel/core': 7.24.4 - '@jest/test-sequencer': 29.7.0 - '@jest/types': 29.6.3 - '@types/node': 20.11.20 - babel-jest: 29.7.0(@babel/core@7.24.4) - chalk: 4.1.2 - ci-info: 3.8.0 - deepmerge: 4.3.1 - glob: 7.2.3 - graceful-fs: 4.2.11 - jest-circus: 29.7.0 - jest-environment-node: 29.7.0 - jest-get-type: 29.6.3 - jest-regex-util: 29.6.3 - jest-resolve: 29.7.0 - jest-runner: 29.7.0 - jest-util: 29.7.0 - jest-validate: 29.7.0 - micromatch: 4.0.5 - parse-json: 5.2.0 - pretty-format: 29.7.0 - slash: 3.0.0 - strip-json-comments: 3.1.1 - ts-node: 10.9.2(@swc/core@1.3.52)(@types/node@20.12.7)(typescript@5.3.3) - transitivePeerDependencies: - - babel-plugin-macros - - supports-color - dev: true - /jest-config@29.7.0(@types/node@20.12.7)(ts-node@10.9.2): resolution: {integrity: sha512-uXbpfeQ7R6TZBqI3/TxCU4q4ttk3u0PJeC+E0zbfSoSjq6bJ7buBPxzQPL0ifrkY4DNu4JUdk0ImlBUYi840eQ==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} @@ -15211,7 +15332,7 @@ packages: '@jest/fake-timers': 29.5.0 '@jest/types': 29.6.3 '@types/jsdom': 20.0.0 - '@types/node': 20.11.20 + '@types/node': 20.12.7 jest-mock: 29.5.0 jest-util: 29.5.0 jsdom: 20.0.2 @@ -15228,7 +15349,7 @@ packages: '@jest/environment': 29.7.0 '@jest/fake-timers': 29.7.0 '@jest/types': 29.6.3 - '@types/node': 20.11.20 + '@types/node': 20.12.7 jest-mock: 29.7.0 jest-util: 29.7.0 dev: true @@ -15259,7 +15380,7 @@ packages: dependencies: '@jest/types': 29.6.3 '@types/graceful-fs': 4.1.5 - '@types/node': 20.11.20 + '@types/node': 20.12.7 anymatch: 3.1.3 fb-watchman: 2.0.2 graceful-fs: 4.2.10 @@ -15278,7 +15399,7 @@ packages: dependencies: '@jest/types': 29.6.3 '@types/graceful-fs': 4.1.5 - '@types/node': 20.11.20 + '@types/node': 20.12.7 anymatch: 3.1.3 fb-watchman: 2.0.2 graceful-fs: 4.2.11 @@ -15348,7 +15469,7 @@ packages: engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} dependencies: '@jest/types': 29.6.3 - '@types/node': 20.11.20 + '@types/node': 20.12.7 jest-util: 29.5.0 dev: true @@ -15357,7 +15478,7 @@ packages: engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} dependencies: '@jest/types': 29.6.3 - '@types/node': 20.11.20 + '@types/node': 20.12.7 jest-util: 29.7.0 dev: true @@ -15418,7 +15539,7 @@ packages: jest-pnp-resolver: 1.2.2(jest-resolve@29.7.0) jest-util: 29.7.0 jest-validate: 29.7.0 - resolve: 1.22.2 + resolve: 1.22.8 resolve.exports: 2.0.1 slash: 3.0.0 dev: true @@ -15432,7 +15553,7 @@ packages: '@jest/test-result': 29.7.0 '@jest/transform': 29.7.0 '@jest/types': 29.6.3 - '@types/node': 20.11.20 + '@types/node': 20.12.7 chalk: 4.1.2 emittery: 0.13.1 graceful-fs: 4.2.11 @@ -15463,7 +15584,7 @@ packages: '@jest/test-result': 29.7.0 '@jest/transform': 29.7.0 '@jest/types': 29.6.3 - '@types/node': 20.11.20 + '@types/node': 20.12.7 chalk: 4.1.2 cjs-module-lexer: 1.2.2 collect-v8-coverage: 1.0.1 @@ -15529,7 +15650,7 @@ packages: engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} dependencies: '@jest/types': 29.6.3 - '@types/node': 20.11.20 + '@types/node': 20.12.7 chalk: 4.1.2 ci-info: 3.8.0 graceful-fs: 4.2.11 @@ -15541,7 +15662,7 @@ packages: engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} dependencies: '@jest/types': 29.6.3 - '@types/node': 20.11.20 + '@types/node': 20.12.7 chalk: 4.1.2 ci-info: 3.8.0 graceful-fs: 4.2.11 @@ -15566,7 +15687,7 @@ packages: dependencies: '@jest/test-result': 29.7.0 '@jest/types': 29.6.3 - '@types/node': 20.11.20 + '@types/node': 20.12.7 ansi-escapes: 4.3.2 chalk: 4.1.2 emittery: 0.13.1 @@ -15588,7 +15709,7 @@ packages: resolution: {integrity: sha512-eIz2msL/EzL9UFTFFx7jBTkeZfku0yUAyZZZmJ93H2TYEiroIx2PQjEXcwYtYl8zXCxb+PAmA2hLIt/6ZEkPHw==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} dependencies: - '@types/node': 20.11.20 + '@types/node': 20.12.7 jest-util: 29.7.0 merge-stream: 2.0.0 supports-color: 8.1.1 @@ -17436,7 +17557,7 @@ packages: resolution: {integrity: sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==} dependencies: hosted-git-info: 2.8.9 - resolve: 1.22.2 + resolve: 1.22.8 semver: 5.7.2 validate-npm-package-license: 3.0.4 dev: true @@ -19357,7 +19478,7 @@ packages: dependencies: debug: 4.3.4 module-details-from-path: 1.0.3 - resolve: 1.22.2 + resolve: 1.22.8 transitivePeerDependencies: - supports-color dev: false @@ -19421,6 +19542,7 @@ packages: is-core-module: 2.12.1 path-parse: 1.0.7 supports-preserve-symlinks-flag: 1.0.0 + dev: true /resolve@1.22.8: resolution: {integrity: sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw==} @@ -19429,7 +19551,6 @@ packages: is-core-module: 2.13.1 path-parse: 1.0.7 supports-preserve-symlinks-flag: 1.0.0 - dev: true /resolve@2.0.0-next.5: resolution: {integrity: sha512-U7WjGVG9sH8tvjW5SmGbQuui75FiyjAX72HX15DwBBwF9dNiQZRQAg9nnPhYy+TUnE0+VcrttuvNI8oSxZcocA==} @@ -19528,6 +19649,21 @@ packages: rollup: 4.12.0 dev: true + /rollup-plugin-output-size@1.3.0(rollup@4.14.3): + resolution: {integrity: sha512-OrTfhj8mxFAO4Yp7OEWwI388uhsiBNDCpfD6tOmcqPfNs5+CWZPDtVmTRZrmXMWfv8skWCOm5ToO4UPy7eRqYg==} + engines: {node: '>=14.16.0'} + peerDependencies: + rollup: ^2.0.0 || ^3.0.0 || ^4.0.0 + peerDependenciesMeta: + rollup: + optional: true + dependencies: + colorette: 2.0.20 + gzip-size: 7.0.0 + pretty-bytes: 6.1.1 + rollup: 4.14.3 + dev: true + /rollup@4.12.0: resolution: {integrity: sha512-wz66wn4t1OHIJw3+XU7mJJQV/2NAfw5OAk6G6Hoo3zcvz/XOfQ52Vgi+AN4Uxoxi0KBBwk2g8zPrTDA4btSB/Q==} engines: {node: '>=18.0.0', npm: '>=8.0.0'} @@ -21258,6 +21394,27 @@ packages: - terser dev: true + /vite-node@1.4.0(@types/node@20.12.7): + 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.2.9(@types/node@20.12.7) + transitivePeerDependencies: + - '@types/node' + - less + - lightningcss + - sass + - stylus + - sugarss + - supports-color + - terser + dev: true + /vite@5.2.9(@types/node@20.10.4): resolution: {integrity: sha512-uOQWfuZBlc6Y3W/DTuQ1Sr+oIXWvqljLvS881SVmAj00d5RdgShLcuXWxseWPd4HXwiYBFW/vXHfKFeqj9uQnw==} engines: {node: ^18.0.0 || >=20.0.0} @@ -21330,6 +21487,42 @@ packages: fsevents: 2.3.3 dev: true + /vite@5.2.9(@types/node@20.12.7): + resolution: {integrity: sha512-uOQWfuZBlc6Y3W/DTuQ1Sr+oIXWvqljLvS881SVmAj00d5RdgShLcuXWxseWPd4HXwiYBFW/vXHfKFeqj9uQnw==} + 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.12.7 + esbuild: 0.20.2 + postcss: 8.4.38 + rollup: 4.14.3 + optionalDependencies: + fsevents: 2.3.3 + dev: true + /vitest@1.4.0(@types/node@20.10.4): resolution: {integrity: sha512-gujzn0g7fmwf83/WzrDTnncZt2UiXP41mHuFYFrdwaLRVQ6JYQEiME2IfEjU3vcFL3VKa75XhI3lFgn+hfVsQw==} engines: {node: ^18.0.0 || >=20.0.0} @@ -21442,6 +21635,62 @@ packages: - terser dev: true + /vitest@1.4.0(@types/node@20.12.7): + 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.12.7 + '@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.2.9(@types/node@20.12.7) + vite-node: 1.4.0(@types/node@20.12.7) + why-is-node-running: 2.2.2 + transitivePeerDependencies: + - less + - lightningcss + - sass + - stylus + - sugarss + - supports-color + - terser + dev: true + /void-elements@3.1.0: resolution: {integrity: sha1-YU9/v42AHwu18GYfWy9XhXUOTwk=} engines: {node: '>=0.10.0'} From b4b8015db583d4c8ccbd42bbc39b47ed97e7886d Mon Sep 17 00:00:00 2001 From: Charles Zhao Date: Mon, 6 May 2024 10:21:45 +0800 Subject: [PATCH 343/687] fix(core): invitee email check should be case insensitive (#5823) * fix(core): invitee email check should be case insensitive * chore: add changeset --- .changeset/popular-chicken-share.md | 5 +++++ packages/core/src/libraries/organization-invitation.ts | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) create mode 100644 .changeset/popular-chicken-share.md diff --git a/.changeset/popular-chicken-share.md b/.changeset/popular-chicken-share.md new file mode 100644 index 00000000000..0a8968351be --- /dev/null +++ b/.changeset/popular-chicken-share.md @@ -0,0 +1,5 @@ +--- +"@logto/core": patch +--- + +fix a bug that prevents invitee from accepting the organization invitation if the email letter case is not matching diff --git a/packages/core/src/libraries/organization-invitation.ts b/packages/core/src/libraries/organization-invitation.ts index 17859be08bd..a89a8717f58 100644 --- a/packages/core/src/libraries/organization-invitation.ts +++ b/packages/core/src/libraries/organization-invitation.ts @@ -157,7 +157,7 @@ export class OrganizationInvitationLibrary { const user = await userQueries.findUserById(acceptedUserId); - if (user.primaryEmail !== entity.invitee) { + if (user.primaryEmail?.toLowerCase() !== entity.invitee.toLowerCase()) { throw new RequestError({ status: 422, code: 'request.invalid_input', From c1c8410093e104577456145d7a762011b034d0a8 Mon Sep 17 00:00:00 2001 From: Xiao Yijun Date: Mon, 6 May 2024 12:03:38 +0800 Subject: [PATCH 344/687] fix(console): hide org resource scopes tab from 3rd-party app modal (#5824) --- .../index.tsx | 35 +++++++++++-------- 1 file changed, 21 insertions(+), 14 deletions(-) diff --git a/packages/console/src/pages/ApplicationDetails/ApplicationDetailsContent/Permissions/ApplicationScopesAssignmentModal/index.tsx b/packages/console/src/pages/ApplicationDetails/ApplicationDetailsContent/Permissions/ApplicationScopesAssignmentModal/index.tsx index 98da0310b73..4e87abfda18 100644 --- a/packages/console/src/pages/ApplicationDetails/ApplicationDetailsContent/Permissions/ApplicationScopesAssignmentModal/index.tsx +++ b/packages/console/src/pages/ApplicationDetails/ApplicationDetailsContent/Permissions/ApplicationScopesAssignmentModal/index.tsx @@ -47,21 +47,28 @@ function ApplicationScopesAssignmentModal({ isOpen, onClose, applicationId }: Pr const tabs = useMemo( () => - Object.values(permissionTabs).map(({ title, key }) => { - const selectedDataCount = scopesAssignment[key].selectedData.length; + Object.values(permissionTabs) + /** + * Hide the organization resource scopes tab since the feature is not ready. + * We don't need the `isDevFeaturesEnabled` flag since the feature will change the UI. + * Todo @xiaoyijun Implement the new organization resource scopes feature. LOG-8823 + */ + .filter(({ key }) => key !== ApplicationUserConsentScopeType.OrganizationResourceScopes) + .map(({ title, key }) => { + const selectedDataCount = scopesAssignment[key].selectedData.length; - return ( - { - setActiveTab(key); - }} - > - {`${t(title)}${selectedDataCount ? ` (${selectedDataCount})` : ''}`} - - ); - }), + return ( + { + setActiveTab(key); + }} + > + {`${t(title)}${selectedDataCount ? ` (${selectedDataCount})` : ''}`} + + ); + }), [activeTab, scopesAssignment, setActiveTab, t] ); From 95682f72a116cd561ccc46e03f7ad2669263152f Mon Sep 17 00:00:00 2001 From: Gao Sun Date: Mon, 6 May 2024 17:06:37 +0800 Subject: [PATCH 345/687] chore(deps): upgrade withtyped packages (#5827) --- packages/cli/package.json | 2 +- packages/console/package.json | 2 +- packages/core/package.json | 2 +- packages/schemas/package.json | 2 +- packages/toolkit/connector-kit/package.json | 4 +- pnpm-lock.yaml | 61 ++++++++++----------- 6 files changed, 34 insertions(+), 39 deletions(-) diff --git a/packages/cli/package.json b/packages/cli/package.json index 2e09797e275..d81a2593a2f 100644 --- a/packages/cli/package.json +++ b/packages/cli/package.json @@ -80,7 +80,7 @@ "@types/tar": "^6.1.12", "@types/yargs": "^17.0.13", "@vitest/coverage-v8": "^1.4.0", - "@withtyped/server": "^0.13.3", + "@withtyped/server": "^0.13.5", "eslint": "^8.56.0", "lint-staged": "^15.0.0", "prettier": "^3.0.0", diff --git a/packages/console/package.json b/packages/console/package.json index 9f775e904cf..f64baa4237b 100644 --- a/packages/console/package.json +++ b/packages/console/package.json @@ -63,7 +63,7 @@ "@types/react-helmet": "^6.1.6", "@types/react-modal": "^3.13.1", "@types/react-syntax-highlighter": "^15.5.1", - "@withtyped/client": "^0.8.4", + "@withtyped/client": "^0.8.6", "buffer": "^5.7.1", "classnames": "^2.3.1", "clean-deep": "^3.4.0", diff --git a/packages/core/package.json b/packages/core/package.json index 96d9968a9fa..03ffb3fddeb 100644 --- a/packages/core/package.json +++ b/packages/core/package.json @@ -46,7 +46,7 @@ "@silverhand/essentials": "^2.9.0", "@silverhand/slonik": "31.0.0-beta.2", "@simplewebauthn/server": "^9.0.0", - "@withtyped/client": "^0.8.4", + "@withtyped/client": "^0.8.6", "camelcase": "^8.0.0", "camelcase-keys": "^9.0.0", "chalk": "^5.0.0", diff --git a/packages/schemas/package.json b/packages/schemas/package.json index 3014a544b1f..718d5d81bbb 100644 --- a/packages/schemas/package.json +++ b/packages/schemas/package.json @@ -84,7 +84,7 @@ "@logto/phrases": "workspace:^1.10.0", "@logto/phrases-experience": "workspace:^1.6.1", "@logto/shared": "workspace:^3.1.0", - "@withtyped/server": "^0.13.3" + "@withtyped/server": "^0.13.5" }, "peerDependencies": { "zod": "^3.22.4" diff --git a/packages/toolkit/connector-kit/package.json b/packages/toolkit/connector-kit/package.json index cd88cf095b7..eb359ff280c 100644 --- a/packages/toolkit/connector-kit/package.json +++ b/packages/toolkit/connector-kit/package.json @@ -36,8 +36,8 @@ "dependencies": { "@logto/language-kit": "workspace:^1.1.0", "@silverhand/essentials": "^2.9.0", - "@withtyped/client": "^0.8.4", - "@withtyped/server": "^0.13.3" + "@withtyped/client": "^0.8.6", + "@withtyped/server": "^0.13.5" }, "optionalDependencies": { "zod": "^3.22.4" diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 206291d5b4c..395e6b64555 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -192,8 +192,8 @@ importers: specifier: ^1.4.0 version: 1.4.0(vitest@1.4.0) '@withtyped/server': - specifier: ^0.13.3 - version: 0.13.3(zod@3.22.4) + specifier: ^0.13.5 + version: 0.13.5(zod@3.22.4) eslint: specifier: ^8.56.0 version: 8.57.0 @@ -2881,8 +2881,8 @@ importers: specifier: ^15.5.1 version: 15.5.1 '@withtyped/client': - specifier: ^0.8.4 - version: 0.8.4(zod@3.22.4) + specifier: ^0.8.6 + version: 0.8.6(zod@3.22.4) buffer: specifier: ^5.7.1 version: 5.7.1 @@ -3136,8 +3136,8 @@ importers: specifier: ^9.0.0 version: 9.0.1 '@withtyped/client': - specifier: ^0.8.4 - version: 0.8.4(zod@3.22.4) + specifier: ^0.8.6 + version: 0.8.6(zod@3.22.4) camelcase: specifier: ^8.0.0 version: 8.0.0 @@ -3854,8 +3854,8 @@ importers: specifier: workspace:^3.1.0 version: link:../shared '@withtyped/server': - specifier: ^0.13.3 - version: 0.13.3(zod@3.22.4) + specifier: ^0.13.5 + version: 0.13.5(zod@3.22.4) zod: specifier: ^3.22.4 version: 3.22.4 @@ -3970,11 +3970,11 @@ importers: specifier: ^2.9.0 version: 2.9.0 '@withtyped/client': - specifier: ^0.8.4 - version: 0.8.4(zod@3.22.4) + specifier: ^0.8.6 + version: 0.8.6(zod@3.22.4) '@withtyped/server': - specifier: ^0.13.3 - version: 0.13.3(zod@3.22.4) + specifier: ^0.13.5 + version: 0.13.5(zod@3.22.4) optionalDependencies: zod: specifier: ^3.22.4 @@ -6788,7 +6788,7 @@ packages: engines: {node: ^20.9.0} dependencies: '@silverhand/essentials': 2.9.0 - '@withtyped/server': 0.13.3(zod@3.22.4) + '@withtyped/server': 0.13.5(zod@3.22.4) transitivePeerDependencies: - zod dev: true @@ -10186,7 +10186,7 @@ packages: strip-literal: 2.0.0 test-exclude: 6.0.0 v8-to-istanbul: 9.2.0 - vitest: 1.4.0(@types/node@20.12.7) + vitest: 1.4.0(@types/node@20.10.4) transitivePeerDependencies: - supports-color dev: true @@ -10230,21 +10230,22 @@ packages: pretty-format: 29.7.0 dev: true - /@withtyped/client@0.8.4(zod@3.22.4): - resolution: {integrity: sha512-oX19xZRjUASZLWUzQW4LKhLsDgtwFfWU7mgReKiY/tddwvHLoakLqz1o1MvRDuz+EOoYrQM+VpkwJeMsnbNT1w==} + /@withtyped/client@0.8.6(zod@3.22.4): + resolution: {integrity: sha512-LJXMHBEJ4VkRMGHF08WDowJRQttrS2QII+6QCcQp4m9M88qJS/2Kvfii1H6u2N4yWNZqHKs3zWVEDRCPV4VLGg==} dependencies: - '@withtyped/server': 0.13.3(zod@3.22.4) + '@withtyped/server': 0.13.5(zod@3.22.4) '@withtyped/shared': 0.2.2 transitivePeerDependencies: - zod - /@withtyped/server@0.13.3(zod@3.22.4): - resolution: {integrity: sha512-MPyjRPQd5JySDnMnXPxGXXnw7AACAl8TLhWPjm4sdBgVMssSrmBbjRxBep0jY64PJ3xzICZh0ArWTRdXyNFIog==} + /@withtyped/server@0.13.5(zod@3.22.4): + resolution: {integrity: sha512-Q5lr6f4G+vjV4q0vBbpEvPUhKOIjAbRqRDXCSHC2nblgB9637njQPvRV8ulXHQWNk5PAMknkgFRJsZWVuHBhAg==} peerDependencies: zod: ^3.19.1 dependencies: '@silverhand/essentials': 2.9.0 '@withtyped/shared': 0.2.2 + nanoid: 4.0.2 zod: 3.22.4 /@withtyped/shared@0.2.2: @@ -11930,17 +11931,6 @@ packages: /dayjs@1.11.6: resolution: {integrity: sha512-zZbY5giJAinCG+7AGaw0wIhNZ6J8AhWuSXKvuc1KAyMiRsvGQWqh4L+MomvhdAYjN+lqvVCMq1I41e3YHvXkyQ==} - /debug@3.2.7: - resolution: {integrity: sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==} - peerDependencies: - supports-color: '*' - peerDependenciesMeta: - supports-color: - optional: true - dependencies: - ms: 2.1.3 - dev: true - /debug@3.2.7(supports-color@5.5.0): resolution: {integrity: sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==} peerDependencies: @@ -12705,7 +12695,7 @@ packages: /eslint-import-resolver-node@0.3.9: resolution: {integrity: sha512-WFj2isz22JahUv+B788TlO3N6zL3nNJGU8CcZbPZvVEkBPaJdCV4vy5wyghty5ROFbCRnm132v8BScu5/1BQ8g==} dependencies: - debug: 3.2.7 + debug: 3.2.7(supports-color@5.5.0) is-core-module: 2.13.1 resolve: 1.22.8 transitivePeerDependencies: @@ -12757,7 +12747,7 @@ packages: optional: true dependencies: '@typescript-eslint/parser': 7.7.0(eslint@8.57.0)(typescript@5.3.3) - debug: 3.2.7 + debug: 3.2.7(supports-color@5.5.0) eslint: 8.57.0 eslint-import-resolver-node: 0.3.9 eslint-import-resolver-typescript: 3.6.1(@typescript-eslint/parser@7.7.0)(eslint-plugin-import@2.29.1)(eslint@8.57.0) @@ -12811,7 +12801,7 @@ packages: array.prototype.findlastindex: 1.2.5 array.prototype.flat: 1.3.2 array.prototype.flatmap: 1.3.2 - debug: 3.2.7 + debug: 3.2.7(supports-color@5.5.0) doctrine: 2.1.0 eslint: 8.57.0 eslint-import-resolver-node: 0.3.9 @@ -17357,6 +17347,11 @@ packages: hasBin: true dev: true + /nanoid@4.0.2: + resolution: {integrity: sha512-7ZtY5KTCNheRGfEFxnedV5zFiORN1+Y1N6zvPTnHQd8ENUvfaDBeuJDZb2bN/oXwXxu3qkTXDzy57W5vAmDTBw==} + engines: {node: ^14 || ^16 || >=18} + hasBin: true + /nanoid@5.0.1: resolution: {integrity: sha512-vWeVtV5Cw68aML/QaZvqN/3QQXc6fBfIieAlu05m7FZW2Dgb+3f0xc0TTxuJW+7u30t7iSDTV/j3kVI0oJqIfQ==} engines: {node: ^18 || >=20} From 4397ca29edc87d6c46e2734ef3d88a7ad3b6be9f Mon Sep 17 00:00:00 2001 From: Gao Sun Date: Mon, 6 May 2024 17:12:36 +0800 Subject: [PATCH 346/687] refactor(core): optimize init (#5826) --- packages/core/src/main.ts | 5 ++--- packages/core/src/tenants/index.ts | 2 +- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/packages/core/src/main.ts b/packages/core/src/main.ts index 3144800d6f2..3ead694a202 100644 --- a/packages/core/src/main.ts +++ b/packages/core/src/main.ts @@ -1,8 +1,10 @@ +import { appInsights } from '@logto/app-insights/node'; import { ConsoleLog } from '@logto/shared'; import { trySafe } from '@silverhand/essentials'; import chalk from 'chalk'; import Koa from 'koa'; +import initApp from './app/init.js'; import { redisCache } from './caches/index.js'; import { checkAlterationState } from './env-set/check-alteration-state.js'; import { EnvSet } from './env-set/index.js'; @@ -11,7 +13,6 @@ import SystemContext from './tenants/SystemContext.js'; import { checkRowLevelSecurity, tenantPool } from './tenants/index.js'; import { loadConnectorFactories } from './utils/connectors/index.js'; -const { appInsights } = await import('@logto/app-insights/node'); const consoleLog = new ConsoleLog(chalk.magenta('index')); if (await appInsights.setup('core')) { @@ -33,8 +34,6 @@ try { SystemContext.shared.loadProviderConfigs(sharedAdminPool), ]); - // Import last until init completed - const { default: initApp } = await import('./app/init.js'); await initApp(app); } catch (error: unknown) { consoleLog.error('Error while initializing app:'); diff --git a/packages/core/src/tenants/index.ts b/packages/core/src/tenants/index.ts index cb39c2b443b..5e43ee85b68 100644 --- a/packages/core/src/tenants/index.ts +++ b/packages/core/src/tenants/index.ts @@ -31,7 +31,7 @@ class TenantPool { // Otherwise, create a new tenant instance and store in LRU cache, using the code below. } - consoleLog.info('Init tenant:', tenantId, customDomain); + consoleLog.info('Init tenant:', tenantId, 'Custom domain:', customDomain); const newTenantPromise = Tenant.create({ id: tenantId, redisCache, customDomain }); this.cache.set(cacheKey, newTenantPromise); From 5eb5d3a2659657100878c095d52c6f20ab391b48 Mon Sep 17 00:00:00 2001 From: Gao Sun Date: Tue, 7 May 2024 11:08:10 +0800 Subject: [PATCH 347/687] chore(deps): upgrade withtyped packages (#5829) --- packages/cli/package.json | 2 +- packages/console/package.json | 2 +- packages/core/package.json | 2 +- packages/schemas/package.json | 2 +- packages/toolkit/connector-kit/package.json | 4 +-- pnpm-lock.yaml | 36 ++++++++++----------- 6 files changed, 24 insertions(+), 24 deletions(-) diff --git a/packages/cli/package.json b/packages/cli/package.json index d81a2593a2f..21574b67b93 100644 --- a/packages/cli/package.json +++ b/packages/cli/package.json @@ -80,7 +80,7 @@ "@types/tar": "^6.1.12", "@types/yargs": "^17.0.13", "@vitest/coverage-v8": "^1.4.0", - "@withtyped/server": "^0.13.5", + "@withtyped/server": "^0.13.6", "eslint": "^8.56.0", "lint-staged": "^15.0.0", "prettier": "^3.0.0", diff --git a/packages/console/package.json b/packages/console/package.json index f64baa4237b..da6a8649509 100644 --- a/packages/console/package.json +++ b/packages/console/package.json @@ -63,7 +63,7 @@ "@types/react-helmet": "^6.1.6", "@types/react-modal": "^3.13.1", "@types/react-syntax-highlighter": "^15.5.1", - "@withtyped/client": "^0.8.6", + "@withtyped/client": "^0.8.7", "buffer": "^5.7.1", "classnames": "^2.3.1", "clean-deep": "^3.4.0", diff --git a/packages/core/package.json b/packages/core/package.json index 03ffb3fddeb..ba3bea967e9 100644 --- a/packages/core/package.json +++ b/packages/core/package.json @@ -46,7 +46,7 @@ "@silverhand/essentials": "^2.9.0", "@silverhand/slonik": "31.0.0-beta.2", "@simplewebauthn/server": "^9.0.0", - "@withtyped/client": "^0.8.6", + "@withtyped/client": "^0.8.7", "camelcase": "^8.0.0", "camelcase-keys": "^9.0.0", "chalk": "^5.0.0", diff --git a/packages/schemas/package.json b/packages/schemas/package.json index 718d5d81bbb..503752f159a 100644 --- a/packages/schemas/package.json +++ b/packages/schemas/package.json @@ -84,7 +84,7 @@ "@logto/phrases": "workspace:^1.10.0", "@logto/phrases-experience": "workspace:^1.6.1", "@logto/shared": "workspace:^3.1.0", - "@withtyped/server": "^0.13.5" + "@withtyped/server": "^0.13.6" }, "peerDependencies": { "zod": "^3.22.4" diff --git a/packages/toolkit/connector-kit/package.json b/packages/toolkit/connector-kit/package.json index eb359ff280c..8dc10d92d75 100644 --- a/packages/toolkit/connector-kit/package.json +++ b/packages/toolkit/connector-kit/package.json @@ -36,8 +36,8 @@ "dependencies": { "@logto/language-kit": "workspace:^1.1.0", "@silverhand/essentials": "^2.9.0", - "@withtyped/client": "^0.8.6", - "@withtyped/server": "^0.13.5" + "@withtyped/client": "^0.8.7", + "@withtyped/server": "^0.13.6" }, "optionalDependencies": { "zod": "^3.22.4" diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 395e6b64555..f9a8357edb1 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -192,8 +192,8 @@ importers: specifier: ^1.4.0 version: 1.4.0(vitest@1.4.0) '@withtyped/server': - specifier: ^0.13.5 - version: 0.13.5(zod@3.22.4) + specifier: ^0.13.6 + version: 0.13.6(zod@3.22.4) eslint: specifier: ^8.56.0 version: 8.57.0 @@ -2881,8 +2881,8 @@ importers: specifier: ^15.5.1 version: 15.5.1 '@withtyped/client': - specifier: ^0.8.6 - version: 0.8.6(zod@3.22.4) + specifier: ^0.8.7 + version: 0.8.7(zod@3.22.4) buffer: specifier: ^5.7.1 version: 5.7.1 @@ -3136,8 +3136,8 @@ importers: specifier: ^9.0.0 version: 9.0.1 '@withtyped/client': - specifier: ^0.8.6 - version: 0.8.6(zod@3.22.4) + specifier: ^0.8.7 + version: 0.8.7(zod@3.22.4) camelcase: specifier: ^8.0.0 version: 8.0.0 @@ -3854,8 +3854,8 @@ importers: specifier: workspace:^3.1.0 version: link:../shared '@withtyped/server': - specifier: ^0.13.5 - version: 0.13.5(zod@3.22.4) + specifier: ^0.13.6 + version: 0.13.6(zod@3.22.4) zod: specifier: ^3.22.4 version: 3.22.4 @@ -3970,11 +3970,11 @@ importers: specifier: ^2.9.0 version: 2.9.0 '@withtyped/client': - specifier: ^0.8.6 - version: 0.8.6(zod@3.22.4) + specifier: ^0.8.7 + version: 0.8.7(zod@3.22.4) '@withtyped/server': - specifier: ^0.13.5 - version: 0.13.5(zod@3.22.4) + specifier: ^0.13.6 + version: 0.13.6(zod@3.22.4) optionalDependencies: zod: specifier: ^3.22.4 @@ -6788,7 +6788,7 @@ packages: engines: {node: ^20.9.0} dependencies: '@silverhand/essentials': 2.9.0 - '@withtyped/server': 0.13.5(zod@3.22.4) + '@withtyped/server': 0.13.6(zod@3.22.4) transitivePeerDependencies: - zod dev: true @@ -10230,16 +10230,16 @@ packages: pretty-format: 29.7.0 dev: true - /@withtyped/client@0.8.6(zod@3.22.4): - resolution: {integrity: sha512-LJXMHBEJ4VkRMGHF08WDowJRQttrS2QII+6QCcQp4m9M88qJS/2Kvfii1H6u2N4yWNZqHKs3zWVEDRCPV4VLGg==} + /@withtyped/client@0.8.7(zod@3.22.4): + resolution: {integrity: sha512-qK+Tsczvko8mBRACtHGYj0CdMZFaBmosMGUahTAr544Jb183INPZPn/NpUFtTEpl5g3e4lUjMc5jPH0V78D0+g==} dependencies: - '@withtyped/server': 0.13.5(zod@3.22.4) + '@withtyped/server': 0.13.6(zod@3.22.4) '@withtyped/shared': 0.2.2 transitivePeerDependencies: - zod - /@withtyped/server@0.13.5(zod@3.22.4): - resolution: {integrity: sha512-Q5lr6f4G+vjV4q0vBbpEvPUhKOIjAbRqRDXCSHC2nblgB9637njQPvRV8ulXHQWNk5PAMknkgFRJsZWVuHBhAg==} + /@withtyped/server@0.13.6(zod@3.22.4): + resolution: {integrity: sha512-l+jaZ6Gy/S3oF9q91JuHtWlRqB+bK8ycniAK2atK05/ZfhS/qBPV/JPA18fM+JzSQA+tr3CYXnul5SshmYsRoA==} peerDependencies: zod: ^3.19.1 dependencies: From f57e21fc2036f9346e4f8e666cbcc26f4a01f4a8 Mon Sep 17 00:00:00 2001 From: Charles Zhao Date: Tue, 7 May 2024 12:03:05 +0800 Subject: [PATCH 348/687] refactor(console): make invitee email breakable in invitation list (#5825) --- .../pages/TenantSettings/TenantMembers/Invitations/index.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/console/src/pages/TenantSettings/TenantMembers/Invitations/index.tsx b/packages/console/src/pages/TenantSettings/TenantMembers/Invitations/index.tsx index 08c51d120d9..3d0e3e421d6 100644 --- a/packages/console/src/pages/TenantSettings/TenantMembers/Invitations/index.tsx +++ b/packages/console/src/pages/TenantSettings/TenantMembers/Invitations/index.tsx @@ -134,7 +134,7 @@ function Invitations() { dataIndex: 'user', colSpan: 2, title: t('user'), - render: ({ invitee }) => {invitee}, + render: ({ invitee }) => {invitee}, }, { dataIndex: 'roles', From 726a65dd8e4424fcde025534c12396baf699fd6f Mon Sep 17 00:00:00 2001 From: wangsijie Date: Tue, 7 May 2024 16:39:37 +0800 Subject: [PATCH 349/687] feat(core,schemas): add org resource scopes to consent get (#5808) --- packages/core/src/libraries/user.ts | 13 ++- packages/core/src/oidc/init.ts | 15 ++- packages/core/src/oidc/resource.ts | 62 +++++++---- .../core/src/routes/interaction/consent.ts | 105 +++++++++++++++--- .../third-party-sign-in/happy-path.test.ts | 66 +++++++++++ packages/schemas/src/types/consent.ts | 22 ++-- 6 files changed, 227 insertions(+), 56 deletions(-) diff --git a/packages/core/src/libraries/user.ts b/packages/core/src/libraries/user.ts index b6ca2020652..99070a8df7e 100644 --- a/packages/core/src/libraries/user.ts +++ b/packages/core/src/libraries/user.ts @@ -175,15 +175,18 @@ export const createUserLibrary = (queries: Queries) => { const findUserScopesForResourceIndicator = async ( userId: string, resourceIndicator: string, + findFromOrganizations = false, organizationId?: string ): Promise => { const usersRoles = await findUsersRolesByUserId(userId); const rolesScopes = await findRolesScopesByRoleIds(usersRoles.map(({ roleId }) => roleId)); - const organizationScopes = await organizations.relations.rolesUsers.getUserResourceScopes( - userId, - resourceIndicator, - organizationId - ); + const organizationScopes = findFromOrganizations + ? await organizations.relations.rolesUsers.getUserResourceScopes( + userId, + resourceIndicator, + organizationId + ) + : []; const scopes = await findScopesByIdsAndResourceIndicator( [...rolesScopes.map(({ scopeId }) => scopeId), ...organizationScopes.map(({ id }) => id)], diff --git a/packages/core/src/oidc/init.ts b/packages/core/src/oidc/init.ts index 769985d1587..14e0ef15d56 100644 --- a/packages/core/src/oidc/init.ts +++ b/packages/core/src/oidc/init.ts @@ -143,7 +143,9 @@ export default function initOidc( const { accessTokenTtl: accessTokenTTL } = resourceServer; - const { client, params } = ctx.oidc; + const { client, params, session, entities } = ctx.oidc; + const userId = session?.accountId ?? entities.Account?.accountId; + /** * In consent or code exchange flow, the organization_id is undefined, * and all the scopes inherited from the all organization roles will be granted. @@ -152,16 +154,19 @@ export default function initOidc( * and will then narrow down the scopes to the specific organization. */ const organizationId = params?.organization_id; - const scopes = await findResourceScopes( + const scopes = await findResourceScopes({ queries, libraries, - ctx, indicator, - typeof organizationId === 'string' ? organizationId : undefined - ); + findFromOrganizations: true, + organizationId: typeof organizationId === 'string' ? organizationId : undefined, + applicationId: client?.clientId, + userId, + }); // Need to filter out the unsupported scopes for the third-party application. if (client && (await isThirdPartyApplication(queries, client.clientId))) { + // Get application consent resource scopes, from RBAC roles const filteredScopes = await filterResourceScopesForTheThirdPartyApplication( libraries, client.clientId, diff --git a/packages/core/src/oidc/resource.ts b/packages/core/src/oidc/resource.ts index 071a6c5e21c..91f3f5b5b00 100644 --- a/packages/core/src/oidc/resource.ts +++ b/packages/core/src/oidc/resource.ts @@ -1,9 +1,9 @@ import { ReservedResource } from '@logto/core-kit'; import { type Resource } from '@logto/schemas'; import { trySafe, type Nullable } from '@silverhand/essentials'; -import { type ResourceServer, type KoaContextWithOIDC } from 'oidc-provider'; +import { type ResourceServer } from 'oidc-provider'; -import { type EnvSet } from '#src/env-set/index.js'; +import { EnvSet } from '#src/env-set/index.js'; import type Libraries from '#src/tenants/Libraries.js'; import type Queries from '#src/tenants/Queries.js'; @@ -28,13 +28,23 @@ export const getSharedResourceServerData = ( * * @see {@link ReservedResource} for the list of reserved resources. */ -export const findResourceScopes = async ( - queries: Queries, - libraries: Libraries, - ctx: KoaContextWithOIDC, - indicator: string, - organizationId?: string -): Promise> => { +export const findResourceScopes = async ({ + queries, + libraries, + userId, + applicationId, + indicator, + organizationId, + findFromOrganizations, +}: { + queries: Queries; + libraries: Libraries; + indicator: string; + findFromOrganizations: boolean; + userId?: string; + applicationId?: string; + organizationId?: string; +}): Promise> => { if (isReservedResource(indicator)) { switch (indicator) { case ReservedResource.Organization: { @@ -44,21 +54,22 @@ export const findResourceScopes = async ( } } - const { oidc } = ctx; const { users: { findUserScopesForResourceIndicator }, applications: { findApplicationScopesForResourceIndicator }, } = libraries; - const userId = oidc.session?.accountId ?? oidc.entities.Account?.accountId; if (userId) { - return findUserScopesForResourceIndicator(userId, indicator, organizationId); + return findUserScopesForResourceIndicator( + userId, + indicator, + findFromOrganizations, + organizationId + ); } - const clientId = oidc.entities.Client?.clientId; - - if (clientId) { - return findApplicationScopesForResourceIndicator(clientId, indicator); + if (applicationId) { + return findApplicationScopesForResourceIndicator(applicationId, indicator); } return []; @@ -115,6 +126,7 @@ export const filterResourceScopesForTheThirdPartyApplication = async ( applications: { getApplicationUserConsentOrganizationScopes, getApplicationUserConsentResourceScopes, + getApplicationUserConsentOrganizationResourceScopes, }, } = libraries; @@ -146,16 +158,20 @@ export const filterResourceScopesForTheThirdPartyApplication = async ( const userConsentResource = userConsentResources.find( ({ resource }) => resource.indicator === indicator ); + const userConsentOrganizationResources = EnvSet.values.isDevFeaturesEnabled + ? await getApplicationUserConsentOrganizationResourceScopes(applicationId) + : []; + const userConsentOrganizationResource = userConsentOrganizationResources.find( + ({ resource }) => resource.indicator === indicator + ); - // If the resource is not in the application enabled user consent resources, return empty array - if (!userConsentResource) { - return []; - } - - const { scopes: userConsentResourceScopes } = userConsentResource; + const resourceScopes = [ + ...(userConsentResource?.scopes ?? []), + ...(userConsentOrganizationResource?.scopes ?? []), + ]; return scopes.filter(({ id: resourceScopeId }) => - userConsentResourceScopes.some( + resourceScopes.some( ({ id: consentResourceScopeId }) => consentResourceScopeId === resourceScopeId ) ); diff --git a/packages/core/src/routes/interaction/consent.ts b/packages/core/src/routes/interaction/consent.ts index 8c35f9079ca..1bcea6bc2d0 100644 --- a/packages/core/src/routes/interaction/consent.ts +++ b/packages/core/src/routes/interaction/consent.ts @@ -4,7 +4,6 @@ import { publicApplicationGuard, publicUserInfoGuard, applicationSignInExperienceGuard, - publicOrganizationGuard, missingResourceScopesGuard, type ConsentInfoResponse, type MissingResourceScopes, @@ -16,8 +15,10 @@ import { type IRouterParamContext } from 'koa-router'; import { errors } from 'oidc-provider'; import { z } from 'zod'; +import { EnvSet } from '#src/env-set/index.js'; import { consent, getMissingScopes } from '#src/libraries/session.js'; import koaGuard from '#src/middleware/koa-guard.js'; +import { findResourceScopes } from '#src/oidc/resource.js'; import type Queries from '#src/tenants/Queries.js'; import type TenantContext from '#src/tenants/TenantContext.js'; import assertThat from '#src/utils/assert-that.js'; @@ -96,16 +97,63 @@ const parseMissingResourceScopesInfo = async ( ); }; +/** + * The missingResourceScopes in the prompt details are from `getResourceServerInfo`, + * which contains resource scopes and organization resource scopes. + * We need to separate the organization resource scopes from the resource scopes. + * The "scopes" in `missingResourceScopes` do not have "id", so we have to rebuild the scopes list first. + */ +const filterAndParseMissingResourceScopes = async ({ + resourceScopes, + queries, + libraries, + userId, + organizationId, +}: { + resourceScopes: Record; + queries: Queries; + libraries: TenantContext['libraries']; + userId: string; + organizationId?: string; +}) => { + const filteredResourceScopes = Object.fromEntries( + await Promise.all( + Object.entries(resourceScopes).map( + async ([resourceIndicator, missingScopes]): Promise<[string, string[]]> => { + if (!EnvSet.values.isDevFeaturesEnabled) { + return [resourceIndicator, missingScopes]; + } + + // Fetch the list of scopes, `findFromOrganizations` is set to false, + // so it will only search the user resource scopes. + const scopes = await findResourceScopes({ + queries, + libraries, + indicator: resourceIndicator, + userId, + findFromOrganizations: Boolean(organizationId), + organizationId, + }); + + return [ + resourceIndicator, + missingScopes.filter((scope) => scopes.some(({ name }) => name === scope)), + ]; + } + ) + ) + ); + + return parseMissingResourceScopesInfo(queries, filteredResourceScopes); +}; + export default function consentRoutes( router: Router>, - { - provider, - queries, - libraries: { - applications: { validateUserConsentOrganizationMembership }, - }, - }: TenantContext + { provider, queries, libraries }: TenantContext ) { + const { + applications: { validateUserConsentOrganizationMembership }, + } = libraries; const consentPath = `${interactionPrefix}/consent`; router.post( @@ -201,12 +249,42 @@ export default function consentRoutes( const userInfo = await queries.users.findUserById(accountId); - const { missingOIDCScope, missingResourceScopes } = getMissingScopes(prompt); + const { missingOIDCScope, missingResourceScopes: allMissingResourceScopes = {} } = + getMissingScopes(prompt); + + // The missingResourceScopes from the prompt details are from `getResourceServerInfo`, + // which contains resource scopes and organization resource scopes. + // We need to separate the organization resource scopes from the resource scopes. + // The "scopes" in `missingResourceScopes` do not have "id", so we have to rebuild the scopes list. + const missingResourceScopes = await filterAndParseMissingResourceScopes({ + resourceScopes: allMissingResourceScopes, + queries, + libraries, + userId: accountId, + }); // Find the organizations if the application is requesting the organizations scope const organizations = missingOIDCScope?.includes(UserScope.Organizations) ? await queries.organizations.relations.users.getOrganizationsByUserId(accountId) - : undefined; + : []; + + const organizationsWithMissingResourceScopes = await Promise.all( + organizations.map(async ({ name, id }) => { + if (!EnvSet.values.isDevFeaturesEnabled) { + return { name, id }; + } + + const missingResourceScopes = await filterAndParseMissingResourceScopes({ + resourceScopes: allMissingResourceScopes, + queries, + libraries, + userId: accountId, + organizationId: id, + }); + + return { name, id, missingResourceScopes }; + }) + ); ctx.body = { // Merge the public application data and application sign-in-experience data @@ -218,15 +296,12 @@ export default function consentRoutes( ), }, user: publicUserInfoGuard.parse(userInfo), - organizations: organizations?.map((organization) => - publicOrganizationGuard.parse(organization) - ), + organizations: organizationsWithMissingResourceScopes, // Filter out the OIDC scopes that are not needed for the consent page. missingOIDCScope: missingOIDCScope?.filter( (scope) => scope !== 'openid' && scope !== 'offline_access' ), - // Parse the missing resource scopes info with details. - missingResourceScopes: await parseMissingResourceScopesInfo(queries, missingResourceScopes), + missingResourceScopes, redirectUri, } satisfies ConsentInfoResponse; diff --git a/packages/integration-tests/src/tests/api/interaction/third-party-sign-in/happy-path.test.ts b/packages/integration-tests/src/tests/api/interaction/third-party-sign-in/happy-path.test.ts index 44d998e3455..7aab62fc200 100644 --- a/packages/integration-tests/src/tests/api/interaction/third-party-sign-in/happy-path.test.ts +++ b/packages/integration-tests/src/tests/api/interaction/third-party-sign-in/happy-path.test.ts @@ -7,9 +7,18 @@ import { assignUserConsentScopes } from '#src/api/application-user-consent-scope import { createApplication, deleteApplication } from '#src/api/application.js'; import { getConsentInfo, putInteraction } from '#src/api/interaction.js'; import { OrganizationScopeApi } from '#src/api/organization-scope.js'; +import { createResource, deleteResource } from '#src/api/resource.js'; +import { createScope } from '#src/api/scope.js'; import { initClient } from '#src/helpers/client.js'; +import { OrganizationApiTest, OrganizationRoleApiTest } from '#src/helpers/organization.js'; import { enableAllPasswordSignInMethods } from '#src/helpers/sign-in-experience.js'; import { generateNewUser } from '#src/helpers/user.js'; +import { + generateResourceIndicator, + generateResourceName, + generateRoleName, + generateScopeName, +} from '#src/utils.js'; describe('consent api', () => { const applications = new Map(); @@ -126,6 +135,63 @@ describe('consent api', () => { await deleteUser(user.id); }); + it('get consent info with organization resource scopes', async () => { + const application = applications.get(thirdPartyApplicationName); + assert(application, new Error('application.not_found')); + + const resource = await createResource(generateResourceName(), generateResourceIndicator()); + const scope = await createScope(resource.id, generateScopeName()); + const scope2 = await createScope(resource.id, generateScopeName()); + const roleApi = new OrganizationRoleApiTest(); + const role = await roleApi.create({ + name: generateRoleName(), + resourceScopeIds: [scope.id], + }); + const organizationApi = new OrganizationApiTest(); + const organization = await organizationApi.create({ name: 'test_org' }); + const { userProfile, user } = await generateNewUser({ username: true, password: true }); + await organizationApi.addUsers(organization.id, [user.id]); + await organizationApi.addUserRoles(organization.id, user.id, [role.id]); + + await assignUserConsentScopes(application.id, { + organizationResourceScopes: [scope.id], + userScopes: [UserScope.Organizations], + }); + + const client = await initClient( + { + appId: application.id, + appSecret: application.secret, + scopes: [UserScope.Organizations, UserScope.Profile, scope.name, scope2.name], + resources: [resource.indicator], + }, + redirectUri + ); + + await client.successSend(putInteraction, { + event: InteractionEvent.SignIn, + identifier: { + username: userProfile.username, + password: userProfile.password, + }, + }); + + const { redirectTo } = await client.submitInteraction(); + + await client.processSession(redirectTo, false); + + const result = await client.send(getConsentInfo); + + expect(result.missingResourceScopes).toHaveLength(0); + // Only scope1, scope2 is removed + expect(result.organizations?.[0]?.missingResourceScopes).toHaveLength(1); + + await roleApi.cleanUp(); + await organizationApi.cleanUp(); + await deleteResource(resource.id); + await deleteUser(user.id); + }); + afterAll(async () => { for (const application of applications.values()) { void deleteApplication(application.id); diff --git a/packages/schemas/src/types/consent.ts b/packages/schemas/src/types/consent.ts index d1e58468df9..15e8b064936 100644 --- a/packages/schemas/src/types/consent.ts +++ b/packages/schemas/src/types/consent.ts @@ -37,14 +37,6 @@ export const applicationSignInExperienceGuard = ApplicationSignInExperiences.gua termsOfUseUrl: true, }); -/** - * Define the public organization info that can be exposed to the public. e.g. on the user consent page. - */ -export const publicOrganizationGuard = Organizations.guard.pick({ - id: true, - name: true, -}); - export const missingResourceScopesGuard = z.object({ // The original resource id has a maximum length of 21 restriction. We need to make it compatible with the logto reserved organization name. // use string here, as we do not care about the resource id length here. @@ -57,6 +49,20 @@ export const missingResourceScopesGuard = z.object({ */ export type MissingResourceScopes = z.infer; +/** + * Define the public organization info that can be exposed to the public. e.g. on the user consent page. + */ +export const publicOrganizationGuard = Organizations.guard + .pick({ + id: true, + name: true, + }) + .extend({ + missingResourceScopes: missingResourceScopesGuard.array().optional(), + }); + +export type PublicOrganization = z.infer; + export const consentInfoResponseGuard = z.object({ application: publicApplicationGuard.merge(applicationSignInExperienceGuard.partial()), user: publicUserInfoGuard, From 0d8d3a0d955fca4bcc6c876929883202ebb83b56 Mon Sep 17 00:00:00 2001 From: Xiao Yijun Date: Wed, 8 May 2024 13:18:32 +0800 Subject: [PATCH 350/687] feat(experience): display org resource scopes on consent page (#5831) --- .../OrganizationSelector/index.module.scss | 11 +++ .../Consent/OrganizationSelector/index.tsx | 58 ++++++++++- .../Consent/ScopeGroup/index.module.scss | 53 ++++++++++ .../src/pages/Consent/ScopeGroup/index.tsx | 54 +++++++++++ .../pages/Consent/ScopesListCard/index.tsx | 96 +++++++------------ .../src/pages/Consent/index.module.scss | 6 ++ .../experience/src/pages/Consent/index.tsx | 49 ++++++++-- .../src/locales/de/description.ts | 8 +- .../src/locales/en/description.ts | 5 +- .../src/locales/es/description.ts | 8 +- .../src/locales/fr/description.ts | 8 +- .../src/locales/it/description.ts | 8 +- .../src/locales/ja/description.ts | 8 +- .../src/locales/ko/description.ts | 8 +- .../src/locales/pl-pl/description.ts | 8 +- .../src/locales/pt-br/description.ts | 8 +- .../src/locales/pt-pt/description.ts | 8 +- .../src/locales/ru/description.ts | 8 +- .../src/locales/tr-tr/description.ts | 8 +- .../src/locales/zh-cn/description.ts | 6 ++ .../src/locales/zh-hk/description.ts | 8 +- .../src/locales/zh-tw/description.ts | 8 +- 22 files changed, 357 insertions(+), 85 deletions(-) create mode 100644 packages/experience/src/pages/Consent/ScopeGroup/index.module.scss create mode 100644 packages/experience/src/pages/Consent/ScopeGroup/index.tsx diff --git a/packages/experience/src/pages/Consent/OrganizationSelector/index.module.scss b/packages/experience/src/pages/Consent/OrganizationSelector/index.module.scss index 42e19c51786..3383b71b795 100644 --- a/packages/experience/src/pages/Consent/OrganizationSelector/index.module.scss +++ b/packages/experience/src/pages/Consent/OrganizationSelector/index.module.scss @@ -5,6 +5,13 @@ margin-bottom: _.unit(2); } +.scopeListWrapper { + border: _.border(var(--color-line-divider)); + border-bottom: unset; + border-radius: 8px 8px 0 0; + padding: _.unit(2) 0; +} + .cardWrapper { border: _.border(var(--color-line-divider)); border-radius: 8px; @@ -15,6 +22,10 @@ border-color: var(--color-brand-default); outline: 3px solid var(--color-overlay-brand-focused); } + + &.withoutTopRadius { + border-radius: 0 0 8px 8px; + } } .expandButton { diff --git a/packages/experience/src/pages/Consent/OrganizationSelector/index.tsx b/packages/experience/src/pages/Consent/OrganizationSelector/index.tsx index 3f806314518..b54f51953fd 100644 --- a/packages/experience/src/pages/Consent/OrganizationSelector/index.tsx +++ b/packages/experience/src/pages/Consent/OrganizationSelector/index.tsx @@ -1,7 +1,12 @@ +import { ReservedResource } from '@logto/core-kit'; +import classNames from 'classnames'; import { useState, useRef } from 'react'; import { useTranslation } from 'react-i18next'; import ExpandableIcon from '@/assets/icons/expandable-icon.svg'; +import { isDevFeaturesEnabled } from '@/constants/env'; + +import ScopeGroup from '../ScopeGroup'; import OrganizationItem, { type Organization } from './OrganizationItem'; import OrganizationSelectorModal from './OrganizationSelectorModal'; @@ -15,6 +20,7 @@ type Props = { readonly onSelect: (organization: Organization) => void; readonly className?: string; }; + const OrganizationSelector = ({ organizations, selectedOrganization, @@ -29,10 +35,58 @@ const OrganizationSelector = ({ return null; } + // Todo @xiaoyijun remove dev flag + const { missingResourceScopes: resourceScopes } = isDevFeaturesEnabled + ? selectedOrganization + : { + missingResourceScopes: [], + }; + return (
-
{t('description.grant_organization_access')}
-
+
+ {t( + `description.${ + isDevFeaturesEnabled ? 'authorize_organization_access' : 'grant_organization_access' + }` + )} +
+ {resourceScopes && resourceScopes.length > 0 && ( +
+ {resourceScopes + .slice() + // Sort the scopes to make sure the organization scope is always on top + .sort(({ resource: resourceA }, { resource: resourceB }) => { + if (resourceA.id === ReservedResource.Organization) { + return -1; + } + return resourceB.id === ReservedResource.Organization ? 1 : 0; + }) + .map(({ resource, scopes }) => ( + + ))} +
+ )} +
0 && + styles.withoutTopRadius + )} + data-active={showDropdown} + > ; // Organization scope description cloud be `null` + }>; +}; + +const ScopeGroup = ({ groupName, scopes, isAutoExpand = false }: ScopeGroupProps) => { + const [expanded, setExpanded] = useState(isAutoExpand); + + const toggle = useCallback(() => { + setExpanded((previous) => !previous); + }, []); + + return ( +
+
+ +
{groupName}
+ +
+ {expanded && ( +
    + {scopes.map(({ id, name, description }) => ( +
  • + {description ?? name} +
  • + ))} +
+ )} +
+ ); +}; + +export default ScopeGroup; diff --git a/packages/experience/src/pages/Consent/ScopesListCard/index.tsx b/packages/experience/src/pages/Consent/ScopesListCard/index.tsx index 9e7742d0482..87b1bdb66cb 100644 --- a/packages/experience/src/pages/Consent/ScopesListCard/index.tsx +++ b/packages/experience/src/pages/Consent/ScopesListCard/index.tsx @@ -1,63 +1,18 @@ import { ReservedResource, UserScope } from '@logto/core-kit'; import { type ConsentInfoResponse } from '@logto/schemas'; -import { type Nullable } from '@silverhand/essentials'; -import classNames from 'classnames'; -import { useCallback, useMemo, useState } from 'react'; +import { useMemo } from 'react'; import { Trans, useTranslation } from 'react-i18next'; -import DownArrowIcon from '@/assets/icons/arrow-down.svg'; -import CheckMark from '@/assets/icons/check-mark.svg'; import TermsLinks from '@/components/TermsLinks'; -import { onKeyDownHandler } from '@/utils/a11y'; +import { isDevFeaturesEnabled } from '@/constants/env'; + +import ScopeGroup from '../ScopeGroup'; import * as styles from './index.module.scss'; const isUserScope = (scope: string): scope is UserScope => Object.values(UserScope).includes(scope); -type ScopeGroupProps = { - readonly groupName: string; - readonly isAutoExpand?: boolean; - readonly scopes: Array<{ - id: string; - name: string; - description?: Nullable; // Organization scope description cloud be `null` - }>; -}; - -const ScopeGroup = ({ groupName, scopes, isAutoExpand = false }: ScopeGroupProps) => { - const [expanded, setExpanded] = useState(isAutoExpand); - - const toggle = useCallback(() => { - setExpanded((previous) => !previous); - }, []); - - return ( -
-
- -
{groupName}
- -
- {expanded && ( -
    - {scopes.map(({ id, name, description }) => ( -
  • - {description ?? name} -
  • - ))} -
- )} -
- ); -}; - type Props = { readonly userScopes: ConsentInfoResponse['missingOIDCScope']; readonly resourceScopes: ConsentInfoResponse['missingResourceScopes']; @@ -94,7 +49,11 @@ const ScopesListCard = ({ // If there is no user scopes and resource scopes, we don't need to show the scopes list. // This is a fallback for the corner case that all the scopes are already granted. - if (!userScopesData?.length && !resourceScopes?.length) { + if ( + !isDevFeaturesEnabled && // Todo @xiaoyijun remove dev feature flag + !userScopesData?.length && + !resourceScopes?.length + ) { return showTerms ? (
-
{t('description.request_permission', { name: appName })}
+
+ {t( + `description.${ + isDevFeaturesEnabled ? 'authorize_personal_data_usage' : 'request_permission' + }`, + { name: appName } + )} +
{userScopesData && userScopesData.length > 0 && ( ))} - {showTerms && ( -
- , - }} - > - {t('description.authorize_agreement', { name: appName })} - -
- )} + {!isDevFeaturesEnabled && // Todo @xiaoyijun remove dev feature flag + showTerms && ( +
+ + ), + }} + > + {t('description.authorize_agreement', { name: appName })} + +
+ )}
); diff --git a/packages/experience/src/pages/Consent/index.module.scss b/packages/experience/src/pages/Consent/index.module.scss index af6bc466215..0b6591f25d0 100644 --- a/packages/experience/src/pages/Consent/index.module.scss +++ b/packages/experience/src/pages/Consent/index.module.scss @@ -6,6 +6,12 @@ margin-top: _.unit(6); } +.terms { + margin-top: _.unit(5); + font: var(--font-body-3); + color: var(--color-type-secondary); +} + .redirectUri { margin-top: _.unit(5); text-align: center; diff --git a/packages/experience/src/pages/Consent/index.tsx b/packages/experience/src/pages/Consent/index.tsx index 269ade38c58..98028d0f814 100644 --- a/packages/experience/src/pages/Consent/index.tsx +++ b/packages/experience/src/pages/Consent/index.tsx @@ -1,11 +1,14 @@ +import { ReservedResource } from '@logto/core-kit'; import { type ConsentInfoResponse } from '@logto/schemas'; import { useCallback, useEffect, useState } from 'react'; -import { useTranslation } from 'react-i18next'; +import { Trans, useTranslation } from 'react-i18next'; import LandingPageLayout from '@/Layout/LandingPageLayout'; import { consent, getConsentInfo } from '@/apis/consent'; import Button from '@/components/Button'; +import TermsLinks from '@/components/TermsLinks'; import TextLink from '@/components/TextLink'; +import { isDevFeaturesEnabled } from '@/constants/env'; import useApi from '@/hooks/use-api'; import useErrorHandler from '@/hooks/use-error-handler'; @@ -66,7 +69,12 @@ const Consent = () => { return null; } - const applicationName = consentData.application.displayName ?? consentData.application.name; + const { + application: { displayName, name, termsOfUseUrl, privacyPolicyUrl }, + } = consentData; + + const applicationName = displayName ?? name; + const showTerms = Boolean(termsOfUseUrl ?? privacyPolicyUrl); return ( { !isDevFeaturesEnabled || resource.id !== ReservedResource.Organization + )} appName={applicationName} className={styles.scopesCard} termsUrl={consentData.application.termsOfUseUrl ?? undefined} @@ -103,9 +117,32 @@ const Consent = () => { />
-
- {t('description.redirect_to', { name: getRedirectUriOrigin(consentData.redirectUri) })} -
+ {(!isDevFeaturesEnabled || !showTerms) && ( +
+ {t('description.redirect_to', { name: getRedirectUriOrigin(consentData.redirectUri) })} +
+ )} + {isDevFeaturesEnabled && showTerms && ( +
+ + ), + }} + > + {t('description.authorize_agreement_with_redirect', { + name, + uri: getRedirectUriOrigin(consentData.redirectUri), + })} + +
+ )} +
{t('description.not_you')}{' '} diff --git a/packages/phrases-experience/src/locales/de/description.ts b/packages/phrases-experience/src/locales/de/description.ts index e96869047b0..9d777c4b2eb 100644 --- a/packages/phrases-experience/src/locales/de/description.ts +++ b/packages/phrases-experience/src/locales/de/description.ts @@ -83,11 +83,17 @@ const description = { /** UNTRANSLATED */ grant_organization_access: 'Grant the organization access:', /** UNTRANSLATED */ + authorize_personal_data_usage: 'Authorize the use of your personal data:', + /** UNTRANSLATED */ + authorize_organization_access: 'Authorize access to the specific organization:', + /** UNTRANSLATED */ user_scopes: 'Personal user data', /** UNTRANSLATED */ organization_scopes: 'Organization access', /** UNTRANSLATED */ - authorize_agreement: `By authorize the access, you agree to the {{name}}'s .`, + authorize_agreement: `By authorizing the access, you agree to the {{name}}'s .`, + /** UNTRANSLATED */ + authorize_agreement_with_redirect: `By authorizing the access, you agree to the {{name}}'s , and will be redirected to {{uri}}.`, /** UNTRANSLATED */ not_you: 'Not you?', /** UNTRANSLATED */ diff --git a/packages/phrases-experience/src/locales/en/description.ts b/packages/phrases-experience/src/locales/en/description.ts index d7f8682d4f6..687095e0d69 100644 --- a/packages/phrases-experience/src/locales/en/description.ts +++ b/packages/phrases-experience/src/locales/en/description.ts @@ -76,9 +76,12 @@ const description = { authorize_title: 'Authorize {{name}}', request_permission: '{{name}} is requesting access to:', grant_organization_access: 'Grant the organization access:', + authorize_personal_data_usage: 'Authorize the use of your personal data:', + authorize_organization_access: 'Authorize access to the specific organization:', user_scopes: 'Personal user data', organization_scopes: 'Organization access', - authorize_agreement: `By authorize the access, you agree to the {{name}}'s .`, + authorize_agreement: `By authorizing the access, you agree to the {{name}}'s .`, + authorize_agreement_with_redirect: `By authorizing the access, you agree to the {{name}}'s , and will be redirected to {{uri}}.`, not_you: 'Not you?', user_id: 'User ID: {{id}}', redirect_to: 'You will be redirected to {{name}}.', diff --git a/packages/phrases-experience/src/locales/es/description.ts b/packages/phrases-experience/src/locales/es/description.ts index 3f759568afc..36f9d2b505a 100644 --- a/packages/phrases-experience/src/locales/es/description.ts +++ b/packages/phrases-experience/src/locales/es/description.ts @@ -82,11 +82,17 @@ const description = { /** UNTRANSLATED */ grant_organization_access: 'Grant the organization access:', /** UNTRANSLATED */ + authorize_personal_data_usage: 'Authorize the use of your personal data:', + /** UNTRANSLATED */ + authorize_organization_access: 'Authorize access to the specific organization:', + /** UNTRANSLATED */ user_scopes: 'Personal user data', /** UNTRANSLATED */ organization_scopes: 'Organization access', /** UNTRANSLATED */ - authorize_agreement: `By authorize the access, you agree to the {{name}}'s .`, + authorize_agreement: `By authorizing the access, you agree to the {{name}}'s .`, + /** UNTRANSLATED */ + authorize_agreement_with_redirect: `By authorizing the access, you agree to the {{name}}'s , and will be redirected to {{uri}}.`, /** UNTRANSLATED */ not_you: 'Not you?', /** UNTRANSLATED */ diff --git a/packages/phrases-experience/src/locales/fr/description.ts b/packages/phrases-experience/src/locales/fr/description.ts index 9870641a33f..9b5069abb0a 100644 --- a/packages/phrases-experience/src/locales/fr/description.ts +++ b/packages/phrases-experience/src/locales/fr/description.ts @@ -83,11 +83,17 @@ const description = { /** UNTRANSLATED */ grant_organization_access: 'Grant the organization access:', /** UNTRANSLATED */ + authorize_personal_data_usage: 'Authorize the use of your personal data:', + /** UNTRANSLATED */ + authorize_organization_access: 'Authorize access to the specific organization:', + /** UNTRANSLATED */ user_scopes: 'Personal user data', /** UNTRANSLATED */ organization_scopes: 'Organization access', /** UNTRANSLATED */ - authorize_agreement: `By authorize the access, you agree to the {{name}}'s .`, + authorize_agreement: `By authorizing the access, you agree to the {{name}}'s .`, + /** UNTRANSLATED */ + authorize_agreement_with_redirect: `By authorizing the access, you agree to the {{name}}'s , and will be redirected to {{uri}}.`, /** UNTRANSLATED */ not_you: 'Not you?', /** UNTRANSLATED */ diff --git a/packages/phrases-experience/src/locales/it/description.ts b/packages/phrases-experience/src/locales/it/description.ts index a5c90ed07f3..8e264e4ccc1 100644 --- a/packages/phrases-experience/src/locales/it/description.ts +++ b/packages/phrases-experience/src/locales/it/description.ts @@ -79,11 +79,17 @@ const description = { /** UNTRANSLATED */ grant_organization_access: 'Grant the organization access:', /** UNTRANSLATED */ + authorize_personal_data_usage: 'Authorize the use of your personal data:', + /** UNTRANSLATED */ + authorize_organization_access: 'Authorize access to the specific organization:', + /** UNTRANSLATED */ user_scopes: 'Personal user data', /** UNTRANSLATED */ organization_scopes: 'Organization access', /** UNTRANSLATED */ - authorize_agreement: `By authorize the access, you agree to the {{name}}'s .`, + authorize_agreement: `By authorizing the access, you agree to the {{name}}'s .`, + /** UNTRANSLATED */ + authorize_agreement_with_redirect: `By authorizing the access, you agree to the {{name}}'s , and will be redirected to {{uri}}.`, /** UNTRANSLATED */ not_you: 'Not you?', /** UNTRANSLATED */ diff --git a/packages/phrases-experience/src/locales/ja/description.ts b/packages/phrases-experience/src/locales/ja/description.ts index a5322fb74fd..6bf7ecd1c57 100644 --- a/packages/phrases-experience/src/locales/ja/description.ts +++ b/packages/phrases-experience/src/locales/ja/description.ts @@ -79,11 +79,17 @@ const description = { /** UNTRANSLATED */ grant_organization_access: 'Grant the organization access:', /** UNTRANSLATED */ + authorize_personal_data_usage: 'Authorize the use of your personal data:', + /** UNTRANSLATED */ + authorize_organization_access: 'Authorize access to the specific organization:', + /** UNTRANSLATED */ user_scopes: 'Personal user data', /** UNTRANSLATED */ organization_scopes: 'Organization access', /** UNTRANSLATED */ - authorize_agreement: `By authorize the access, you agree to the {{name}}'s .`, + authorize_agreement: `By authorizing the access, you agree to the {{name}}'s .`, + /** UNTRANSLATED */ + authorize_agreement_with_redirect: `By authorizing the access, you agree to the {{name}}'s , and will be redirected to {{uri}}.`, /** UNTRANSLATED */ not_you: 'Not you?', /** UNTRANSLATED */ diff --git a/packages/phrases-experience/src/locales/ko/description.ts b/packages/phrases-experience/src/locales/ko/description.ts index b34cc59cd43..219ebdc619c 100644 --- a/packages/phrases-experience/src/locales/ko/description.ts +++ b/packages/phrases-experience/src/locales/ko/description.ts @@ -74,11 +74,17 @@ const description = { /** UNTRANSLATED */ grant_organization_access: 'Grant the organization access:', /** UNTRANSLATED */ + authorize_personal_data_usage: 'Authorize the use of your personal data:', + /** UNTRANSLATED */ + authorize_organization_access: 'Authorize access to the specific organization:', + /** UNTRANSLATED */ user_scopes: 'Personal user data', /** UNTRANSLATED */ organization_scopes: 'Organization access', /** UNTRANSLATED */ - authorize_agreement: `By authorize the access, you agree to the {{name}}'s .`, + authorize_agreement: `By authorizing the access, you agree to the {{name}}'s .`, + /** UNTRANSLATED */ + authorize_agreement_with_redirect: `By authorizing the access, you agree to the {{name}}'s , and will be redirected to {{uri}}.`, /** UNTRANSLATED */ not_you: 'Not you?', /** UNTRANSLATED */ diff --git a/packages/phrases-experience/src/locales/pl-pl/description.ts b/packages/phrases-experience/src/locales/pl-pl/description.ts index bd107651e0b..3d42287e9bb 100644 --- a/packages/phrases-experience/src/locales/pl-pl/description.ts +++ b/packages/phrases-experience/src/locales/pl-pl/description.ts @@ -79,11 +79,17 @@ const description = { /** UNTRANSLATED */ grant_organization_access: 'Grant the organization access:', /** UNTRANSLATED */ + authorize_personal_data_usage: 'Authorize the use of your personal data:', + /** UNTRANSLATED */ + authorize_organization_access: 'Authorize access to the specific organization:', + /** UNTRANSLATED */ user_scopes: 'Personal user data', /** UNTRANSLATED */ organization_scopes: 'Organization access', /** UNTRANSLATED */ - authorize_agreement: `By authorize the access, you agree to the {{name}}'s .`, + authorize_agreement: `By authorizing the access, you agree to the {{name}}'s .`, + /** UNTRANSLATED */ + authorize_agreement_with_redirect: `By authorizing the access, you agree to the {{name}}'s , and will be redirected to {{uri}}.`, /** UNTRANSLATED */ not_you: 'Not you?', /** UNTRANSLATED */ diff --git a/packages/phrases-experience/src/locales/pt-br/description.ts b/packages/phrases-experience/src/locales/pt-br/description.ts index 421e2d42447..1743243458a 100644 --- a/packages/phrases-experience/src/locales/pt-br/description.ts +++ b/packages/phrases-experience/src/locales/pt-br/description.ts @@ -78,11 +78,17 @@ const description = { /** UNTRANSLATED */ grant_organization_access: 'Grant the organization access:', /** UNTRANSLATED */ + authorize_personal_data_usage: 'Authorize the use of your personal data:', + /** UNTRANSLATED */ + authorize_organization_access: 'Authorize access to the specific organization:', + /** UNTRANSLATED */ user_scopes: 'Personal user data', /** UNTRANSLATED */ organization_scopes: 'Organization access', /** UNTRANSLATED */ - authorize_agreement: `By authorize the access, you agree to the {{name}}'s .`, + authorize_agreement: `By authorizing the access, you agree to the {{name}}'s .`, + /** UNTRANSLATED */ + authorize_agreement_with_redirect: `By authorizing the access, you agree to the {{name}}'s , and will be redirected to {{uri}}.`, /** UNTRANSLATED */ not_you: 'Not you?', /** UNTRANSLATED */ diff --git a/packages/phrases-experience/src/locales/pt-pt/description.ts b/packages/phrases-experience/src/locales/pt-pt/description.ts index af43b3ab8c4..46cadfd04c1 100644 --- a/packages/phrases-experience/src/locales/pt-pt/description.ts +++ b/packages/phrases-experience/src/locales/pt-pt/description.ts @@ -78,11 +78,17 @@ const description = { /** UNTRANSLATED */ grant_organization_access: 'Grant the organization access:', /** UNTRANSLATED */ + authorize_personal_data_usage: 'Authorize the use of your personal data:', + /** UNTRANSLATED */ + authorize_organization_access: 'Authorize access to the specific organization:', + /** UNTRANSLATED */ user_scopes: 'Personal user data', /** UNTRANSLATED */ organization_scopes: 'Organization access', /** UNTRANSLATED */ - authorize_agreement: `By authorize the access, you agree to the {{name}}'s .`, + authorize_agreement: `By authorizing the access, you agree to the {{name}}'s .`, + /** UNTRANSLATED */ + authorize_agreement_with_redirect: `By authorizing the access, you agree to the {{name}}'s , and will be redirected to {{uri}}.`, /** UNTRANSLATED */ not_you: 'Not you?', /** UNTRANSLATED */ diff --git a/packages/phrases-experience/src/locales/ru/description.ts b/packages/phrases-experience/src/locales/ru/description.ts index 830e05566ee..48052a31dc7 100644 --- a/packages/phrases-experience/src/locales/ru/description.ts +++ b/packages/phrases-experience/src/locales/ru/description.ts @@ -82,11 +82,17 @@ const description = { /** UNTRANSLATED */ grant_organization_access: 'Grant the organization access:', /** UNTRANSLATED */ + authorize_personal_data_usage: 'Authorize the use of your personal data:', + /** UNTRANSLATED */ + authorize_organization_access: 'Authorize access to the specific organization:', + /** UNTRANSLATED */ user_scopes: 'Personal user data', /** UNTRANSLATED */ organization_scopes: 'Organization access', /** UNTRANSLATED */ - authorize_agreement: `By authorize the access, you agree to the {{name}}'s .`, + authorize_agreement: `By authorizing the access, you agree to the {{name}}'s .`, + /** UNTRANSLATED */ + authorize_agreement_with_redirect: `By authorizing the access, you agree to the {{name}}'s , and will be redirected to {{uri}}.`, /** UNTRANSLATED */ not_you: 'Not you?', /** UNTRANSLATED */ diff --git a/packages/phrases-experience/src/locales/tr-tr/description.ts b/packages/phrases-experience/src/locales/tr-tr/description.ts index b2f6e6adbd2..24748104c78 100644 --- a/packages/phrases-experience/src/locales/tr-tr/description.ts +++ b/packages/phrases-experience/src/locales/tr-tr/description.ts @@ -78,11 +78,17 @@ const description = { /** UNTRANSLATED */ grant_organization_access: 'Grant the organization access:', /** UNTRANSLATED */ + authorize_personal_data_usage: 'Authorize the use of your personal data:', + /** UNTRANSLATED */ + authorize_organization_access: 'Authorize access to the specific organization:', + /** UNTRANSLATED */ user_scopes: 'Personal user data', /** UNTRANSLATED */ organization_scopes: 'Organization access', /** UNTRANSLATED */ - authorize_agreement: `By authorize the access, you agree to the {{name}}'s .`, + authorize_agreement: `By authorizing the access, you agree to the {{name}}'s .`, + /** UNTRANSLATED */ + authorize_agreement_with_redirect: `By authorizing the access, you agree to the {{name}}'s , and will be redirected to {{uri}}.`, /** UNTRANSLATED */ not_you: 'Not you?', /** UNTRANSLATED */ diff --git a/packages/phrases-experience/src/locales/zh-cn/description.ts b/packages/phrases-experience/src/locales/zh-cn/description.ts index ba207ad56bb..1853e34d860 100644 --- a/packages/phrases-experience/src/locales/zh-cn/description.ts +++ b/packages/phrases-experience/src/locales/zh-cn/description.ts @@ -66,9 +66,15 @@ const description = { authorize_title: '授权给 {{name}}', request_permission: '{{name}} 需要权限:', grant_organization_access: '授予组织访问权限:', + /** UNTRANSLATED */ + authorize_personal_data_usage: 'Authorize the use of your personal data:', + /** UNTRANSLATED */ + authorize_organization_access: 'Authorize access to the specific organization:', user_scopes: '用户个人信息', organization_scopes: '组织权限', authorize_agreement: `你将同意授权给 {{name}} .`, + /** UNTRANSLATED */ + authorize_agreement_with_redirect: `你将同意授权给 {{name}} ,然后你将被重定向到 {{uri}}。`, not_you: '不是你本人吗?', user_id: '用户 ID: {{id}}', redirect_to: '你将被重定向到 {{name}}。', diff --git a/packages/phrases-experience/src/locales/zh-hk/description.ts b/packages/phrases-experience/src/locales/zh-hk/description.ts index 7b3d08c63e2..be3278acac2 100644 --- a/packages/phrases-experience/src/locales/zh-hk/description.ts +++ b/packages/phrases-experience/src/locales/zh-hk/description.ts @@ -70,11 +70,17 @@ const description = { /** UNTRANSLATED */ grant_organization_access: 'Grant the organization access:', /** UNTRANSLATED */ + authorize_personal_data_usage: 'Authorize the use of your personal data:', + /** UNTRANSLATED */ + authorize_organization_access: 'Authorize access to the specific organization:', + /** UNTRANSLATED */ user_scopes: 'Personal user data', /** UNTRANSLATED */ organization_scopes: 'Organization access', /** UNTRANSLATED */ - authorize_agreement: `By authorize the access, you agree to the {{name}}'s .`, + authorize_agreement: `By authorizing the access, you agree to the {{name}}'s .`, + /** UNTRANSLATED */ + authorize_agreement_with_redirect: `By authorizing the access, you agree to the {{name}}'s , and will be redirected to {{uri}}.`, /** UNTRANSLATED */ not_you: 'Not you?', /** UNTRANSLATED */ diff --git a/packages/phrases-experience/src/locales/zh-tw/description.ts b/packages/phrases-experience/src/locales/zh-tw/description.ts index 0855f68376b..d683dfa8126 100644 --- a/packages/phrases-experience/src/locales/zh-tw/description.ts +++ b/packages/phrases-experience/src/locales/zh-tw/description.ts @@ -70,11 +70,17 @@ const description = { /** UNTRANSLATED */ grant_organization_access: 'Grant the organization access:', /** UNTRANSLATED */ + authorize_personal_data_usage: 'Authorize the use of your personal data:', + /** UNTRANSLATED */ + authorize_organization_access: 'Authorize access to the specific organization:', + /** UNTRANSLATED */ user_scopes: 'Personal user data', /** UNTRANSLATED */ organization_scopes: 'Organization access', /** UNTRANSLATED */ - authorize_agreement: `By authorize the access, you agree to the {{name}}'s .`, + authorize_agreement: `By authorizing the access, you agree to the {{name}}'s .`, + /** UNTRANSLATED */ + authorize_agreement_with_redirect: `By authorizing the access, you agree to the {{name}}'s , and will be redirected to {{uri}}.`, /** UNTRANSLATED */ not_you: 'Not you?', /** UNTRANSLATED */ From 21bb35b1274345a97fa8d9736972269d8b0f6e74 Mon Sep 17 00:00:00 2001 From: Gao Sun Date: Thu, 9 May 2024 11:19:01 +0800 Subject: [PATCH 351/687] feat: init management api hook middleware function (#5783) * feat: init management api hook middleware function * refactor: fix type issues * feat(core): implement auto triggered management api hooks implement auto triggered managment api hooks * refactor(console,core,schemas): rename the managementHook to dataHook rename the managementHooke to dataHook and redefine the types * feat(core): add dev feature guard add dev feature guard * chore: update changeset update changeset * refactor(core,console,schemas,shared): update the webhook logics update the webhook logics. Address some PR review comments * fix(test): fix integration tests fix integration tests * fix(test): remove legacy code remove legacy code * refactor(core,schemas): refactor the hook library code refactor the webhooks library code. address some comments * fix(core): address rebase issue update console log using getConsoleLogFromContext * fix(core): fix ut fix ut * fix(core): refactor data webhook code refactor data webhook codes * refactor(core): clean up some management api webhook code clean up some management api webhook code --------- Co-authored-by: simeng-li --- .changeset/fluffy-steaks-flow.md | 10 + .changeset/metal-lions-swim.md | 7 + .../src/components/BasicWebhookForm/index.tsx | 5 +- packages/console/src/consts/webhooks.ts | 20 +- .../WebhookDetails/WebhookLogs/index.tsx | 10 +- packages/console/src/pages/Webhooks/index.tsx | 5 +- packages/core/package.json | 1 + packages/core/src/__mocks__/hook.ts | 10 +- .../src/libraries/hook/context-manager.ts | 24 +++ .../core/src/libraries/hook/index.test.ts | 111 +++++++++-- packages/core/src/libraries/hook/index.ts | 186 +++++++++++------- packages/core/src/libraries/hook/types.ts | 28 +++ .../core/src/libraries/hook/utils.test.ts | 4 +- packages/core/src/libraries/hook/utils.ts | 15 +- .../koa-management-api-hooks.test.ts | 95 +++++++++ .../middleware/koa-management-api-hooks.ts | 66 +++++++ packages/core/src/routes/hook.test.ts | 32 +-- packages/core/src/routes/hook.ts | 8 +- packages/core/src/routes/init.ts | 2 + .../middleware/koa-interaction-hooks.ts | 7 +- packages/core/src/routes/types.ts | 2 + .../src/tests/api/hook/hook.stats.test.ts | 6 +- .../src/tests/api/hook/hook.test.ts | 18 +- .../src/tests/api/hook/hook.testing.test.ts | 22 ++- .../src/tests/api/hook/hook.trigger.test.ts | 69 ++++--- .../src/foundations/jsonb-types/hooks.ts | 53 ++++- packages/schemas/src/types/hook.ts | 22 ++- packages/shared/src/utils/index.ts | 9 +- packages/shared/src/utils/normalize-error.ts | 94 +++++++++ pnpm-lock.yaml | 8 + 30 files changed, 763 insertions(+), 186 deletions(-) create mode 100644 .changeset/fluffy-steaks-flow.md create mode 100644 .changeset/metal-lions-swim.md create mode 100644 packages/core/src/libraries/hook/context-manager.ts create mode 100644 packages/core/src/libraries/hook/types.ts create mode 100644 packages/core/src/middleware/koa-management-api-hooks.test.ts create mode 100644 packages/core/src/middleware/koa-management-api-hooks.ts create mode 100644 packages/shared/src/utils/normalize-error.ts diff --git a/.changeset/fluffy-steaks-flow.md b/.changeset/fluffy-steaks-flow.md new file mode 100644 index 00000000000..998c2289937 --- /dev/null +++ b/.changeset/fluffy-steaks-flow.md @@ -0,0 +1,10 @@ +--- +"@logto/schemas": minor +"@logto/core": minor +"@logto/console": minor +--- + +refactor the definition of hook event types + +- Add `DataHook` event types. `DataHook` are triggered by data changes. +- Add "interaction" prefix to existing hook event types. Interaction hook events are triggered by end user interactions, e.g. completing sign-in. diff --git a/.changeset/metal-lions-swim.md b/.changeset/metal-lions-swim.md new file mode 100644 index 00000000000..aef92851d90 --- /dev/null +++ b/.changeset/metal-lions-swim.md @@ -0,0 +1,7 @@ +--- +"@logto/shared": patch +--- + +add `normalizeError` method to `@logto/shared` package + +Use this method to normalize error objects for logging. This method is useful for logging errors in a consistent format. diff --git a/packages/console/src/components/BasicWebhookForm/index.tsx b/packages/console/src/components/BasicWebhookForm/index.tsx index 8e28e5ed8b8..b332732964b 100644 --- a/packages/console/src/components/BasicWebhookForm/index.tsx +++ b/packages/console/src/components/BasicWebhookForm/index.tsx @@ -1,4 +1,4 @@ -import { HookEvent, type Hook, type HookConfig } from '@logto/schemas'; +import { type HookEvent, type Hook, type HookConfig, InteractionHookEvent } from '@logto/schemas'; import { Controller, useFormContext } from 'react-hook-form'; import { useTranslation } from 'react-i18next'; @@ -10,7 +10,8 @@ import { uriValidator } from '@/utils/validator'; import * as styles from './index.module.scss'; -const hookEventOptions = Object.values(HookEvent).map((event) => ({ +// TODO: Implement all hook events +const hookEventOptions = Object.values(InteractionHookEvent).map((event) => ({ title: hookEventLabel[event], value: event, })); diff --git a/packages/console/src/consts/webhooks.ts b/packages/console/src/consts/webhooks.ts index 77af895fc7a..d3b8cec2bea 100644 --- a/packages/console/src/consts/webhooks.ts +++ b/packages/console/src/consts/webhooks.ts @@ -1,22 +1,24 @@ import { type AdminConsoleKey } from '@logto/phrases'; -import { HookEvent, type LogKey } from '@logto/schemas'; +import { InteractionHookEvent, type LogKey } from '@logto/schemas'; type HookEventLabel = { - [key in HookEvent]: AdminConsoleKey; + // TODO: Implement all hook events + [key in InteractionHookEvent]: AdminConsoleKey; }; export const hookEventLabel = Object.freeze({ - [HookEvent.PostRegister]: 'webhooks.events.post_register', - [HookEvent.PostResetPassword]: 'webhooks.events.post_reset_password', - [HookEvent.PostSignIn]: 'webhooks.events.post_sign_in', + [InteractionHookEvent.PostRegister]: 'webhooks.events.post_register', + [InteractionHookEvent.PostResetPassword]: 'webhooks.events.post_reset_password', + [InteractionHookEvent.PostSignIn]: 'webhooks.events.post_sign_in', }) satisfies HookEventLabel; type HookEventLogKey = { - [key in HookEvent]: LogKey; + // TODO: Implement all hook events + [key in InteractionHookEvent]: LogKey; }; export const hookEventLogKey = Object.freeze({ - [HookEvent.PostRegister]: 'TriggerHook.PostRegister', - [HookEvent.PostResetPassword]: 'TriggerHook.PostResetPassword', - [HookEvent.PostSignIn]: 'TriggerHook.PostSignIn', + [InteractionHookEvent.PostRegister]: 'TriggerHook.PostRegister', + [InteractionHookEvent.PostResetPassword]: 'TriggerHook.PostResetPassword', + [InteractionHookEvent.PostSignIn]: 'TriggerHook.PostSignIn', }) satisfies HookEventLogKey; diff --git a/packages/console/src/pages/WebhookDetails/WebhookLogs/index.tsx b/packages/console/src/pages/WebhookDetails/WebhookLogs/index.tsx index e4a24c6d167..733a321b00f 100644 --- a/packages/console/src/pages/WebhookDetails/WebhookLogs/index.tsx +++ b/packages/console/src/pages/WebhookDetails/WebhookLogs/index.tsx @@ -1,4 +1,4 @@ -import { type Log, HookEvent } from '@logto/schemas'; +import { type Log, InteractionHookEvent } from '@logto/schemas'; import { conditional } from '@silverhand/essentials'; import { useTranslation } from 'react-i18next'; import { useOutletContext } from 'react-router-dom'; @@ -21,7 +21,8 @@ import { type WebhookDetailsOutletContext } from '../types'; import * as styles from './index.module.scss'; -const hookLogEventOptions = Object.values(HookEvent).map((event) => ({ +// TODO: Implement all hook events +const hookLogEventOptions = Object.values(InteractionHookEvent).map((event) => ({ title: , value: hookEventLogKey[event], })); @@ -96,7 +97,10 @@ function WebhookLogs() { dataIndex: 'event', colSpan: 6, render: ({ key }) => { - const event = Object.values(HookEvent).find((event) => hookEventLogKey[event] === key); + // TODO: Implement all hook events + const event = Object.values(InteractionHookEvent).find( + (event) => hookEventLogKey[event] === key + ); return conditional(event && t(hookEventLabel[event])) ?? '-'; }, }, diff --git a/packages/console/src/pages/Webhooks/index.tsx b/packages/console/src/pages/Webhooks/index.tsx index e7e881c9c2b..c2a622cd9a1 100644 --- a/packages/console/src/pages/Webhooks/index.tsx +++ b/packages/console/src/pages/Webhooks/index.tsx @@ -1,4 +1,4 @@ -import { type HookEvent, type Hook, Theme, type HookResponse } from '@logto/schemas'; +import { type Hook, Theme, type HookResponse, type InteractionHookEvent } from '@logto/schemas'; import { conditional } from '@silverhand/essentials'; import { toast } from 'react-hot-toast'; import { useTranslation } from 'react-i18next'; @@ -93,8 +93,9 @@ function Webhooks() { const eventArray = conditional(events.length > 0 && events) ?? [event]; return ( eventArray + // TODO: Implement all hook events // eslint-disable-next-line unicorn/prefer-native-coercion-functions - .filter((_event): _event is HookEvent => Boolean(_event)) + .filter((_event): _event is InteractionHookEvent => Boolean(_event)) .map((_event) => t(hookEventLabel[_event])) .join(', ') ); diff --git a/packages/core/package.json b/packages/core/package.json index ba3bea967e9..5f71ac05e60 100644 --- a/packages/core/package.json +++ b/packages/core/package.json @@ -79,6 +79,7 @@ "oidc-provider": "^8.4.6", "openapi-types": "^12.1.3", "otplib": "^12.0.1", + "p-map": "^7.0.2", "p-retry": "^6.0.0", "pg-protocol": "^1.6.0", "pluralize": "^8.0.0", diff --git a/packages/core/src/__mocks__/hook.ts b/packages/core/src/__mocks__/hook.ts index 75589eba6b9..8b90b2cf352 100644 --- a/packages/core/src/__mocks__/hook.ts +++ b/packages/core/src/__mocks__/hook.ts @@ -1,4 +1,4 @@ -import { type Hook, HookEvent } from '@logto/schemas'; +import { type Hook, InteractionHookEvent } from '@logto/schemas'; export const mockNanoIdForHook = 'random_string'; @@ -11,7 +11,7 @@ export const mockHook: Hook = { id: mockNanoIdForHook, name: 'foo', event: null, - events: [HookEvent.PostRegister], + events: [InteractionHookEvent.PostRegister], config: { url: 'https://example.com', }, @@ -25,7 +25,7 @@ const mockHookData1: Hook = { id: 'hook_id_1', name: 'foo', event: null, - events: [HookEvent.PostRegister], + events: [InteractionHookEvent.PostRegister], config: { url: 'https://example1.com', }, @@ -39,7 +39,7 @@ const mockHookData2: Hook = { id: 'hook_id_2', name: 'bar', event: null, - events: [HookEvent.PostResetPassword], + events: [InteractionHookEvent.PostResetPassword], config: { url: 'https://example2.com', }, @@ -53,7 +53,7 @@ const mockHookData3: Hook = { id: 'hook_id_3', name: 'baz', event: null, - events: [HookEvent.PostSignIn], + events: [InteractionHookEvent.PostSignIn], config: { url: 'https://example3.com', }, diff --git a/packages/core/src/libraries/hook/context-manager.ts b/packages/core/src/libraries/hook/context-manager.ts new file mode 100644 index 00000000000..cb38a83e93d --- /dev/null +++ b/packages/core/src/libraries/hook/context-manager.ts @@ -0,0 +1,24 @@ +import { type DataHookEvent } from '@logto/schemas'; + +type DataHookContext = { + event: DataHookEvent; + data?: Record; +}; + +type DataHookMetadata = { + userAgent?: string; + ip: string; +}; + +export class DataHookContextManager { + contextArray: DataHookContext[] = []; + + constructor(public metadata: DataHookMetadata) {} + + appendContext({ event, data }: DataHookContext) { + // eslint-disable-next-line @silverhand/fp/no-mutating-methods + this.contextArray.push({ event, data }); + } +} + +// TODO: @simeng-li migrate the current interaction hook context using hook context manager diff --git a/packages/core/src/libraries/hook/index.test.ts b/packages/core/src/libraries/hook/index.test.ts index 033aec1d6bc..66a82f539ef 100644 --- a/packages/core/src/libraries/hook/index.test.ts +++ b/packages/core/src/libraries/hook/index.test.ts @@ -1,11 +1,12 @@ import type { Hook } from '@logto/schemas'; -import { HookEvent, InteractionEvent, LogResult } from '@logto/schemas'; +import { InteractionEvent, InteractionHookEvent, LogResult } from '@logto/schemas'; import { ConsoleLog } from '@logto/shared'; import { createMockUtils } from '@logto/shared/esm'; import RequestError from '#src/errors/RequestError/index.js'; import { mockId, mockIdGenerators } from '#src/test-utils/nanoid.js'; +import { DataHookContextManager } from './context-manager.js'; import { generateHookTestPayload, parseResponse } from './utils.js'; const { jest } = import.meta; @@ -29,26 +30,39 @@ const { sendWebhookRequest } = mockEsm('./utils.js', () => ({ const { MockQueries } = await import('#src/test-utils/tenant.js'); const url = 'https://logto.gg'; + const hook: Hook = { tenantId: 'bar', id: 'foo', name: 'hook_name', - event: HookEvent.PostSignIn, - events: [HookEvent.PostSignIn], + event: InteractionHookEvent.PostSignIn, + events: [InteractionHookEvent.PostSignIn], signingKey: 'signing_key', enabled: true, config: { headers: { bar: 'baz' }, url, retries: 3 }, createdAt: Date.now() / 1000, }; +const dataHook: Hook = { + tenantId: 'bar', + id: 'foo', + name: 'hook_name', + event: 'Role.Created', + events: ['Role.Created'], + enabled: true, + signingKey: 'signing_key', + config: { headers: { bar: 'baz' }, url, retries: 3 }, + createdAt: Date.now() / 1000, +}; + const insertLog = jest.fn(); const mockHookState = { requestCount: 100, successCount: 10 }; const getHookExecutionStatsByHookId = jest.fn().mockResolvedValue(mockHookState); -const findAllHooks = jest.fn().mockResolvedValue([hook]); +const findAllHooks = jest.fn().mockResolvedValue([hook, dataHook]); const findHookById = jest.fn().mockResolvedValue(hook); const { createHookLibrary } = await import('./index.js'); -const { triggerInteractionHooks, testHook } = createHookLibrary( +const { triggerInteractionHooks, triggerTestHook, triggerDataHooks } = createHookLibrary( new MockQueries({ users: { findUserById: jest.fn().mockReturnValue({ @@ -97,10 +111,13 @@ describe('triggerInteractionHooks()', () => { const calledPayload: unknown = insertLog.mock.calls[0][0]; expect(calledPayload).toHaveProperty('id', mockId); - expect(calledPayload).toHaveProperty('key', 'TriggerHook.' + HookEvent.PostSignIn); + expect(calledPayload).toHaveProperty('key', 'TriggerHook.' + InteractionHookEvent.PostSignIn); expect(calledPayload).toHaveProperty('payload.result', LogResult.Success); expect(calledPayload).toHaveProperty('payload.hookId', 'foo'); - expect(calledPayload).toHaveProperty('payload.hookRequest.body.event', HookEvent.PostSignIn); + expect(calledPayload).toHaveProperty( + 'payload.hookRequest.body.event', + InteractionHookEvent.PostSignIn + ); expect(calledPayload).toHaveProperty( 'payload.hookRequest.body.interactionEvent', InteractionEvent.SignIn @@ -113,7 +130,7 @@ describe('triggerInteractionHooks()', () => { }); }); -describe('testHook', () => { +describe('triggerTestHook', () => { afterEach(() => { jest.clearAllMocks(); }); @@ -121,11 +138,14 @@ describe('testHook', () => { it('should call sendWebhookRequest with correct values', async () => { jest.useFakeTimers().setSystemTime(100_000); - await testHook(hook.id, [HookEvent.PostSignIn], hook.config); - const testHookPayload = generateHookTestPayload(hook.id, HookEvent.PostSignIn); + await triggerTestHook(hook.id, [InteractionHookEvent.PostSignIn], hook.config); + const triggerTestHookPayload = generateHookTestPayload( + hook.id, + InteractionHookEvent.PostSignIn + ); expect(sendWebhookRequest).toHaveBeenCalledWith({ hookConfig: hook.config, - payload: testHookPayload, + payload: triggerTestHookPayload, signingKey: hook.signingKey, }); @@ -133,13 +153,19 @@ describe('testHook', () => { }); it('should call sendWebhookRequest with correct times if multiple events are provided', async () => { - await testHook(hook.id, [HookEvent.PostSignIn, HookEvent.PostResetPassword], hook.config); + await triggerTestHook( + hook.id, + [InteractionHookEvent.PostSignIn, InteractionHookEvent.PostResetPassword], + hook.config + ); expect(sendWebhookRequest).toBeCalledTimes(2); }); it('should throw send test payload failed error if sendWebhookRequest fails', async () => { sendWebhookRequest.mockRejectedValueOnce(new Error('test error')); - await expect(testHook(hook.id, [HookEvent.PostSignIn], hook.config)).rejects.toThrowError( + await expect( + triggerTestHook(hook.id, [InteractionHookEvent.PostSignIn], hook.config) + ).rejects.toThrowError( new RequestError({ code: 'hook.send_test_payload_failed', message: 'Error: test error', @@ -148,3 +174,62 @@ describe('testHook', () => { ); }); }); + +describe('triggerDataHooks()', () => { + afterEach(() => { + jest.clearAllMocks(); + }); + + it('should set correct payload when hook triggered', async () => { + jest.useFakeTimers().setSystemTime(100_000); + + const metadata = { userAgent: 'ua', ip: 'ip' }; + const hookData = { path: '/test', method: 'POST', body: { success: true } }; + + const hooksManager = new DataHookContextManager(metadata); + hooksManager.appendContext({ + event: 'Role.Created', + data: hookData, + }); + + await triggerDataHooks(new ConsoleLog(), hooksManager); + + expect(findAllHooks).toHaveBeenCalled(); + + expect(sendWebhookRequest).toHaveBeenCalledWith({ + hookConfig: dataHook.config, + payload: { + hookId: 'foo', + event: 'Role.Created', + createdAt: new Date(100_000).toISOString(), + ...hookData, + ...metadata, + }, + signingKey: dataHook.signingKey, + }); + + const calledPayload: unknown = insertLog.mock.calls[0][0]; + + expect(calledPayload).toMatchObject({ + id: mockId, + key: 'TriggerHook.Role.Created', + payload: { + result: LogResult.Success, + hookId: 'foo', + hookRequest: { + body: { + event: 'Role.Created', + hookId: 'foo', + ...hookData, + }, + }, + response: { + statusCode: 200, + body: { message: 'ok' }, + }, + }, + }); + + jest.useRealTimers(); + }); +}); diff --git a/packages/core/src/libraries/hook/index.ts b/packages/core/src/libraries/hook/index.ts index c6a88960795..b7634e72af6 100644 --- a/packages/core/src/libraries/hook/index.ts +++ b/packages/core/src/libraries/hook/index.ts @@ -1,48 +1,36 @@ import { - HookEvent, - type HookEventPayload, - InteractionEvent, LogResult, userInfoSelectFields, + type DataHookEventPayload, + type Hook, type HookConfig, + type HookEvent, + type HookEventPayload, type HookTestErrorResponseData, + type InteractionHookEventPayload, } from '@logto/schemas'; -import { type ConsoleLog, generateStandardId } from '@logto/shared'; +import { generateStandardId, normalizeError, type ConsoleLog } from '@logto/shared'; import { conditional, pick, trySafe } from '@silverhand/essentials'; import { HTTPError } from 'ky'; +import pMap from 'p-map'; import RequestError from '#src/errors/RequestError/index.js'; import { LogEntry } from '#src/middleware/koa-audit-log.js'; import type Queries from '#src/tenants/Queries.js'; +import { type DataHookContextManager } from './context-manager.js'; +import { + interactionEventToHookEvent, + type InteractionHookContext, + type InteractionHookResult, +} from './types.js'; import { generateHookTestPayload, parseResponse, sendWebhookRequest } from './utils.js'; -/** - * The context for triggering interaction hooks by `triggerInteractionHooks`. - * In the `koaInteractionHooks` middleware, - * we will store the context before processing the interaction and consume it after the interaction is processed if needed. - */ -export type InteractionHookContext = { - event: InteractionEvent; - sessionId?: string; - applicationId?: string; - userIp?: string; +type BetterOmit = { + [key in keyof T as key extends Ignore ? never : key]: T[key]; }; -/** - * The interaction hook result for triggering interaction hooks by `triggerInteractionHooks`. - * In the `koaInteractionHooks` middleware, - * if we get an interaction hook result after the interaction is processed, related hooks will be triggered. - */ -export type InteractionHookResult = { - userId: string; -}; - -const eventToHook: Record = { - [InteractionEvent.Register]: HookEvent.PostRegister, - [InteractionEvent.SignIn]: HookEvent.PostSignIn, - [InteractionEvent.ForgotPassword]: HookEvent.PostResetPassword, -}; +type HookEventPayloadWithoutHookId = BetterOmit; export const createHookLibrary = (queries: Queries) => { const { @@ -53,6 +41,66 @@ export const createHookLibrary = (queries: Queries) => { hooks: { findAllHooks, findHookById }, } = queries; + /** + * Trigger web hook with the given payload and create a log entry for the request and response. + */ + const sendWebhook = async ( + hook: Hook, + payload: HookEventPayloadWithoutHookId, + consoleLog: ConsoleLog + ) => { + const { id, config, signingKey } = hook; + consoleLog.info(`\tTriggering hook ${id} due to ${payload.event} event`); + + const json: HookEventPayload = { ...payload, hookId: id }; + const logEntry = new LogEntry(`TriggerHook.${payload.event}`); + + logEntry.append({ hookId: id, hookRequest: { body: json } }); + + // Trigger web hook and log response + try { + const response = await sendWebhookRequest({ + hookConfig: config, + payload: json, + signingKey, + }); + + logEntry.append({ + response: await parseResponse(response), + }); + } catch (error: unknown) { + logEntry.append({ + result: LogResult.Error, + response: conditional(error instanceof HTTPError && (await parseResponse(error.response))), + error: String(normalizeError(error)), + }); + } + + consoleLog.info( + `\tHook ${id} ${logEntry.payload.result === LogResult.Success ? 'succeeded' : 'failed'}` + ); + + await insertLog({ + id: generateStandardId(), + key: logEntry.key, + payload: logEntry.payload, + }); + }; + + /** + * Trigger multiple web hooks with concurrency control. + */ + const sendWebhooks = async ( + webhooks: Array<{ hook: Hook; payload: T }>, + consoleLog: ConsoleLog + ) => + pMap(webhooks, async ({ hook, payload }) => sendWebhook(hook, payload, consoleLog), { + concurrency: 10, + }); + + /** + * Trigger interaction hooks with the given interaction context and result. + */ const triggerInteractionHooks = async ( consoleLog: ConsoleLog, interactionContext: InteractionHookContext, @@ -62,14 +110,14 @@ export const createHookLibrary = (queries: Queries) => { const { userId } = interactionResult; const { event, sessionId, applicationId, userIp } = interactionContext; - const hookEvent = eventToHook[event]; + const hookEvent = interactionEventToHookEvent[event]; const found = await findAllHooks(); - const rows = found.filter( + const hooks = found.filter( ({ event, events, enabled }) => enabled && (events.length > 0 ? events.includes(hookEvent) : event === hookEvent) // For backward compatibility ); - if (rows.length === 0) { + if (hooks.length === 0) { return; } @@ -88,51 +136,48 @@ export const createHookLibrary = (queries: Queries) => { userIp, user: user && pick(user, ...userInfoSelectFields), application: application && pick(application, 'id', 'type', 'name', 'description'), - } satisfies Omit; + } satisfies BetterOmit; + + await sendWebhooks( + hooks.map((hook) => ({ hook, payload })), + consoleLog + ); + }; + + /** + * Trigger data hooks with the given data mutation context. All context objects will be used to trigger hooks. + */ + const triggerDataHooks = async ( + consoleLog: ConsoleLog, + contextManager: DataHookContextManager + ) => { + if (contextManager.contextArray.length === 0) { + return; + } - await Promise.all( - rows.map(async ({ id, config, signingKey }) => { - consoleLog.info(`\tTriggering hook ${id} due to ${hookEvent} event`); - const json: HookEventPayload = { hookId: id, ...payload }; - const logEntry = new LogEntry(`TriggerHook.${hookEvent}`); + const found = await findAllHooks(); - logEntry.append({ hookId: id, hookRequest: { body: json } }); + // Filter hooks that match each events + const webhooks = contextManager.contextArray.flatMap(({ event, data }) => { + const hooks = found.filter( + ({ event: hookEvent, events, enabled }) => + enabled && (events.length > 0 ? events.includes(event) : event === hookEvent) + ); - // Trigger web hook and log response - await sendWebhookRequest({ - hookConfig: config, - payload: json, - signingKey, - }) - .then(async (response) => { - logEntry.append({ - response: await parseResponse(response), - }); - }) - .catch(async (error) => { - logEntry.append({ - result: LogResult.Error, - response: conditional( - error instanceof HTTPError && (await parseResponse(error.response)) - ), - error: conditional(error instanceof Error && String(error)), - }); - }); + const payload = { + event, + createdAt: new Date().toISOString(), + ...contextManager.metadata, + ...data, + } satisfies BetterOmit; - consoleLog.info( - `\tHook ${id} ${logEntry.payload.result === LogResult.Success ? 'succeeded' : 'failed'}` - ); + return hooks.map((hook) => ({ hook, payload })); + }); - await insertLog({ - id: generateStandardId(), - key: logEntry.key, - payload: logEntry.payload, - }); - }) - ); + await sendWebhooks(webhooks, consoleLog); }; - const testHook = async (hookId: string, events: HookEvent[], config: HookConfig) => { + const triggerTestHook = async (hookId: string, events: HookEvent[], config: HookConfig) => { const { signingKey } = await findHookById(hookId); try { await Promise.all( @@ -169,6 +214,7 @@ export const createHookLibrary = (queries: Queries) => { return { triggerInteractionHooks, - testHook, + triggerDataHooks, + triggerTestHook, }; }; diff --git a/packages/core/src/libraries/hook/types.ts b/packages/core/src/libraries/hook/types.ts new file mode 100644 index 00000000000..f7721de0d26 --- /dev/null +++ b/packages/core/src/libraries/hook/types.ts @@ -0,0 +1,28 @@ +import { InteractionEvent, InteractionHookEvent } from '@logto/schemas'; + +/** + * The context for triggering interaction hooks by `triggerInteractionHooks`. + * In the `koaInteractionHooks` middleware, + * we will store the context before processing the interaction and consume it after the interaction is processed if needed. + */ +export type InteractionHookContext = { + event: InteractionEvent; + sessionId?: string; + applicationId?: string; + userIp?: string; +}; + +/** + * The interaction hook result for triggering interaction hooks by `triggerInteractionHooks`. + * In the `koaInteractionHooks` middleware, + * if we get an interaction hook result after the interaction is processed, related hooks will be triggered. + */ +export type InteractionHookResult = { + userId: string; +}; + +export const interactionEventToHookEvent: Record = { + [InteractionEvent.Register]: InteractionHookEvent.PostRegister, + [InteractionEvent.SignIn]: InteractionHookEvent.PostSignIn, + [InteractionEvent.ForgotPassword]: InteractionHookEvent.PostResetPassword, +}; diff --git a/packages/core/src/libraries/hook/utils.test.ts b/packages/core/src/libraries/hook/utils.test.ts index e59feb38472..8112592b34d 100644 --- a/packages/core/src/libraries/hook/utils.test.ts +++ b/packages/core/src/libraries/hook/utils.test.ts @@ -1,4 +1,4 @@ -import { HookEvent } from '@logto/schemas'; +import { type HookEvent, InteractionHookEvent } from '@logto/schemas'; import { createMockUtils } from '@logto/shared/esm'; import ky from 'ky'; @@ -21,7 +21,7 @@ const { generateHookTestPayload, sendWebhookRequest } = await import('./utils.js describe('sendWebhookRequest', () => { it('should call got.post with correct values', async () => { const mockHookId = 'mockHookId'; - const mockEvent: HookEvent = HookEvent.PostSignIn; + const mockEvent: HookEvent = InteractionHookEvent.PostSignIn; const testPayload = generateHookTestPayload(mockHookId, mockEvent); const mockUrl = 'https://logto.gg'; diff --git a/packages/core/src/libraries/hook/utils.ts b/packages/core/src/libraries/hook/utils.ts index f07f375e4c5..e28732f1a2f 100644 --- a/packages/core/src/libraries/hook/utils.ts +++ b/packages/core/src/libraries/hook/utils.ts @@ -1,10 +1,12 @@ import { - type HookEvent, - type HookEventPayload, ApplicationType, + managementApiHooksRegistration, type HookConfig, + type HookEvent, + type HookEventPayload, } from '@logto/schemas'; import { conditional, trySafe } from '@silverhand/essentials'; +import { type IRouterParamContext } from 'koa-router'; import ky, { type KyResponse } from 'ky'; import { sign } from '#src/utils/sign.js'; @@ -83,3 +85,12 @@ export const generateHookTestPayload = (hookId: string, event: HookEvent): HookE }, }; }; + +export const buildManagementApiDataHookRegistrationKey = ( + method: string, + route: IRouterParamContext['_matchedRoute'] +) => `${method} ${route}`; + +export const hasRegisteredDataHookEvent = ( + key: string +): key is keyof typeof managementApiHooksRegistration => key in managementApiHooksRegistration; diff --git a/packages/core/src/middleware/koa-management-api-hooks.test.ts b/packages/core/src/middleware/koa-management-api-hooks.test.ts new file mode 100644 index 00000000000..eba7130c592 --- /dev/null +++ b/packages/core/src/middleware/koa-management-api-hooks.test.ts @@ -0,0 +1,95 @@ +import { managementApiHooksRegistration } from '@logto/schemas'; +import { ConsoleLog } from '@logto/shared'; +import { type ParameterizedContext } from 'koa'; + +import type Libraries from '#src/tenants/Libraries.js'; +import { createContextWithRouteParameters } from '#src/utils/test-utils.js'; + +import { koaManagementApiHooks, type WithHookContext } from './koa-management-api-hooks.js'; + +const { jest } = import.meta; + +const notToBeCalled = () => { + throw new Error('Should not be called'); +}; + +describe('koaManagementApiHooks', () => { + const next = jest.fn(); + const triggerDataHooks = jest.fn(); + // @ts-expect-error mock + const mockHooksLibrary: Libraries['hooks'] = { + triggerDataHooks, + }; + + it("should do nothing if there's no hook context", async () => { + const ctx = { + ...createContextWithRouteParameters(), + header: {}, + appendDataHookContext: notToBeCalled, + }; + await koaManagementApiHooks(mockHooksLibrary)(ctx, next); + expect(triggerDataHooks).not.toBeCalled(); + }); + + it('should trigger management hooks', async () => { + const ctx: ParameterizedContext = { + ...createContextWithRouteParameters(), + header: {}, + appendDataHookContext: notToBeCalled, + }; + next.mockImplementation(() => { + ctx.appendDataHookContext({ event: 'Role.Created', data: { id: '123' } }); + }); + + await koaManagementApiHooks(mockHooksLibrary)(ctx, next); + expect(triggerDataHooks).toBeCalledTimes(1); + expect(triggerDataHooks).toBeCalledWith( + expect.any(ConsoleLog), + expect.objectContaining({ + contextArray: [ + { + event: 'Role.Created', + data: { id: '123' }, + }, + ], + }) + ); + }); + + describe('auto append pre-registered management API hooks', () => { + beforeEach(() => { + jest.clearAllMocks(); + }); + + const events = Object.entries(managementApiHooksRegistration); + + it.each(events)('should append hook context for %s', async (key, event) => { + const [method, route] = key.split(' ') as [string, string]; + + const ctx: ParameterizedContext = { + ...createContextWithRouteParameters(), + header: {}, + appendDataHookContext: notToBeCalled, + method, + _matchedRoute: route, + path: route, + body: { key }, + status: 200, + }; + + await koaManagementApiHooks(mockHooksLibrary)(ctx, next); + + expect(triggerDataHooks).toBeCalledWith( + expect.any(ConsoleLog), + expect.objectContaining({ + contextArray: [ + { + event, + data: { path: route, method, body: { key }, status: 200 }, + }, + ], + }) + ); + }); + }); +}); diff --git a/packages/core/src/middleware/koa-management-api-hooks.ts b/packages/core/src/middleware/koa-management-api-hooks.ts new file mode 100644 index 00000000000..f941d8f40bb --- /dev/null +++ b/packages/core/src/middleware/koa-management-api-hooks.ts @@ -0,0 +1,66 @@ +import { managementApiHooksRegistration } from '@logto/schemas'; +import { trySafe } from '@silverhand/essentials'; +import { type MiddlewareType } from 'koa'; +import { type IRouterParamContext } from 'koa-router'; + +import { EnvSet } from '#src/env-set/index.js'; +import { DataHookContextManager } from '#src/libraries/hook/context-manager.js'; +import { + buildManagementApiDataHookRegistrationKey, + hasRegisteredDataHookEvent, +} from '#src/libraries/hook/utils.js'; +import type Libraries from '#src/tenants/Libraries.js'; +import { getConsoleLogFromContext } from '#src/utils/console.js'; + +export type WithHookContext = + ContextT & { appendDataHookContext: DataHookContextManager['appendContext'] }; + +/** + * The factory to create a new management hook middleware function. + * + * To trigger management hooks, use `appendDataHookContext` to append the context. + * + * @param hooks The hooks library. + * @returns The middleware function. + */ +export const koaManagementApiHooks = ( + hooks: Libraries['hooks'] +): MiddlewareType, ResponseT> => { + return async (ctx, next) => { + // TODO: Remove dev feature guard + const { isDevFeaturesEnabled } = EnvSet.values; + if (!isDevFeaturesEnabled) { + return; + } + + const { + header: { 'user-agent': userAgent }, + ip, + } = ctx; + + const dataHooks = new DataHookContextManager({ userAgent, ip }); + + /** + * Append a hook context to trigger management hooks. If multiple contexts are appended, all of + * them will be triggered. + */ + ctx.appendDataHookContext = dataHooks.appendContext.bind(dataHooks); + + await next(); + + // Auto append pre-registered management API hooks if any + const { path, method, body, status, _matchedRoute } = ctx; + const hookRegistrationKey = buildManagementApiDataHookRegistrationKey(method, _matchedRoute); + + // TODO: @simeng-li do we need to insert the request body to the hook context? + if (hasRegisteredDataHookEvent(hookRegistrationKey)) { + const event = managementApiHooksRegistration[hookRegistrationKey]; + dataHooks.appendContext({ event, data: { path, method, body, status } }); + } + + if (dataHooks.contextArray.length > 0) { + // Hooks should not crash the app + void trySafe(hooks.triggerDataHooks(getConsoleLogFromContext(ctx), dataHooks)); + } + }; +}; diff --git a/packages/core/src/routes/hook.test.ts b/packages/core/src/routes/hook.test.ts index 765620bfadf..0b379fef6ac 100644 --- a/packages/core/src/routes/hook.test.ts +++ b/packages/core/src/routes/hook.test.ts @@ -1,12 +1,12 @@ import { - HookEvent, + InteractionHookEvent, + LogResult, + hook, + type CreateHook, type Hook, - type HookEvents, type HookConfig, - type CreateHook, - LogResult, + type HookEvents, type Log, - hook, } from '@logto/schemas'; import { pickDefault } from '@logto/shared/esm'; import { subDays } from 'date-fns'; @@ -76,10 +76,10 @@ const mockQueries = { logs, }; -const testHook = jest.fn(); +const triggerTestHook = jest.fn(); const mockLibraries = { - hooks: { testHook }, + hooks: { triggerTestHook }, quota: createMockQuotaLibrary(), }; @@ -165,7 +165,7 @@ describe('hook routes', () => { it('POST /hooks', async () => { const name = 'fooName'; - const events: HookEvents = [HookEvent.PostRegister]; + const events: HookEvents = [InteractionHookEvent.PostRegister]; const config: HookConfig = { url: 'https://example.com', }; @@ -187,7 +187,7 @@ describe('hook routes', () => { it('POST /hooks should be able to create a hook with multi events', async () => { const name = 'anyName'; - const events: HookEvents = [HookEvent.PostSignIn, HookEvent.PostRegister]; + const events: HookEvents = [InteractionHookEvent.PostSignIn, InteractionHookEvent.PostRegister]; const config: HookConfig = { url: 'https://example.com', }; @@ -219,7 +219,7 @@ describe('hook routes', () => { it('POST /hooks should success when create a hook with the old payload format', async () => { const payload: Partial = { - event: HookEvent.PostRegister, + event: InteractionHookEvent.PostRegister, config: { url: 'https://example.com', retries: 2, @@ -232,7 +232,7 @@ describe('hook routes', () => { expect(response.body).toMatchObject({ tenantId: mockTenantIdForHook, id: generatedId, - event: HookEvent.PostRegister, + event: InteractionHookEvent.PostRegister, config: { url: 'https://example.com', retries: 2, @@ -243,7 +243,7 @@ describe('hook routes', () => { it('POST /hooks/:id/test should return 204 if test is successful', async () => { const targetMockHook = mockHookList[0] ?? mockHook; const response = await hookRequest.post(`/hooks/${targetMockHook.id}/test`).send({ - events: [HookEvent.PostRegister], + events: [InteractionHookEvent.PostRegister], config: { url: 'https://example.com' }, }); expect(response.status).toEqual(204); @@ -252,7 +252,7 @@ describe('hook routes', () => { it('PATCH /hooks/:id', async () => { const targetMockHook = mockHookList[0] ?? mockHook; const name = 'newName'; - const events: HookEvents = [HookEvent.PostSignIn]; + const events: HookEvents = [InteractionHookEvent.PostSignIn]; const config: HookConfig = { url: 'https://new.com', }; @@ -272,7 +272,7 @@ describe('hook routes', () => { it('PATCH /hooks/:id should success when update a hook with multi events', async () => { const targetMockHook = mockHookList[0] ?? mockHook; - const events = [HookEvent.PostSignIn, HookEvent.PostResetPassword]; + const events = [InteractionHookEvent.PostSignIn, InteractionHookEvent.PostResetPassword]; const response = await hookRequest.patch(`/hooks/${targetMockHook.id}`).send({ events }); expect(response.status).toEqual(200); @@ -283,7 +283,7 @@ describe('hook routes', () => { it('PATCH /hooks/:id should success when update a hook with the old payload format', async () => { const targetMockHook = mockHookList[0] ?? mockHook; - const event = HookEvent.PostSignIn; + const event = InteractionHookEvent.PostSignIn; const response = await hookRequest.patch(`/hooks/${targetMockHook.id}`).send({ event, config: { @@ -303,7 +303,7 @@ describe('hook routes', () => { }); it('PATCH /hooks/:id with empty events list should fail', async () => { - const invalidEvents: HookEvent[] = []; + const invalidEvents: InteractionHookEvent[] = []; const response = await hookRequest .patch(`/hooks/${mockNanoIdForHook}`) .send({ events: invalidEvents }); diff --git a/packages/core/src/routes/hook.ts b/packages/core/src/routes/hook.ts index 8e87c162123..a57c0732132 100644 --- a/packages/core/src/routes/hook.ts +++ b/packages/core/src/routes/hook.ts @@ -1,12 +1,12 @@ import { Hooks, Logs, + hook, hookConfigGuard, hookEventsGuard, hookResponseGuard, - hook, - type HookResponse, type Hook, + type HookResponse, } from '@logto/schemas'; import { generateStandardId, generateStandardSecret } from '@logto/shared'; import { conditional, deduplicate, yes } from '@silverhand/essentials'; @@ -42,7 +42,7 @@ export default function hookRoutes( } = queries; const { - hooks: { testHook }, + hooks: { triggerTestHook }, quota, } = libraries; @@ -196,7 +196,7 @@ export default function hookRoutes( body: { events, config }, } = ctx.guard; - await testHook(id, events, config); + await triggerTestHook(id, events, config); ctx.status = 204; diff --git a/packages/core/src/routes/init.ts b/packages/core/src/routes/init.ts index 0ab14e1e9ff..d5f25b16b30 100644 --- a/packages/core/src/routes/init.ts +++ b/packages/core/src/routes/init.ts @@ -5,6 +5,7 @@ import Router from 'koa-router'; import { EnvSet } from '#src/env-set/index.js'; import koaBodyEtag from '#src/middleware/koa-body-etag.js'; import koaCors from '#src/middleware/koa-cors.js'; +import { koaManagementApiHooks } from '#src/middleware/koa-management-api-hooks.js'; import koaTenantGuard from '#src/middleware/koa-tenant-guard.js'; import type TenantContext from '#src/tenants/TenantContext.js'; @@ -48,6 +49,7 @@ const createRouters = (tenant: TenantContext) => { const managementRouter: ManagementApiRouter = new Router(); managementRouter.use(koaAuth(tenant.envSet, getManagementApiResourceIndicator(tenant.id))); managementRouter.use(koaTenantGuard(tenant.id, tenant.queries)); + managementRouter.use(koaManagementApiHooks(tenant.libraries.hooks)); applicationRoutes(managementRouter, tenant); applicationRoleRoutes(managementRouter, tenant); diff --git a/packages/core/src/routes/interaction/middleware/koa-interaction-hooks.ts b/packages/core/src/routes/interaction/middleware/koa-interaction-hooks.ts index c8e7424f290..2f0a5d96dd1 100644 --- a/packages/core/src/routes/interaction/middleware/koa-interaction-hooks.ts +++ b/packages/core/src/routes/interaction/middleware/koa-interaction-hooks.ts @@ -1,11 +1,11 @@ -import { type Optional, trySafe, conditionalString } from '@silverhand/essentials'; +import { conditionalString, trySafe, type Optional } from '@silverhand/essentials'; import type { MiddlewareType } from 'koa'; import type { IRouterParamContext } from 'koa-router'; import { type InteractionHookContext, type InteractionHookResult, -} from '#src/libraries/hook/index.js'; +} from '#src/libraries/hook/types.js'; import type Libraries from '#src/tenants/Libraries.js'; import { getConsoleLogFromContext } from '#src/utils/console.js'; @@ -33,6 +33,7 @@ export default function koaInteractionHooks< }: Libraries): MiddlewareType, ResponseT> { return async (ctx, next) => { const { event } = getInteractionStorage(ctx.interactionDetails.result); + const { interactionDetails, header: { 'user-agent': userAgent }, @@ -60,6 +61,8 @@ export default function koaInteractionHooks< interactionHookResult = result; }; + // TODO: @simeng-li Add DataHookContext to the interaction hook middleware as well + await next(); if (interactionHookResult) { diff --git a/packages/core/src/routes/types.ts b/packages/core/src/routes/types.ts index 2eb5bcb5a84..398af97c500 100644 --- a/packages/core/src/routes/types.ts +++ b/packages/core/src/routes/types.ts @@ -4,6 +4,7 @@ import type Router from 'koa-router'; import type { WithLogContext } from '#src/middleware/koa-audit-log.js'; import type { WithAuthContext } from '#src/middleware/koa-auth/index.js'; import type { WithI18nContext } from '#src/middleware/koa-i18next.js'; +import { type WithHookContext } from '#src/middleware/koa-management-api-hooks.js'; import type TenantContext from '#src/tenants/TenantContext.js'; export type AnonymousRouter = Router; @@ -11,6 +12,7 @@ export type AnonymousRouter = Router; type ManagementApiRouterContext = WithAuthContext & WithLogContext & WithI18nContext & + WithHookContext & ExtendableContext; export type ManagementApiRouter = Router; diff --git a/packages/integration-tests/src/tests/api/hook/hook.stats.test.ts b/packages/integration-tests/src/tests/api/hook/hook.stats.test.ts index 39bebae951d..331a38ce0b6 100644 --- a/packages/integration-tests/src/tests/api/hook/hook.stats.test.ts +++ b/packages/integration-tests/src/tests/api/hook/hook.stats.test.ts @@ -1,10 +1,10 @@ import { type Hook, - HookEvent, type HookResponse, type Log, LogResult, SignInIdentifier, + InteractionHookEvent, } from '@logto/schemas'; import { deleteUser } from '#src/api/admin-user.js'; @@ -34,7 +34,7 @@ describe('hook logs', () => { it('should get recent hook logs correctly', async () => { const createdHook = await authedAdminApi .post('hooks', { - json: getHookCreationPayload(HookEvent.PostRegister, 'http://localhost:9999'), + json: getHookCreationPayload(InteractionHookEvent.PostRegister, 'http://localhost:9999'), }) .json(); @@ -59,7 +59,7 @@ describe('hook logs', () => { it('should get hook execution stats correctly', async () => { const createdHook = await authedAdminApi .post('hooks', { - json: getHookCreationPayload(HookEvent.PostRegister, 'http://localhost:9999'), + json: getHookCreationPayload(InteractionHookEvent.PostRegister, 'http://localhost:9999'), }) .json(); diff --git a/packages/integration-tests/src/tests/api/hook/hook.test.ts b/packages/integration-tests/src/tests/api/hook/hook.test.ts index 4f018dab903..5874671f193 100644 --- a/packages/integration-tests/src/tests/api/hook/hook.test.ts +++ b/packages/integration-tests/src/tests/api/hook/hook.test.ts @@ -1,5 +1,5 @@ import type { Hook } from '@logto/schemas'; -import { HookEvent } from '@logto/schemas'; +import { InteractionHookEvent } from '@logto/schemas'; import { authedAdminApi } from '#src/api/index.js'; import { getHookCreationPayload } from '#src/helpers/hook.js'; @@ -7,7 +7,7 @@ import { expectRejects } from '#src/helpers/index.js'; describe('hooks', () => { it('should be able to create, query, update, and delete a hook', async () => { - const payload = getHookCreationPayload(HookEvent.PostRegister); + const payload = getHookCreationPayload(InteractionHookEvent.PostRegister); const created = await authedAdminApi.post('hooks', { json: payload }).json(); expect(created).toMatchObject(payload); @@ -16,9 +16,9 @@ describe('hooks', () => { expect(await authedAdminApi.get(`hooks/${created.id}`).json()).toEqual(created); expect( await authedAdminApi - .patch(`hooks/${created.id}`, { json: { events: [HookEvent.PostSignIn] } }) + .patch(`hooks/${created.id}`, { json: { events: [InteractionHookEvent.PostSignIn] } }) .json() - ).toMatchObject({ ...created, events: [HookEvent.PostSignIn] }); + ).toMatchObject({ ...created, events: [InteractionHookEvent.PostSignIn] }); expect(await authedAdminApi.delete(`hooks/${created.id}`)).toHaveProperty('status', 204); await expectRejects(authedAdminApi.get(`hooks/${created.id}`), { code: 'entity.not_exists_with_id', @@ -28,7 +28,7 @@ describe('hooks', () => { it('should be able to create, query, update, and delete a hook by the original API', async () => { const payload = { - event: HookEvent.PostRegister, + event: InteractionHookEvent.PostRegister, config: { url: 'not_work_url', retries: 2, @@ -42,11 +42,11 @@ describe('hooks', () => { expect(await authedAdminApi.get(`hooks/${created.id}`).json()).toEqual(created); expect( await authedAdminApi - .patch(`hooks/${created.id}`, { json: { event: HookEvent.PostSignIn } }) + .patch(`hooks/${created.id}`, { json: { event: InteractionHookEvent.PostSignIn } }) .json() ).toMatchObject({ ...created, - event: HookEvent.PostSignIn, + event: InteractionHookEvent.PostSignIn, }); expect(await authedAdminApi.delete(`hooks/${created.id}`)).toHaveProperty('status', 204); await expectRejects(authedAdminApi.get(`hooks/${created.id}`), { @@ -56,7 +56,7 @@ describe('hooks', () => { }); it('should return hooks with pagination if pagination-related query params are provided', async () => { - const payload = getHookCreationPayload(HookEvent.PostRegister); + const payload = getHookCreationPayload(InteractionHookEvent.PostRegister); const created = await authedAdminApi.post('hooks', { json: payload }).json(); const response = await authedAdminApi.get('hooks?page=1&page_size=20'); @@ -71,7 +71,7 @@ describe('hooks', () => { it('should throw error when creating a hook with an empty hook name', async () => { const payload = { name: '', - events: [HookEvent.PostRegister], + events: [InteractionHookEvent.PostRegister], config: { url: 'not_work_url', }, diff --git a/packages/integration-tests/src/tests/api/hook/hook.testing.test.ts b/packages/integration-tests/src/tests/api/hook/hook.testing.test.ts index d4c3d180e67..82ff79a514c 100644 --- a/packages/integration-tests/src/tests/api/hook/hook.testing.test.ts +++ b/packages/integration-tests/src/tests/api/hook/hook.testing.test.ts @@ -1,4 +1,4 @@ -import { HookEvent, type Hook } from '@logto/schemas'; +import { InteractionHookEvent, type Hook } from '@logto/schemas'; import { authedAdminApi } from '#src/api/api.js'; import { getHookCreationPayload } from '#src/helpers/hook.js'; @@ -32,10 +32,13 @@ describe('hook testing', () => { }); it('should return 204 if test hook successfully', async () => { - const payload = getHookCreationPayload(HookEvent.PostRegister, responseSuccessEndpoint); + const payload = getHookCreationPayload( + InteractionHookEvent.PostRegister, + responseSuccessEndpoint + ); const created = await authedAdminApi.post('hooks', { json: payload }).json(); const response = await authedAdminApi.post(`hooks/${created.id}/test`, { - json: { events: [HookEvent.PostSignIn], config: { url: responseSuccessEndpoint } }, + json: { events: [InteractionHookEvent.PostSignIn], config: { url: responseSuccessEndpoint } }, }); expect(response.status).toBe(204); @@ -47,7 +50,10 @@ describe('hook testing', () => { const invalidHookId = 'invalid_id'; await expectRejects( authedAdminApi.post(`hooks/${invalidHookId}/test`, { - json: { events: [HookEvent.PostSignIn], config: { url: responseSuccessEndpoint } }, + json: { + events: [InteractionHookEvent.PostSignIn], + config: { url: responseSuccessEndpoint }, + }, }), { code: 'entity.not_exists_with_id', @@ -57,11 +63,11 @@ describe('hook testing', () => { }); it('should return 422 if the hook endpoint is not working', async () => { - const payload = getHookCreationPayload(HookEvent.PostRegister); + const payload = getHookCreationPayload(InteractionHookEvent.PostRegister); const created = await authedAdminApi.post('hooks', { json: payload }).json(); await expectRejects( authedAdminApi.post(`hooks/${created.id}/test`, { - json: { events: [HookEvent.PostSignIn], config: { url: 'not_work_url' } }, + json: { events: [InteractionHookEvent.PostSignIn], config: { url: 'not_work_url' } }, }), { code: 'hook.send_test_payload_failed', @@ -74,11 +80,11 @@ describe('hook testing', () => { }); it('should return 422 and contains endpoint response if the hook endpoint return 500', async () => { - const payload = getHookCreationPayload(HookEvent.PostRegister); + const payload = getHookCreationPayload(InteractionHookEvent.PostRegister); const created = await authedAdminApi.post('hooks', { json: payload }).json(); await expectRejects( authedAdminApi.post(`hooks/${created.id}/test`, { - json: { events: [HookEvent.PostSignIn], config: { url: responseErrorEndpoint } }, + json: { events: [InteractionHookEvent.PostSignIn], config: { url: responseErrorEndpoint } }, }), { code: 'hook.endpoint_responded_with_error', diff --git a/packages/integration-tests/src/tests/api/hook/hook.trigger.test.ts b/packages/integration-tests/src/tests/api/hook/hook.trigger.test.ts index eadc336a9a7..0ea20f897c4 100644 --- a/packages/integration-tests/src/tests/api/hook/hook.trigger.test.ts +++ b/packages/integration-tests/src/tests/api/hook/hook.trigger.test.ts @@ -2,13 +2,14 @@ import { createHmac } from 'node:crypto'; import { type RequestListener } from 'node:http'; import { - type Hook, - HookEvent, - type LogKey, + ConnectorType, + InteractionHookEvent, LogResult, SignInIdentifier, + type Hook, type Log, - ConnectorType, + type LogContextPayload, + type LogKey, } from '@logto/schemas'; import { type Optional } from '@silverhand/essentials'; @@ -58,6 +59,9 @@ const hookServerRequestListener: RequestListener = (request, response) => { }); }; +const assertHookLogError = ({ result, error }: LogContextPayload, errorMessage: string) => + result === LogResult.Error && typeof error === 'string' && error.includes(errorMessage); + describe('trigger hooks', () => { const { listen, close } = createMockServer(9999, hookServerRequestListener); @@ -76,7 +80,7 @@ describe('trigger hooks', () => { it('should trigger sign-in hook and record error when interaction finished', async () => { const createdHook = await authedAdminApi - .post('hooks', { json: getHookCreationPayload(HookEvent.PostSignIn) }) + .post('hooks', { json: getHookCreationPayload(InteractionHookEvent.PostSignIn) }) .json(); const logKey: LogKey = 'TriggerHook.PostSignIn'; @@ -92,12 +96,15 @@ describe('trigger hooks', () => { createdHook.id, new URLSearchParams({ logKey, page_size: '100' }) ); - expect( - logs.some( - ({ payload: { result, error } }) => - result === LogResult.Error && error === 'TypeError: Failed to parse URL from not_work_url' - ) - ).toBeTruthy(); + + const hookLog = logs.find(({ payload: { hookId } }) => hookId === createdHook.id); + expect(hookLog).toBeTruthy(); + + if (hookLog) { + expect( + assertHookLogError(hookLog.payload, 'Failed to parse URL from not_work_url') + ).toBeTruthy(); + } // Clean up await authedAdminApi.delete(`hooks/${createdHook.id}`); @@ -107,18 +114,18 @@ describe('trigger hooks', () => { it('should trigger multiple register hooks and record properly when interaction finished', async () => { const [hook1, hook2, hook3] = await Promise.all([ authedAdminApi - .post('hooks', { json: getHookCreationPayload(HookEvent.PostRegister) }) + .post('hooks', { json: getHookCreationPayload(InteractionHookEvent.PostRegister) }) .json(), authedAdminApi .post('hooks', { - json: getHookCreationPayload(HookEvent.PostRegister, 'http://localhost:9999'), + json: getHookCreationPayload(InteractionHookEvent.PostRegister, 'http://localhost:9999'), }) .json(), // Using the old API to create a hook authedAdminApi .post('hooks', { json: { - event: HookEvent.PostRegister, + event: InteractionHookEvent.PostRegister, config: { url: 'http://localhost:9999', retries: 2 }, }, }) @@ -137,7 +144,7 @@ describe('trigger hooks', () => { // Check hook trigger log for (const [hook, expectedResult, expectedError] of [ - [hook1, LogResult.Error, 'TypeError: Failed to parse URL from not_work_url'], + [hook1, LogResult.Error, 'Failed to parse URL from not_work_url'], [hook2, LogResult.Success, undefined], [hook3, LogResult.Success, undefined], ] satisfies Array<[Hook, LogResult, Optional]>) { @@ -147,17 +154,24 @@ describe('trigger hooks', () => { new URLSearchParams({ logKey, page_size: '100' }) ); + const log = logs.find(({ payload: { hookId } }) => hookId === hook.id); + + expect(log).toBeTruthy(); + + // Skip the test if the log is not found + if (!log) { + return; + } + // Assert user ip is in the hook request - expect( - logs.every(({ payload }) => (payload.hookRequest as HookRequest).body.userIp) - ).toBeTruthy(); + expect((log.payload.hookRequest as HookRequest).body.userIp).toBeTruthy(); - expect( - logs.some( - ({ payload: { result, error } }) => - result === expectedResult && (!expectedError || error === expectedError) - ) - ).toBeTruthy(); + // Assert the log result and error message + expect(log.payload.result).toEqual(expectedResult); + + if (expectedError) { + expect(assertHookLogError(log.payload, expectedError)).toBeTruthy(); + } } // Clean up @@ -172,7 +186,7 @@ describe('trigger hooks', () => { it('should secure webhook payload data successfully', async () => { const createdHook = await authedAdminApi .post('hooks', { - json: getHookCreationPayload(HookEvent.PostRegister, 'http://localhost:9999'), + json: getHookCreationPayload(InteractionHookEvent.PostRegister, 'http://localhost:9999'), }) .json(); @@ -219,7 +233,10 @@ describe('trigger hooks', () => { // Create a reset password hook const resetPasswordHook = await authedAdminApi .post('hooks', { - json: getHookCreationPayload(HookEvent.PostResetPassword, 'http://localhost:9999'), + json: getHookCreationPayload( + InteractionHookEvent.PostResetPassword, + 'http://localhost:9999' + ), }) .json(); const logKey: LogKey = 'TriggerHook.PostResetPassword'; diff --git a/packages/schemas/src/foundations/jsonb-types/hooks.ts b/packages/schemas/src/foundations/jsonb-types/hooks.ts index bee79153447..502f5e20718 100644 --- a/packages/schemas/src/foundations/jsonb-types/hooks.ts +++ b/packages/schemas/src/foundations/jsonb-types/hooks.ts @@ -1,17 +1,54 @@ import { z } from 'zod'; -export enum HookEvent { +/** + * We categorize the hook events into two types: + * + * InteractionHookEvent: The hook events that are triggered by user interactions. + * DataHookEvent: The hook events that are triggered by Logto data mutations. + */ + +// InteractionHookEvent +export enum InteractionHookEvent { PostRegister = 'PostRegister', PostSignIn = 'PostSignIn', PostResetPassword = 'PostResetPassword', } -export const hookEventGuard: z.ZodType = z.nativeEnum(HookEvent); +// DataHookEvent +// TODO: @simeng-li implement more data hook events +enum DataHookMutableSchema { + Role = 'Role', +} + +enum DataHookMutationType { + Created = 'Created', + Updated = 'Updated', + Deleted = 'Deleted', +} +export type DataHookEvent = `${DataHookMutableSchema}.${DataHookMutationType}`; + +/** The hook event values that can be registered. */ +export const hookEvents = Object.freeze([ + InteractionHookEvent.PostRegister, + InteractionHookEvent.PostSignIn, + InteractionHookEvent.PostResetPassword, + 'Role.Created', + 'Role.Updated', + 'Role.Deleted', +] as const satisfies Array); + +/** The type of hook event values that can be registered. */ +export type HookEvent = (typeof hookEvents)[number]; + +export const hookEventGuard = z.enum(hookEvents); export const hookEventsGuard = hookEventGuard.array(); export type HookEvents = z.infer; +/** + * Hook configuration for web hook. + */ export const hookConfigGuard = z.object({ /** We don't need `type` since v1 only has web hook */ // type: 'web'; @@ -29,3 +66,15 @@ export const hookConfigGuard = z.object({ }); export type HookConfig = z.infer; + +type ApiMethod = 'GET' | 'POST' | 'PUT' | 'DELETE' | 'PATCH'; + +/** + * Management API hooks registration. + * Define the hook event that should be triggered when the management API is called. + */ +export const managementApiHooksRegistration = Object.freeze({ + 'POST /roles': 'Role.Created', + 'PATCH /roles/:id': 'Role.Updated', + 'DELETE /roles/:id': 'Role.Deleted', +} satisfies Record<`${ApiMethod} ${string}`, DataHookEvent>); diff --git a/packages/schemas/src/types/hook.ts b/packages/schemas/src/types/hook.ts index 361ee3f1f49..b61aaf53f7b 100644 --- a/packages/schemas/src/types/hook.ts +++ b/packages/schemas/src/types/hook.ts @@ -1,14 +1,14 @@ import { z } from 'zod'; import { Hooks, type Application, type User } from '../db-entries/index.js'; -import { type HookEvent } from '../foundations/index.js'; +import { type DataHookEvent, type InteractionHookEvent } from '../foundations/index.js'; import type { userInfoSelectFields } from './user.js'; -export type HookEventPayload = { - hookId: string; - event: HookEvent; +export type InteractionHookEventPayload = { + event: InteractionHookEvent; createdAt: string; + hookId: string; sessionId?: string; userAgent?: string; userId?: string; @@ -17,6 +17,20 @@ export type HookEventPayload = { application?: Pick; } & Record; +export type DataHookEventPayload = { + event: DataHookEvent; + createdAt: string; + hookId: string; + ip?: string; + userAgent?: string; + body?: Record; + path?: string; + status?: number; + method?: string; +} & Record; + +export type HookEventPayload = InteractionHookEventPayload | DataHookEventPayload; + const hookExecutionStatsGuard = z.object({ successCount: z.number(), requestCount: z.number(), diff --git a/packages/shared/src/utils/index.ts b/packages/shared/src/utils/index.ts index 6a04dd7b093..14ef68c3ea4 100644 --- a/packages/shared/src/utils/index.ts +++ b/packages/shared/src/utils/index.ts @@ -1,7 +1,8 @@ -export * from './object.js'; -export * from './ttl-cache.js'; +export * from './fetch.js'; export * from './id.js'; -export * from './user-display-name.js'; +export * from './normalize-error.js'; +export * from './object.js'; export * from './phone.js'; export * from './sub-domain.js'; -export * from './fetch.js'; +export * from './ttl-cache.js'; +export * from './user-display-name.js'; diff --git a/packages/shared/src/utils/normalize-error.ts b/packages/shared/src/utils/normalize-error.ts new file mode 100644 index 00000000000..a7bcd273421 --- /dev/null +++ b/packages/shared/src/utils/normalize-error.ts @@ -0,0 +1,94 @@ +/* Migrated from @logto/app-insights */ + +import { trySafe } from '@silverhand/essentials'; + +const transformedKey = Symbol('Indicates an object is transformed from an `Error` instance'); + +const isObject = (value: unknown): value is object => typeof value === 'object' && value !== null; + +// Edited from https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Errors/Cyclic_object_value#circular_references +function getCircularReplacer() { + const ancestors: unknown[] = []; + const transformedMap = new WeakMap(); + + const transformErrorValue = (value: unknown) => { + // Special handling for `Error` instances since they have non-enumerable properties + if (value instanceof Error) { + if (!transformedMap.has(value)) { + const transformed: Record = {}; + + for (const key of Object.getOwnPropertyNames(value)) { + // @ts-expect-error getOwnPropertyNames() returns the valid keys + // eslint-disable-next-line @silverhand/fp/no-mutation + transformed[key] = value[key]; + } + + // eslint-disable-next-line @silverhand/fp/no-mutation + transformed[transformedKey] = true; + + transformedMap.set(value, transformed); + } + + return transformedMap.get(value); + } + + return value; + }; + + return function (this: unknown, key: string, value: unknown) { + // Ignore `stack` property since ApplicationInsights will show it + if (isObject(this) && Object.hasOwn(this, transformedKey) && key === 'stack') { + return; + } + + if (!isObject(value)) { + return value; + } + + // `this` is the object that value is contained in, + // i.e., its direct parent. + while (ancestors.length > 0 && ancestors.at(-1) !== this) { + // eslint-disable-next-line @silverhand/fp/no-mutating-methods + ancestors.pop(); + } + + const transformed = transformErrorValue(value); + + if (ancestors.includes(transformed)) { + return '[Circular ~]'; + } + + // eslint-disable-next-line @silverhand/fp/no-mutating-methods + ancestors.push(transformed); + return transformed; + }; +} + +/** + * Clone and stringify error object for logging purpose. + * The stringified result will be used as the error message. + * This is necessary because directly stringify an non-Error object will lose the stack trace. + */ +export const normalizeError = (error: unknown) => { + /** + * - Ensure the message if not empty otherwise Application Insights will respond 400 + * and the error will not be recorded. + * - We stringify error object here since other error properties won't show on the + * ApplicationInsights details page. + */ + const message = trySafe(() => JSON.stringify(error, getCircularReplacer())) ?? 'Unknown error'; + + // Ensure we don't mutate the original error + const normalized = new Error(message); + + if (error instanceof Error) { + // Manually clone key fields of the error for AppInsights display + /* eslint-disable @silverhand/fp/no-mutation */ + normalized.name = error.name; + normalized.stack = error.stack; + normalized.cause = error.cause; + /* eslint-enable @silverhand/fp/no-mutation */ + } + + return normalized; +}; diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index f9a8357edb1..f21e0ea95a0 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -3234,6 +3234,9 @@ importers: otplib: specifier: ^12.0.1 version: 12.0.1 + p-map: + specifier: ^7.0.2 + version: 7.0.2 p-retry: specifier: ^6.0.0 version: 6.0.0 @@ -17929,6 +17932,11 @@ packages: engines: {node: '>=6'} dev: true + /p-map@7.0.2: + resolution: {integrity: sha512-z4cYYMMdKHzw4O5UkWJImbZynVIo0lSGTXc7bzB1e/rrDqkgGUNysK/o4bTr+0+xKvvLoTyGqYC4Fgljy9qe1Q==} + engines: {node: '>=18'} + dev: false + /p-queue@8.0.1: resolution: {integrity: sha512-NXzu9aQJTAzbBqOt2hwsR63ea7yvxJc0PwN/zobNAudYfb1B7R08SzB4TsLeSbUCuG467NhnoT0oO6w1qRO+BA==} engines: {node: '>=18'} From 39e239753e968c3af7c3736a857b5b5420bb8413 Mon Sep 17 00:00:00 2001 From: Charles Zhao Date: Thu, 9 May 2024 11:49:06 +0800 Subject: [PATCH 352/687] feat(console): add webflow integration guide (#5832) --- .../console/src/assets/docs/guides/index.ts | 8 + .../assets/docs/guides/spa-webflow/README.mdx | 138 ++++++++++++++++++ .../docs/guides/spa-webflow/config.json | 3 + .../assets/docs/guides/spa-webflow/index.ts | 11 ++ .../assets/docs/guides/spa-webflow/logo.svg | 10 ++ 5 files changed, 170 insertions(+) create mode 100644 packages/console/src/assets/docs/guides/spa-webflow/README.mdx create mode 100644 packages/console/src/assets/docs/guides/spa-webflow/config.json create mode 100644 packages/console/src/assets/docs/guides/spa-webflow/index.ts create mode 100644 packages/console/src/assets/docs/guides/spa-webflow/logo.svg diff --git a/packages/console/src/assets/docs/guides/index.ts b/packages/console/src/assets/docs/guides/index.ts index 39b9e0e765f..c7202c0c373 100644 --- a/packages/console/src/assets/docs/guides/index.ts +++ b/packages/console/src/assets/docs/guides/index.ts @@ -15,6 +15,7 @@ import spaAngular from './spa-angular/index'; import spaReact from './spa-react/index'; import spaVanilla from './spa-vanilla/index'; import spaVue from './spa-vue/index'; +import spaWebflow from './spa-webflow/index'; import thirdPartyOidc from './third-party-oidc/index'; import { type Guide } from './types'; import webDotnetCore from './web-dotnet-core/index'; @@ -162,6 +163,13 @@ const guides: Readonly = Object.freeze([ Component: lazy(async () => import('./web-php/README.mdx')), metadata: webPhp, }, + { + order: 2.1, + id: 'spa-webflow', + Logo: lazy(async () => import('./spa-webflow/logo.svg')), + Component: lazy(async () => import('./spa-webflow/README.mdx')), + metadata: spaWebflow, + }, { order: 3, id: 'web-python', diff --git a/packages/console/src/assets/docs/guides/spa-webflow/README.mdx b/packages/console/src/assets/docs/guides/spa-webflow/README.mdx new file mode 100644 index 00000000000..1ad4cf7cf04 --- /dev/null +++ b/packages/console/src/assets/docs/guides/spa-webflow/README.mdx @@ -0,0 +1,138 @@ +import UriInputField from '@/mdx-components/UriInputField'; +import Tabs from '@mdx/components/Tabs'; +import TabItem from '@mdx/components/TabItem'; +import InlineNotification from '@/ds-components/InlineNotification'; +import Steps from '@/mdx-components/Steps'; +import Step from '@/mdx-components/Step'; + + + + + +### Prerequisits: + +1. Integrating Logto with Webflow requires the "Custom code" feature of Webflow, which requires at least the "Basic" plan. +2. A Webflow site, either use an existing site or create a new one. + + + + + +In this step, we'll add global-level custom code to your Webflow site. Since NPM is not supported in Webflow, we'll use the [jsdelivr.com](https://www.jsdelivr.com/) CDN service to import the Logto SDK. + +Open the "Site settings" page, and navigate to the "Custom code" section. Add the following code to the "Head code" section. + +
+  
+    {``}
+  
+
+ +
+ + + + + In the following steps, we assume your Webflow site is running on https://your-awesome-site.webflow.io. + + +### Configure Redirect URI + +First, let’s enter your redirect URI. E.g. `https://your-awesome-site.webflow.io/callback`. + + + +### Implement a sign-in button + +Return to your Webflow designer, drag and drop a "Sign in" button to the home page, and assign it an ID “sign-in” for later reference using `getElementById()`. + +
+  
+    {``}
+  
+
+ +### Handle redirect + +

We're almost there! In the last step, we use {`${props.redirectUris[0] ?? 'https://your-awesome-site.webflow.io/callback'}`} as the Redirect URI, and now we need to handle it properly.

+ +First let's create a "Callback" page in Webflow, and simply put some static text "Redirecting..." on it. Then add the following page-level custom code to "Callback" page. + +```html + +``` + +
+ + + +After signing out, it'll be great to redirect user back to your website. Let's add `https://your-awesome-site.webflow.io` as the Post Sign-out URI below, and use it as the parameter when calling `.signOut()`. + + + +### Implement a sign-out button + +Return to the Webflow designer, and add a “Sign out” button on your home page. Similarly, assign an ID “sign-out” to the button, and add the following code to the page-level custom code. + +
+  
+    {`const signOutButton = document.getElementById('sign-out');
+const onClickSignOut = () => logtoClient.signOut('${props.postLogoutRedirectUris[0] ?? 'https://your-awesome-site.webflow.io'}');
+signOutButton.addEventListener('click', onClickSignOut);`}
+  
+
+ +
+ + + +In Logto SDK, generally we can use `logtoClient.isAuthenticated()` method to check the authentication status, if the user is signed in, the value will be `true`; otherwise, it will be `false`. + +In your Webflow site, you can also use it to programmatically show and hide the sign-in and sign-out buttons. Apply the following custom code to adjust button CSS accordingly. + +```js +const isAuthenticated = await logtoClient.isAuthenticated(); + +signInButton.style.display = isAuthenticated ? 'none' : 'block'; +signOutButton.style.display = isAuthenticated ? 'block' : 'none'; +``` + + + + + +Now, test your Webflow site: + +1. Deploy and visit your site URL, the sign-in button should be visible. +2. Click the sign-in button, the SDK will initiate the sign-in process, redirecting you to the Logto sign-in page. +3. After signing in, you will be redirected back to your site, seeing the username and the sign-out button. +4. Click the sign-out button to sign-out. + + + +
diff --git a/packages/console/src/assets/docs/guides/spa-webflow/config.json b/packages/console/src/assets/docs/guides/spa-webflow/config.json new file mode 100644 index 00000000000..f00075c683d --- /dev/null +++ b/packages/console/src/assets/docs/guides/spa-webflow/config.json @@ -0,0 +1,3 @@ +{ + "order": 2.1 +} diff --git a/packages/console/src/assets/docs/guides/spa-webflow/index.ts b/packages/console/src/assets/docs/guides/spa-webflow/index.ts new file mode 100644 index 00000000000..672802e5e3d --- /dev/null +++ b/packages/console/src/assets/docs/guides/spa-webflow/index.ts @@ -0,0 +1,11 @@ +import { ApplicationType } from '@logto/schemas'; + +import { type GuideMetadata } from '../types'; + +const metadata: Readonly = Object.freeze({ + name: 'Webflow', + description: 'Webflow is a SaaS platform for website building and hosting.', + target: ApplicationType.SPA, +}); + +export default metadata; diff --git a/packages/console/src/assets/docs/guides/spa-webflow/logo.svg b/packages/console/src/assets/docs/guides/spa-webflow/logo.svg new file mode 100644 index 00000000000..e5df00dfe65 --- /dev/null +++ b/packages/console/src/assets/docs/guides/spa-webflow/logo.svg @@ -0,0 +1,10 @@ + + + + + + + + + + From f8221a38dbe99219552893de7a6ceafa22580120 Mon Sep 17 00:00:00 2001 From: Gao Sun Date: Thu, 9 May 2024 11:57:56 +0800 Subject: [PATCH 353/687] refactor(console): update conversion report timing (#5833) --- .../src/components/Conversion/index.tsx | 27 ---------- .../src/components/Conversion/use-retry.ts | 52 ------------------- .../src/components/Conversion/utils.ts | 50 +++++++++++------- packages/console/src/consts/env.ts | 2 +- packages/console/src/onboarding/index.tsx | 20 ------- .../pages/SignInExperience/index.tsx | 20 +++++-- 6 files changed, 47 insertions(+), 124 deletions(-) delete mode 100644 packages/console/src/components/Conversion/use-retry.ts diff --git a/packages/console/src/components/Conversion/index.tsx b/packages/console/src/components/Conversion/index.tsx index 17202ac1088..3414963d028 100644 --- a/packages/console/src/components/Conversion/index.tsx +++ b/packages/console/src/components/Conversion/index.tsx @@ -3,16 +3,11 @@ import { Helmet } from 'react-helmet'; import useCurrentUser from '@/hooks/use-current-user'; -import { useRetry } from './use-retry'; import { shouldReport, gtagAwTrackingId, redditPixelId, hashEmail, - type GtagConversionId, - type RedditReportType, - reportToGoogle, - reportToReddit, plausibleDataDomain, } from './utils'; @@ -109,25 +104,3 @@ export function GlobalScripts() { ); } - -type ReportConversionOptions = { - transactionId?: string; - gtagId?: GtagConversionId; - redditType?: RedditReportType; -}; - -export const useReportConversion = ({ - gtagId, - redditType, - transactionId, -}: ReportConversionOptions) => { - useRetry({ - precondition: Boolean(shouldReport && gtagId), - execute: () => (gtagId ? reportToGoogle(gtagId, { transactionId }) : false), - }); - - useRetry({ - precondition: Boolean(shouldReport && redditType), - execute: () => (redditType ? reportToReddit(redditType) : false), - }); -}; diff --git a/packages/console/src/components/Conversion/use-retry.ts b/packages/console/src/components/Conversion/use-retry.ts deleted file mode 100644 index da7c73f0d00..00000000000 --- a/packages/console/src/components/Conversion/use-retry.ts +++ /dev/null @@ -1,52 +0,0 @@ -import { useEffect } from 'react'; - -type UseRetryOptions = { - /** The precondition to check before executing the function. */ - precondition: boolean; - /** The function to execute when the precondition is not met. */ - onPreconditionFailed?: () => void; - /** The function to execute. If it returns `true`, the retry will stop. */ - execute: () => boolean; - /** - * The maximum number of retries. - * - * @default 3 - */ - maxRetry?: number; -}; - -/** - * A hook to retry a function until the condition is met. The retry interval is 1 second. - */ -export const useRetry = ({ - precondition, - onPreconditionFailed, - execute, - maxRetry = 3, -}: UseRetryOptions) => { - useEffect(() => { - if (!precondition) { - onPreconditionFailed?.(); - } - }, [onPreconditionFailed, precondition]); - - useEffect(() => { - if (!precondition) { - return; - } - - // eslint-disable-next-line @silverhand/fp/no-let - let retry = 0; - const interval = setInterval(() => { - if (execute() || retry >= maxRetry) { - clearInterval(interval); - } - // eslint-disable-next-line @silverhand/fp/no-mutation - retry += 1; - }, 1000); - - return () => { - clearInterval(interval); - }; - }, [execute, maxRetry, precondition]); -}; diff --git a/packages/console/src/components/Conversion/utils.ts b/packages/console/src/components/Conversion/utils.ts index d74ee5f38db..730ab9f4915 100644 --- a/packages/console/src/components/Conversion/utils.ts +++ b/packages/console/src/components/Conversion/utils.ts @@ -1,6 +1,7 @@ import { cond } from '@silverhand/essentials'; +import debug from 'debug'; -import { isProduction } from '@/consts/env'; +const log = debug('conversion'); export const gtagAwTrackingId = 'AW-11124811245'; export enum GtagConversionId { @@ -54,30 +55,18 @@ export const hashEmail = async (email?: string) => { return sha256(canonicalizedEmail); }; -/** Print debug message if not in production. */ -const debug = (...args: Parameters<(typeof console)['debug']>) => { - if (!isProduction) { - console.debug(...args); - } -}; - /** * Add more if needed: https://reddit.my.site.com/helpcenter/s/article/Install-the-Reddit-Pixel-on-your-website */ -export type RedditReportType = - | 'PageVisit' - | 'ViewContent' - | 'Search' - | 'Purchase' - | 'Lead' - | 'SignUp'; - -export const reportToReddit = (redditType: RedditReportType) => { +type RedditReportType = 'PageVisit' | 'ViewContent' | 'Search' | 'Purchase' | 'Lead' | 'SignUp'; + +const reportToReddit = (redditType: RedditReportType) => { if (!window.rdt) { + log('report:', 'window.rdt is not available'); return false; } - debug('report:', 'redditType =', redditType); + log('report:', 'redditType =', redditType); window.rdt('track', redditType); return true; @@ -88,13 +77,14 @@ export const reportToGoogle = ( { transactionId }: { transactionId?: string } = {} ) => { if (!window.gtag) { + log('report:', 'window.gtag is not available'); return false; } const run = async () => { const transaction = cond(transactionId && { transaction_id: await sha256(transactionId) }); - debug('report:', 'gtagId =', gtagId, 'transaction =', transaction); + log('report:', 'gtagId =', gtagId, 'transaction =', transaction); window.gtag?.('event', 'conversion', { send_to: gtagId, ...transaction, @@ -105,3 +95,25 @@ export const reportToGoogle = ( return true; }; + +type ReportConversionOptions = { + transactionId?: string; + gtagId?: GtagConversionId; + redditType?: RedditReportType; +}; + +export const reportConversion = async ({ + gtagId, + redditType, + transactionId, +}: ReportConversionOptions) => { + if (!shouldReport) { + log('skip reporting conversion:', { gtagId, redditType, transactionId }); + return; + } + + return Promise.all([ + gtagId ? reportToGoogle(gtagId, { transactionId }) : undefined, + redditType ? reportToReddit(redditType) : undefined, + ]); +}; diff --git a/packages/console/src/consts/env.ts b/packages/console/src/consts/env.ts index fcdd528d1ee..888eb2d738f 100644 --- a/packages/console/src/consts/env.ts +++ b/packages/console/src/consts/env.ts @@ -1,6 +1,6 @@ import { yes } from '@silverhand/essentials'; -export const isProduction = process.env.NODE_ENV === 'production'; +const isProduction = process.env.NODE_ENV === 'production'; export const isCloud = yes(process.env.IS_CLOUD); export const adminEndpoint = process.env.ADMIN_ENDPOINT; diff --git a/packages/console/src/onboarding/index.tsx b/packages/console/src/onboarding/index.tsx index a5f5833d196..04c984a24e3 100644 --- a/packages/console/src/onboarding/index.tsx +++ b/packages/console/src/onboarding/index.tsx @@ -3,14 +3,11 @@ import { useContext, useEffect } from 'react'; import { Route, Navigate, Outlet, Routes } from 'react-router-dom'; import { SWRConfig } from 'swr'; -import { useReportConversion } from '@/components/Conversion'; -import { GtagConversionId } from '@/components/Conversion/utils'; import AppBoundary from '@/containers/AppBoundary'; import ProtectedRoutes from '@/containers/ProtectedRoutes'; import TenantAccess from '@/containers/TenantAccess'; import { AppThemeContext } from '@/contexts/AppThemeProvider'; import Toast from '@/ds-components/Toast'; -import useCurrentUser from '@/hooks/use-current-user'; import useSwrOptions from '@/hooks/use-swr-options'; import useTenantPathname from '@/hooks/use-tenant-pathname'; @@ -27,23 +24,6 @@ function Layout() { const { setThemeOverride } = useContext(AppThemeContext); const { match, getTo } = useTenantPathname(); - // User object should be available at this point as it's rendered by the `` - // component in `packages/console/src/App.tsx`. - const { user } = useCurrentUser(); - - /** - * Report a sign-up conversion. - * - * Note it may run multiple times (e.g. a user visit multiple times to finish the onboarding process, - * which rarely happens). We should turn on deduplication settings in the provider's dashboard. For - * example, in Google, we should set conversion's "Count" to "One". - */ - useReportConversion({ - gtagId: GtagConversionId.SignUp, - redditType: 'SignUp', - transactionId: user?.id, - }); - useEffect(() => { setThemeOverride(Theme.Light); diff --git a/packages/console/src/onboarding/pages/SignInExperience/index.tsx b/packages/console/src/onboarding/pages/SignInExperience/index.tsx index 04539f8a02d..c31a6dedb6f 100644 --- a/packages/console/src/onboarding/pages/SignInExperience/index.tsx +++ b/packages/console/src/onboarding/pages/SignInExperience/index.tsx @@ -8,6 +8,7 @@ import useSWR from 'swr'; import Tools from '@/assets/icons/tools.svg'; import ActionBar from '@/components/ActionBar'; +import { GtagConversionId, reportConversion } from '@/components/Conversion/utils'; import PageMeta from '@/components/PageMeta'; import { TenantsContext } from '@/contexts/TenantsProvider'; import Button from '@/ds-components/Button'; @@ -18,6 +19,7 @@ import TextInput from '@/ds-components/TextInput'; import ImageUploaderField from '@/ds-components/Uploader/ImageUploaderField'; import useApi from '@/hooks/use-api'; import type { RequestError } from '@/hooks/use-api'; +import useCurrentUser from '@/hooks/use-current-user'; import useTenantPathname from '@/hooks/use-tenant-pathname'; import useUserAssetsService from '@/hooks/use-user-assets-service'; import { CardSelector, MultiCardSelector } from '@/onboarding/components/CardSelector'; @@ -53,6 +55,7 @@ function SignInExperience() { const api = useApi(); const { isReady: isUserAssetsServiceReady } = useUserAssetsService(); const { update } = useUserOnboardingData(); + const { user } = useCurrentUser(); const { navigateTenant, currentTenantId } = useContext(TenantsContext); const enterAdminConsole = async () => { @@ -115,11 +118,18 @@ function SignInExperience() { } } - const updatedData = await api - .patch(buildUrl('api/sign-in-exp', { removeUnusedDemoSocialConnector: '1' }), { - json: formDataParser.toUpdateOnboardingSieData(formData, signInExperience), - }) - .json(); + const [updatedData] = await Promise.all([ + api + .patch(buildUrl('api/sign-in-exp', { removeUnusedDemoSocialConnector: '1' }), { + json: formDataParser.toUpdateOnboardingSieData(formData, signInExperience), + }) + .json(), + reportConversion({ + gtagId: GtagConversionId.SignUp, + redditType: 'SignUp', + transactionId: user?.id, + }), + ]); void mutate(updatedData); From 0227822b2de251b519025b1d3a6024327a1327f6 Mon Sep 17 00:00:00 2001 From: Darcy Ye Date: Thu, 9 May 2024 12:55:56 +0800 Subject: [PATCH 354/687] feat(connector): can access all user email even if no public email is set (#5737) --- .changeset/pretty-mirrors-peel.md | 8 ++ .../connectors/connector-github/package.json | 4 +- .../connector-github/src/constant.ts | 8 +- .../connector-github/src/index.test.ts | 119 +++++++++++++----- .../connectors/connector-github/src/index.ts | 92 ++++++++------ .../connectors/connector-github/src/types.ts | 11 ++ pnpm-lock.yaml | 13 +- 7 files changed, 179 insertions(+), 76 deletions(-) create mode 100644 .changeset/pretty-mirrors-peel.md diff --git a/.changeset/pretty-mirrors-peel.md b/.changeset/pretty-mirrors-peel.md new file mode 100644 index 00000000000..a50915c9dcb --- /dev/null +++ b/.changeset/pretty-mirrors-peel.md @@ -0,0 +1,8 @@ +--- +"@logto/connector-github": minor +--- + +fetch GitHub account's private email address list and pick the verified primary email as a fallback + +- Add `user:email` as part of default scope to fetch GitHub account's private email address list +- Pick the verified primary email among private email address list as a fallback if the user does not set a public email for GitHub account diff --git a/packages/connectors/connector-github/package.json b/packages/connectors/connector-github/package.json index b0e35afbd78..83fa7cbc5f6 100644 --- a/packages/connectors/connector-github/package.json +++ b/packages/connectors/connector-github/package.json @@ -6,7 +6,7 @@ "dependencies": { "@logto/connector-kit": "workspace:^3.0.0", "@silverhand/essentials": "^2.9.0", - "got": "^14.0.0", + "ky": "^1.2.3", "query-string": "^9.0.0", "snakecase-keys": "^8.0.0", "zod": "^3.22.4" @@ -64,7 +64,7 @@ "@vitest/coverage-v8": "^1.4.0", "eslint": "^8.56.0", "lint-staged": "^15.0.2", - "nock": "^13.3.1", + "nock": "14.0.0-beta.6", "prettier": "^3.0.0", "rollup": "^4.12.0", "rollup-plugin-output-size": "^1.3.0", diff --git a/packages/connectors/connector-github/src/constant.ts b/packages/connectors/connector-github/src/constant.ts index 4d9445e16fa..798546e4027 100644 --- a/packages/connectors/connector-github/src/constant.ts +++ b/packages/connectors/connector-github/src/constant.ts @@ -2,9 +2,15 @@ import type { ConnectorMetadata } from '@logto/connector-kit'; import { ConnectorPlatform, ConnectorConfigFormItemType } from '@logto/connector-kit'; export const authorizationEndpoint = 'https://github.com/login/oauth/authorize'; -export const scope = 'read:user'; +/** + * `read:user` read user profile data; `user:email` read user email addresses (including private email addresses). + * Ref: https://docs.github.com/en/apps/oauth-apps/building-oauth-apps/scopes-for-oauth-apps + */ +export const scope = 'read:user user:email'; export const accessTokenEndpoint = 'https://github.com/login/oauth/access_token'; export const userInfoEndpoint = 'https://api.github.com/user'; +// Ref: https://docs.github.com/en/rest/users/emails?apiVersion=2022-11-28#list-email-addresses-for-the-authenticated-user +export const userEmailsEndpoint = 'https://api.github.com/user/emails'; export const defaultMetadata: ConnectorMetadata = { id: 'github-universal', diff --git a/packages/connectors/connector-github/src/index.test.ts b/packages/connectors/connector-github/src/index.test.ts index 0656245e073..f7d0793ce2f 100644 --- a/packages/connectors/connector-github/src/index.test.ts +++ b/packages/connectors/connector-github/src/index.test.ts @@ -1,9 +1,13 @@ import nock from 'nock'; import { ConnectorError, ConnectorErrorCodes } from '@logto/connector-kit'; -import qs from 'query-string'; -import { accessTokenEndpoint, authorizationEndpoint, userInfoEndpoint } from './constant.js'; +import { + accessTokenEndpoint, + authorizationEndpoint, + userEmailsEndpoint, + userInfoEndpoint, +} from './constant.js'; import createConnector, { getAccessToken } from './index.js'; import { mockedConfig } from './mock.js'; @@ -28,7 +32,7 @@ describe('getAuthorizationUri', () => { vi.fn() ); expect(authorizationUri).toEqual( - `${authorizationEndpoint}?client_id=%3Cclient-id%3E&redirect_uri=http%3A%2F%2Flocalhost%3A3000%2Fcallback&state=some_state&scope=read%3Auser` + `${authorizationEndpoint}?client_id=%3Cclient-id%3E&redirect_uri=http%3A%2F%2Flocalhost%3A3000%2Fcallback&state=some_state&scope=read%3Auser+user%3Aemail` ); }); }); @@ -40,16 +44,11 @@ describe('getAccessToken', () => { }); it('should get an accessToken by exchanging with code', async () => { - nock(accessTokenEndpoint) - .post('') - .reply( - 200, - qs.stringify({ - access_token: 'access_token', - scope: 'scope', - token_type: 'token_type', - }) - ); + nock(accessTokenEndpoint).post('').reply(200, { + access_token: 'access_token', + scope: 'scope', + token_type: 'token_type', + }); const { accessToken } = await getAccessToken(mockedConfig, { code: 'code' }); expect(accessToken).toEqual('access_token'); }); @@ -57,7 +56,7 @@ describe('getAccessToken', () => { it('throws SocialAuthCodeInvalid error if accessToken not found in response', async () => { nock(accessTokenEndpoint) .post('') - .reply(200, qs.stringify({ access_token: '', scope: 'scope', token_type: 'token_type' })); + .reply(200, { access_token: '', scope: 'scope', token_type: 'token_type' }); await expect(getAccessToken(mockedConfig, { code: 'code' })).rejects.toStrictEqual( new ConnectorError(ConnectorErrorCodes.SocialAuthCodeInvalid) ); @@ -66,16 +65,11 @@ describe('getAccessToken', () => { describe('getUserInfo', () => { beforeEach(() => { - nock(accessTokenEndpoint) - .post('') - .reply( - 200, - qs.stringify({ - access_token: 'access_token', - scope: 'scope', - token_type: 'token_type', - }) - ); + nock(accessTokenEndpoint).post('').query(true).reply(200, { + access_token: 'access_token', + scope: 'scope', + token_type: 'token_type', + }); }); afterEach(() => { @@ -91,6 +85,7 @@ describe('getUserInfo', () => { email: 'octocat@github.com', foo: 'bar', }); + nock(userEmailsEndpoint).get('').reply(200, []); const connector = await createConnector({ getConfig }); const socialUserInfo = await connector.getUserInfo({ code: 'code' }, vi.fn()); expect(socialUserInfo).toStrictEqual({ @@ -99,11 +94,70 @@ describe('getUserInfo', () => { name: 'monalisa octocat', 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', + userInfo: { + id: 1, + avatar_url: 'https://github.com/images/error/octocat_happy.gif', + name: 'monalisa octocat', + email: 'octocat@github.com', + foo: 'bar', + }, + userEmails: [], + }, + }); + }); + + it('should fallback to verified primary email if not public is available', async () => { + nock(userInfoEndpoint).get('').reply(200, { + id: 1, + avatar_url: 'https://github.com/images/error/octocat_happy.gif', + name: 'monalisa octocat', + email: undefined, + foo: 'bar', + }); + nock(userEmailsEndpoint) + .get('') + .reply(200, [ + { + email: 'foo@logto.io', + verified: true, + primary: true, + visibility: 'public', + }, + { + email: 'foo1@logto.io', + verified: true, + primary: false, + visibility: null, + }, + ]); + const connector = await createConnector({ getConfig }); + const socialUserInfo = await connector.getUserInfo({ code: 'code' }, vi.fn()); + expect(socialUserInfo).toStrictEqual({ + id: '1', + avatar: 'https://github.com/images/error/octocat_happy.gif', + name: 'monalisa octocat', + email: 'foo@logto.io', + rawData: { + userInfo: { + id: 1, + avatar_url: 'https://github.com/images/error/octocat_happy.gif', + name: 'monalisa octocat', + foo: 'bar', + }, + userEmails: [ + { + email: 'foo@logto.io', + verified: true, + primary: true, + visibility: 'public', + }, + { + email: 'foo1@logto.io', + verified: true, + primary: false, + visibility: null, + }, + ], }, }); }); @@ -115,15 +169,14 @@ describe('getUserInfo', () => { name: null, email: null, }); + nock(userEmailsEndpoint).get('').reply(200, []); const connector = await createConnector({ getConfig }); const socialUserInfo = await connector.getUserInfo({ code: 'code' }, vi.fn()); expect(socialUserInfo).toMatchObject({ id: '1', rawData: { - id: 1, - avatar_url: null, - name: null, - email: null, + userInfo: { id: 1, avatar_url: null, name: null, email: null }, + userEmails: [], }, }); }); diff --git a/packages/connectors/connector-github/src/index.ts b/packages/connectors/connector-github/src/index.ts index 52a0e97f182..8c36bdc36ba 100644 --- a/packages/connectors/connector-github/src/index.ts +++ b/packages/connectors/connector-github/src/index.ts @@ -1,6 +1,12 @@ import { assert, conditional } from '@silverhand/essentials'; -import { got, HTTPError } from 'got'; +import { + ConnectorError, + ConnectorErrorCodes, + validateConfig, + ConnectorType, + jsonGuard, +} from '@logto/connector-kit'; import type { GetAuthorizationUri, GetUserInfo, @@ -8,20 +14,14 @@ import type { CreateConnector, GetConnectorConfig, } from '@logto/connector-kit'; -import { - ConnectorError, - ConnectorErrorCodes, - validateConfig, - ConnectorType, - parseJson, -} from '@logto/connector-kit'; -import qs from 'query-string'; +import ky, { HTTPError } from 'ky'; import { authorizationEndpoint, accessTokenEndpoint, scope as defaultScope, userInfoEndpoint, + userEmailsEndpoint, defaultMetadata, defaultTimeout, } from './constant.js'; @@ -29,6 +29,7 @@ import type { GithubConfig } from './types.js'; import { authorizationCallbackErrorGuard, githubConfigGuard, + emailAddressGuard, accessTokenResponseGuard, userInfoResponseGuard, authResponseGuard, @@ -79,17 +80,18 @@ export const getAccessToken = async (config: GithubConfig, codeObject: { code: s const { code } = codeObject; const { clientId: client_id, clientSecret: client_secret } = config; - const httpResponse = await got.post({ - url: accessTokenEndpoint, - json: { - client_id, - client_secret, - code, - }, - timeout: { request: defaultTimeout }, - }); + const httpResponse = await ky + .post(accessTokenEndpoint, { + body: new URLSearchParams({ + client_id, + client_secret, + code, + }), + timeout: defaultTimeout, + }) + .json(); - const result = accessTokenResponseGuard.safeParse(qs.parse(httpResponse.body)); + const result = accessTokenResponseGuard.safeParse(httpResponse); if (!result.success) { throw new ConnectorError(ConnectorErrorCodes.InvalidResponse, result.error); @@ -110,34 +112,54 @@ const getUserInfo = validateConfig(config, githubConfigGuard); const { accessToken } = await getAccessToken(config, { code }); + const authedApi = ky.create({ + timeout: defaultTimeout, + hooks: { + beforeRequest: [ + (request) => { + request.headers.set('Authorization', `Bearer ${accessToken}`); + }, + ], + }, + }); + try { - const httpResponse = await got.get(userInfoEndpoint, { - headers: { - authorization: `token ${accessToken}`, - }, - timeout: { request: defaultTimeout }, - }); - const rawData = parseJson(httpResponse.body); - const result = userInfoResponseGuard.safeParse(rawData); - - if (!result.success) { - throw new ConnectorError(ConnectorErrorCodes.InvalidResponse, result.error); + const [userInfo, userEmails] = await Promise.all([ + authedApi.get(userInfoEndpoint).json(), + authedApi.get(userEmailsEndpoint).json(), + ]); + + const userInfoResult = userInfoResponseGuard.safeParse(userInfo); + const userEmailsResult = emailAddressGuard.array().safeParse(userEmails); + + if (!userInfoResult.success) { + throw new ConnectorError(ConnectorErrorCodes.InvalidResponse, userInfoResult.error); + } + + if (!userEmailsResult.success) { + throw new ConnectorError(ConnectorErrorCodes.InvalidResponse, userEmailsResult.error); } - const { id, avatar_url: avatar, email, name } = result.data; + const { id, avatar_url: avatar, email: publicEmail, name } = userInfoResult.data; return { id: String(id), avatar: conditional(avatar), - email: conditional(email), + email: conditional( + publicEmail ?? + userEmailsResult.data.find(({ verified, primary }) => verified && primary)?.email + ), name: conditional(name), - rawData, + rawData: jsonGuard.parse({ + userInfo, + userEmails, + }), }; } catch (error: unknown) { if (error instanceof HTTPError) { - const { statusCode, body: rawBody } = error.response; + const { status, body: rawBody } = error.response; - if (statusCode === 401) { + if (status === 401) { throw new ConnectorError(ConnectorErrorCodes.SocialAccessTokenInvalid); } diff --git a/packages/connectors/connector-github/src/types.ts b/packages/connectors/connector-github/src/types.ts index fcd8c30915a..7906e4e8be9 100644 --- a/packages/connectors/connector-github/src/types.ts +++ b/packages/connectors/connector-github/src/types.ts @@ -8,6 +8,17 @@ export const githubConfigGuard = z.object({ export type GithubConfig = z.infer; +/** + * This guard is used to validate the response from the GitHub API when requesting the user's email addresses. + * Ref: https://docs.github.com/en/rest/users/emails?apiVersion=2022-11-28#list-email-addresses-for-the-authenticated-user + */ +export const emailAddressGuard = z.object({ + email: z.string(), + primary: z.boolean(), + verified: z.boolean(), + visibility: z.string().nullable(), +}); + export const accessTokenResponseGuard = z.object({ access_token: z.string(), scope: z.string(), diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index f21e0ea95a0..f474e325e5e 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -981,9 +981,9 @@ importers: '@silverhand/essentials': specifier: ^2.9.0 version: 2.9.0 - got: - specifier: ^14.0.0 - version: 14.0.0 + ky: + specifier: ^1.2.3 + version: 1.2.3 query-string: specifier: ^9.0.0 version: 9.0.0 @@ -1028,8 +1028,8 @@ importers: specifier: ^15.0.2 version: 15.0.2 nock: - specifier: ^13.3.1 - version: 13.3.1 + specifier: 14.0.0-beta.6 + version: 14.0.0-beta.6 prettier: specifier: ^3.0.0 version: 3.0.0 @@ -18007,6 +18007,9 @@ packages: resolution: {integrity: sha512-2GTVocFkwblV/TIg9AmT7TI2fO4xdWkyN8aFUEVtiVNWt96GTR3FgQyHFValfCbcj1k9Xf962Ws2hYXYUr9k1Q==} engines: {node: '>= 12.0.0'} hasBin: true + peerDependenciesMeta: + '@parcel/core': + optional: true dependencies: '@parcel/config-default': 2.9.3(@parcel/core@2.9.3)(postcss@8.4.31) '@parcel/core': 2.9.3 From 7244dadf69f7cb23f6c970bbc7070dd7885ad391 Mon Sep 17 00:00:00 2001 From: wangsijie Date: Thu, 9 May 2024 13:32:31 +0800 Subject: [PATCH 355/687] feat(core,schemas): update consent info (#5822) --- packages/core/src/libraries/session.test.ts | 31 +- packages/core/src/libraries/session.ts | 40 ++- .../core/src/middleware/koa-auto-consent.ts | 19 +- .../{consent.ts => consent/index.ts} | 270 +++++++++--------- .../src/routes/interaction/consent/utils.ts | 131 +++++++++ packages/core/src/routes/interaction/index.ts | 2 +- .../integration-tests/src/api/interaction.ts | 3 +- .../integration-tests/src/client/index.ts | 17 ++ .../third-party-sign-in/happy-path.test.ts | 104 ++++++- packages/schemas/src/types/consent.ts | 2 +- 10 files changed, 438 insertions(+), 181 deletions(-) rename packages/core/src/routes/interaction/{consent.ts => consent/index.ts} (52%) create mode 100644 packages/core/src/routes/interaction/consent/utils.ts diff --git a/packages/core/src/libraries/session.test.ts b/packages/core/src/libraries/session.test.ts index 94bf68b60bc..32a8e0e54f7 100644 --- a/packages/core/src/libraries/session.test.ts +++ b/packages/core/src/libraries/session.test.ts @@ -59,7 +59,7 @@ describe('consent', () => { it('should update with new grantId if not exist', async () => { const provider = createMockProvider(jest.fn().mockResolvedValue(baseInteractionDetails), Grant); - await consent(context, provider, queries, baseInteractionDetails); + await consent({ ctx: context, provider, queries, interactionDetails: baseInteractionDetails }); expect(grantSave).toHaveBeenCalled(); @@ -85,7 +85,7 @@ describe('consent', () => { const provider = createMockProvider(jest.fn().mockResolvedValue(interactionDetails), Grant); - await consent(context, provider, queries, interactionDetails); + await consent({ ctx: context, provider, queries, interactionDetails }); expect(grantSave).toHaveBeenCalled(); @@ -109,7 +109,7 @@ describe('consent', () => { })); const provider = createMockProvider(jest.fn().mockResolvedValue(baseInteractionDetails), Grant); - await consent(context, provider, queries, baseInteractionDetails); + await consent({ ctx: context, provider, queries, interactionDetails: baseInteractionDetails }); expect(userQueries.updateUserById).toHaveBeenCalledWith(mockUser.id, { applicationId: baseInteractionDetails.params.client_id, @@ -117,21 +117,18 @@ describe('consent', () => { }); it('should grant missing scopes', async () => { - const interactionDetails = { - ...baseInteractionDetails, - prompt: { - details: { - missingOIDCScope: ['openid', 'profile'], - missingResourceScopes: { - resource1: ['resource1_scope1', 'resource1_scope2'], - resource2: ['resource2_scope1'], - }, - }, + const provider = createMockProvider(jest.fn().mockResolvedValue(baseInteractionDetails), Grant); + await consent({ + ctx: context, + provider, + queries, + interactionDetails: baseInteractionDetails, + missingOIDCScopes: ['openid', 'profile'], + resourceScopesToGrant: { + resource1: ['resource1_scope1', 'resource1_scope2'], + resource2: ['resource2_scope1'], }, - } as unknown as Interaction; - - const provider = createMockProvider(jest.fn().mockResolvedValue(interactionDetails), Grant); - await consent(context, provider, queries, interactionDetails); + }); expect(grantAddOIDCScope).toHaveBeenCalledWith('openid profile'); expect(grantAddResourceScope).toHaveBeenCalledWith( diff --git a/packages/core/src/libraries/session.ts b/packages/core/src/libraries/session.ts index eaef720c9a1..e1173fc04ca 100644 --- a/packages/core/src/libraries/session.ts +++ b/packages/core/src/libraries/session.ts @@ -68,17 +68,27 @@ export const getMissingScopes = (prompt: PromptDetail) => { return missingScopesGuard.parse(prompt.details); }; -export const consent = async ( - ctx: Context, - provider: Provider, - queries: Queries, - interactionDetails: Awaited> -) => { +export const consent = async ({ + ctx, + provider, + queries, + interactionDetails, + missingOIDCScopes = [], + resourceScopesToGrant = {}, + resourceScopesToReject = {}, +}: { + ctx: Context; + provider: Provider; + queries: Queries; + interactionDetails: Awaited>; + missingOIDCScopes?: string[]; + resourceScopesToGrant?: Record; + resourceScopesToReject?: Record; +}) => { const { session, grantId, params: { client_id }, - prompt, } = interactionDetails; assertThat(session, 'session.not_found'); @@ -91,17 +101,17 @@ export const consent = async ( await saveUserFirstConsentedAppId(queries, accountId, String(client_id)); - const { missingOIDCScope, missingResourceScopes } = getMissingScopes(prompt); - // Fulfill missing scopes - if (missingOIDCScope) { - grant.addOIDCScope(missingOIDCScope.join(' ')); + if (missingOIDCScopes.length > 0) { + grant.addOIDCScope(missingOIDCScopes.join(' ')); } - if (missingResourceScopes) { - for (const [indicator, scope] of Object.entries(missingResourceScopes)) { - grant.addResourceScope(indicator, scope.join(' ')); - } + for (const [indicator, scope] of Object.entries(resourceScopesToGrant)) { + grant.addResourceScope(indicator, scope.join(' ')); + } + + for (const [indicator, scope] of Object.entries(resourceScopesToReject)) { + grant.rejectResourceScope(indicator, scope.join(' ')); } const finalGrantId = await grant.save(); diff --git a/packages/core/src/middleware/koa-auto-consent.ts b/packages/core/src/middleware/koa-auto-consent.ts index 15aa2c342d8..d13cb4dfbaf 100644 --- a/packages/core/src/middleware/koa-auto-consent.ts +++ b/packages/core/src/middleware/koa-auto-consent.ts @@ -4,7 +4,7 @@ import { type IRouterParamContext } from 'koa-router'; import type Provider from 'oidc-provider'; import { errors } from 'oidc-provider'; -import { consent } from '#src/libraries/session.js'; +import { consent, getMissingScopes } from '#src/libraries/session.js'; import type Queries from '#src/tenants/Queries.js'; import assertThat from '#src/utils/assert-that.js'; @@ -18,7 +18,10 @@ export default function koaAutoConsent { return async (ctx, next) => { const interactionDetails = await provider.interactionDetails(ctx.req, ctx.res); - const { client_id: clientId } = interactionDetails.params; + const { + params: { client_id: clientId }, + prompt, + } = interactionDetails; const { applications: { findApplicationById }, @@ -36,7 +39,17 @@ export default function koaAutoConsent -): Promise => { - if (!missingResourceScopes) { - return []; - } - - const resourcesWithScopes = await Promise.all( - Object.entries(missingResourceScopes).map(async ([resourceIndicator, scopeNames]) => { - // Organization resources are reserved resources, we don't need to find the resource details - if (resourceIndicator === ReservedResource.Organization) { - const [_, organizationScopes] = await queries.organizations.scopes.findAll(); - const scopes = scopeNames.map((scopeName) => { - const scope = organizationScopes.find((scope) => scope.name === scopeName); - - // Will be guarded by OIDC provider, should not happen - assertThat( - scope, - new InvalidTarget(`scope with name ${scopeName} not found for organization resource`) - ); - - return scope; - }); - - return { - resource: { - id: resourceIndicator, - name: resourceIndicator, - }, - scopes, - }; - } - - const resource = await queries.resources.findResourceByIndicator(resourceIndicator); - - // Will be guarded by OIDC provider, should not happen - assertThat( - resource, - new InvalidTarget(`resource with indicator ${resourceIndicator} not found`) - ); - - // Find the scopes details - const scopes = await Promise.all( - scopeNames.map(async (scopeName) => - queries.scopes.findScopeByNameAndResourceId(scopeName, resource.id) - ) - ); - - return { - resource, - scopes: scopes - // eslint-disable-next-line no-implicit-coercion -- filter out not found scopes (should not happen) - .filter((scope): scope is Scope => !!scope), - }; - }) - ); - - return ( - resourcesWithScopes - // Filter out if all resource scopes are not found (should not happen) - .filter(({ scopes }) => scopes.length > 0) - .map((resourceWithGroups) => missingResourceScopesGuard.parse(resourceWithGroups)) - ); -}; - -/** - * The missingResourceScopes in the prompt details are from `getResourceServerInfo`, - * which contains resource scopes and organization resource scopes. - * We need to separate the organization resource scopes from the resource scopes. - * The "scopes" in `missingResourceScopes` do not have "id", so we have to rebuild the scopes list first. - */ -const filterAndParseMissingResourceScopes = async ({ - resourceScopes, - queries, - libraries, - userId, - organizationId, -}: { - resourceScopes: Record; - queries: Queries; - libraries: TenantContext['libraries']; - userId: string; - organizationId?: string; -}) => { - const filteredResourceScopes = Object.fromEntries( - await Promise.all( - Object.entries(resourceScopes).map( - async ([resourceIndicator, missingScopes]): Promise<[string, string[]]> => { - if (!EnvSet.values.isDevFeaturesEnabled) { - return [resourceIndicator, missingScopes]; - } - - // Fetch the list of scopes, `findFromOrganizations` is set to false, - // so it will only search the user resource scopes. - const scopes = await findResourceScopes({ - queries, - libraries, - indicator: resourceIndicator, - userId, - findFromOrganizations: Boolean(organizationId), - organizationId, - }); +import { interactionPrefix } from '../const.js'; +import type { WithInteractionDetailsContext } from '../middleware/koa-interaction-details.js'; - return [ - resourceIndicator, - missingScopes.filter((scope) => scopes.some(({ name }) => name === scope)), - ]; - } - ) - ) - ); +import { filterAndParseMissingResourceScopes } from './utils.js'; - return parseMissingResourceScopesInfo(queries, filteredResourceScopes); -}; +const { InvalidClient, InvalidRedirectUri } = errors; export default function consentRoutes( router: Router>, @@ -172,22 +51,23 @@ export default function consentRoutes( }, } = ctx; - // Grant the organizations to the application if the user has selected the organizations - if (organizationIds?.length) { - const { - session, - params: { client_id: applicationId }, - } = interactionDetails; + const { + session, + params: { client_id: applicationId }, + prompt, + } = interactionDetails; - assertThat(session, 'session.not_found'); + assertThat(session, 'session.not_found'); - assertThat( - applicationId && typeof applicationId === 'string', - new InvalidClient('client must be available') - ); + assertThat( + applicationId && typeof applicationId === 'string', + new InvalidClient('client must be available') + ); - const { accountId: userId } = session; + const { accountId: userId } = session; + // Grant the organizations to the application if the user has selected the organizations + if (organizationIds?.length) { // Assert that user is a member of all organizations await validateUserConsentOrganizationMembership(userId, organizationIds); @@ -200,7 +80,115 @@ export default function consentRoutes( ); } - const redirectTo = await consent(ctx, provider, queries, interactionDetails); + const { missingOIDCScope = [], missingResourceScopes: allMissingResourceScopes = {} } = + getMissingScopes(prompt); + + /* === Rebuild resource scopes === */ + // The resource scopes saved in the prompt details lost the organization information. + // Instead of trust the front-end's submission, we choose to find the organizations and build the resource scopes again, + // to ensure the scopes are correct. + + // Find the organizations granted by the user + // The user may send consent request multiple times, so we need to find the organizations again + const [, organizations] = EnvSet.values.isDevFeaturesEnabled + ? await queries.applications.userConsentOrganizations.getEntities(Organizations, { + applicationId, + userId, + }) + : [0, []]; + + // The missingResourceScopes from the prompt details are from `getResourceServerInfo`, + // which contains resource scopes and organization resource scopes. + // We need to separate the organization resource scopes from the resource scopes. + // The "scopes" in `missingResourceScopes` do not have "id", so we have to rebuild the scopes list. + const missingResourceScopes = await filterAndParseMissingResourceScopes({ + resourceScopes: allMissingResourceScopes, + queries, + libraries, + userId, + }); + + const organizationsWithMissingResourceScopes = await Promise.all( + organizations.map(async ({ name, id }) => { + if (!EnvSet.values.isDevFeaturesEnabled) { + return { name, id }; + } + + const missingResourceScopes = await filterAndParseMissingResourceScopes({ + resourceScopes: allMissingResourceScopes, + queries, + libraries, + userId, + organizationId: id, + }); + + return { name, id, missingResourceScopes }; + }) + ); + /* === End rebuild resource scopes === */ + + // Join the missing resource scopes from the prompt details and the missing resource scopes from the organizations + const resourceScopesEntries: Array<[string, string[]]> = missingResourceScopes.map( + ({ resource, scopes }) => [resource.indicator, scopes.map(({ name }) => name)] + ); + const resourceScopesToGrant: Record = Object.fromEntries( + organizationsWithMissingResourceScopes.reduce>( + (entries, { missingResourceScopes }) => { + if (!missingResourceScopes) { + return entries; + } + + const organizationEntries: Array<[string, string[]]> = missingResourceScopes.map( + ({ resource, scopes }) => [resource.indicator, scopes.map(({ name }) => name)] + ); + + // The entries whoes resource indecator is not in the prev entries + const newEntries: Array<[string, string[]]> = organizationEntries.filter( + ([resourceIndicator]) => + !entries.some(([indicator]) => indicator === resourceIndicator) + ); + + const existingEntries: Array<[string, string[]]> = entries.map( + ([indicator, scopes]) => { + const organizationEntry = organizationEntries.find( + ([resourceIndicator]) => resourceIndicator === indicator + ); + + if (!organizationEntry) { + return [indicator, scopes]; + } + + return [indicator, deduplicate([...scopes, ...organizationEntry[1]])]; + } + ); + + return [...newEntries, ...existingEntries]; + }, + resourceScopesEntries + ) + ); + + const resourceScopesToReject = Object.fromEntries( + Object.entries(allMissingResourceScopes).map(([resourceIndicator, scopes]) => { + const resource = resourceScopesToGrant[resourceIndicator]; + + if (!resource) { + return [resourceIndicator, []]; + } + + return [resourceIndicator, scopes.filter((scope) => !resource.includes(scope))]; + }) + ); + + const redirectTo = await consent({ + ctx, + provider, + queries, + interactionDetails, + missingOIDCScopes: missingOIDCScope, + resourceScopesToGrant, + resourceScopesToReject, + }); ctx.body = { redirectTo }; diff --git a/packages/core/src/routes/interaction/consent/utils.ts b/packages/core/src/routes/interaction/consent/utils.ts new file mode 100644 index 00000000000..eda88989721 --- /dev/null +++ b/packages/core/src/routes/interaction/consent/utils.ts @@ -0,0 +1,131 @@ +import { ReservedResource } from '@logto/core-kit'; +import { type MissingResourceScopes, type Scope, missingResourceScopesGuard } from '@logto/schemas'; +import { errors } from 'oidc-provider'; + +import { EnvSet } from '#src/env-set/index.js'; +import { findResourceScopes } from '#src/oidc/resource.js'; +import type Libraries from '#src/tenants/Libraries.js'; +import type Queries from '#src/tenants/Queries.js'; +import assertThat from '#src/utils/assert-that.js'; + +const { InvalidTarget } = errors; + +/** + * Parse the missing resource scopes info with details. We need to display the resource name and scope details on the consent page. + */ +const parseMissingResourceScopesInfo = async ( + queries: Queries, + missingResourceScopes?: Record +): Promise => { + if (!missingResourceScopes) { + return []; + } + + const resourcesWithScopes = await Promise.all( + Object.entries(missingResourceScopes).map(async ([resourceIndicator, scopeNames]) => { + // Organization resources are reserved resources, we don't need to find the resource details + if (resourceIndicator === ReservedResource.Organization) { + const [_, organizationScopes] = await queries.organizations.scopes.findAll(); + const scopes = scopeNames.map((scopeName) => { + const scope = organizationScopes.find((scope) => scope.name === scopeName); + + // Will be guarded by OIDC provider, should not happen + assertThat( + scope, + new InvalidTarget(`scope with name ${scopeName} not found for organization resource`) + ); + + return scope; + }); + + return { + resource: { + id: resourceIndicator, + name: resourceIndicator, + indicator: resourceIndicator, + }, + scopes, + }; + } + + const resource = await queries.resources.findResourceByIndicator(resourceIndicator); + + // Will be guarded by OIDC provider, should not happen + assertThat( + resource, + new InvalidTarget(`resource with indicator ${resourceIndicator} not found`) + ); + + // Find the scopes details + const scopes = await Promise.all( + scopeNames.map(async (scopeName) => + queries.scopes.findScopeByNameAndResourceId(scopeName, resource.id) + ) + ); + + return { + resource, + scopes: scopes + // eslint-disable-next-line no-implicit-coercion -- filter out not found scopes (should not happen) + .filter((scope): scope is Scope => !!scope), + }; + }) + ); + + return ( + resourcesWithScopes + // Filter out if all resource scopes are not found (should not happen) + .filter(({ scopes }) => scopes.length > 0) + .map((resourceWithGroups) => missingResourceScopesGuard.parse(resourceWithGroups)) + ); +}; + +/** + * The missingResourceScopes in the prompt details are from `getResourceServerInfo`, + * which contains resource scopes and organization resource scopes. + * We need to separate the organization resource scopes from the resource scopes. + * The "scopes" in `missingResourceScopes` do not have "id", so we have to rebuild the scopes list first. + */ +export const filterAndParseMissingResourceScopes = async ({ + resourceScopes, + queries, + libraries, + userId, + organizationId, +}: { + resourceScopes: Record; + queries: Queries; + libraries: Libraries; + userId: string; + organizationId?: string; +}) => { + const filteredResourceScopes = Object.fromEntries( + await Promise.all( + Object.entries(resourceScopes).map( + async ([resourceIndicator, missingScopes]): Promise<[string, string[]]> => { + if (!EnvSet.values.isDevFeaturesEnabled) { + return [resourceIndicator, missingScopes]; + } + + // Fetch the list of scopes, `findFromOrganizations` is set to false, + // so it will only search the user resource scopes. + const scopes = await findResourceScopes({ + queries, + libraries, + indicator: resourceIndicator, + userId, + findFromOrganizations: Boolean(organizationId), + organizationId, + }); + + return [ + resourceIndicator, + missingScopes.filter((scope) => scopes.some(({ name }) => name === scope)), + ]; + } + ) + ) + ); + + return parseMissingResourceScopesInfo(queries, filteredResourceScopes); +}; diff --git a/packages/core/src/routes/interaction/index.ts b/packages/core/src/routes/interaction/index.ts index 419f4bec793..ff14cc9cf3b 100644 --- a/packages/core/src/routes/interaction/index.ts +++ b/packages/core/src/routes/interaction/index.ts @@ -13,7 +13,7 @@ import type { AnonymousRouter, RouterInitArgs } from '../types.js'; import submitInteraction from './actions/submit-interaction.js'; import additionalRoutes from './additional.js'; -import consentRoutes from './consent.js'; +import consentRoutes from './consent/index.js'; import { interactionPrefix } from './const.js'; import mfaRoutes from './mfa.js'; import koaInteractionDetails from './middleware/koa-interaction-details.js'; diff --git a/packages/integration-tests/src/api/interaction.ts b/packages/integration-tests/src/api/interaction.ts index 977b690e0f1..45ff2501de2 100644 --- a/packages/integration-tests/src/api/interaction.ts +++ b/packages/integration-tests/src/api/interaction.ts @@ -133,7 +133,7 @@ export const skipMfaBinding = async (cookie: string) => }, }); -export const consent = async (api: KyInstance, cookie: string) => +export const consent = async (cookie: string, payload: { organizationIds?: string[] } = {}) => api .post('interaction/consent', { headers: { @@ -141,6 +141,7 @@ export const consent = async (api: KyInstance, cookie: string) => }, redirect: 'manual', throwHttpErrors: false, + json: payload, }) .json(); diff --git a/packages/integration-tests/src/client/index.ts b/packages/integration-tests/src/client/index.ts index 48552523c8e..d487f71e273 100644 --- a/packages/integration-tests/src/client/index.ts +++ b/packages/integration-tests/src/client/index.ts @@ -127,6 +127,23 @@ export default class MockClient { await this.logto.handleSignInCallback(signInCallbackUri); } + public async manualConsent(redirectTo: string) { + const authCodeResponse = await ky.get(redirectTo, { + headers: { + cookie: this.interactionCookie, + }, + redirect: 'manual', + throwHttpErrors: false, + }); + + // Note: Should redirect to the signInCallbackUri + assert(authCodeResponse.status === 303, new Error('Complete auth failed')); + const signInCallbackUri = authCodeResponse.headers.get('location'); + assert(signInCallbackUri, new Error('Get sign in callback uri failed')); + + return this.logto.handleSignInCallback(signInCallbackUri); + } + public async getAccessToken(resource?: string, organizationId?: string) { return this.logto.getAccessToken(resource, organizationId); } diff --git a/packages/integration-tests/src/tests/api/interaction/third-party-sign-in/happy-path.test.ts b/packages/integration-tests/src/tests/api/interaction/third-party-sign-in/happy-path.test.ts index 7aab62fc200..8c3e1bb453c 100644 --- a/packages/integration-tests/src/tests/api/interaction/third-party-sign-in/happy-path.test.ts +++ b/packages/integration-tests/src/tests/api/interaction/third-party-sign-in/happy-path.test.ts @@ -5,7 +5,7 @@ import { assert } from '@silverhand/essentials'; import { deleteUser } from '#src/api/admin-user.js'; import { assignUserConsentScopes } from '#src/api/application-user-consent-scope.js'; import { createApplication, deleteApplication } from '#src/api/application.js'; -import { getConsentInfo, putInteraction } from '#src/api/interaction.js'; +import { consent, getConsentInfo, putInteraction } from '#src/api/interaction.js'; import { OrganizationScopeApi } from '#src/api/organization-scope.js'; import { createResource, deleteResource } from '#src/api/resource.js'; import { createScope } from '#src/api/scope.js'; @@ -18,6 +18,7 @@ import { generateResourceName, generateRoleName, generateScopeName, + getAccessTokenPayload, } from '#src/utils.js'; describe('consent api', () => { @@ -92,7 +93,7 @@ describe('consent api', () => { const organizationScopeApi = new OrganizationScopeApi(); const organizationScope = await organizationScopeApi.create({ - name: 'organization-scope', + name: generateScopeName(), }); await assignUserConsentScopes(application.id, { @@ -192,6 +193,105 @@ describe('consent api', () => { await deleteUser(user.id); }); + describe('submit consent info', () => { + it('should perform manual consent successfully', async () => { + const application = applications.get(thirdPartyApplicationName); + assert(application, new Error('application.not_found')); + + const { userProfile, user } = await generateNewUser({ username: true, password: true }); + + const client = await initClient( + { + appId: application.id, + appSecret: application.secret, + }, + redirectUri + ); + + await client.successSend(putInteraction, { + event: InteractionEvent.SignIn, + identifier: { + username: userProfile.username, + password: userProfile.password, + }, + }); + + const { redirectTo } = await client.submitInteraction(); + + await client.processSession(redirectTo, false); + const { redirectTo: consentRedirectTo } = await client.send(consent); + await client.manualConsent(consentRedirectTo); + + await deleteUser(user.id); + }); + + it('consent with organization id and verify access token scope', async () => { + const application = applications.get(thirdPartyApplicationName); + assert(application, new Error('application.not_found')); + + const resource = await createResource(generateResourceName(), generateResourceIndicator()); + const scope = await createScope(resource.id, generateScopeName()); + const scope2 = await createScope(resource.id, generateScopeName()); + const roleApi = new OrganizationRoleApiTest(); + const role = await roleApi.create({ + name: generateRoleName(), + resourceScopeIds: [scope.id], + }); + const role2 = await roleApi.create({ + name: generateRoleName(), + resourceScopeIds: [scope2.id], + }); + const organizationApi = new OrganizationApiTest(); + const organization = await organizationApi.create({ name: 'test_org_1' }); + const { userProfile, user } = await generateNewUser({ username: true, password: true }); + await organizationApi.addUsers(organization.id, [user.id]); + await organizationApi.addUserRoles(organization.id, user.id, [role.id]); + + const organization2 = await organizationApi.create({ name: 'test_org_2' }); + await organizationApi.addUsers(organization2.id, [user.id]); + await organizationApi.addUserRoles(organization2.id, user.id, [role2.id]); + + await assignUserConsentScopes(application.id, { + organizationResourceScopes: [scope.id], + userScopes: [UserScope.Organizations], + }); + + const client = await initClient( + { + appId: application.id, + appSecret: application.secret, + scopes: [UserScope.Organizations, UserScope.Profile, scope.name, scope2.name], + resources: [resource.indicator], + }, + redirectUri + ); + + await client.successSend(putInteraction, { + event: InteractionEvent.SignIn, + identifier: { + username: userProfile.username, + password: userProfile.password, + }, + }); + + const { redirectTo } = await client.submitInteraction(); + + await client.processSession(redirectTo, false); + const { redirectTo: consentRedirectTo } = await client.send(consent, { + organizationIds: [organization.id], + }); + await client.manualConsent(consentRedirectTo); + const accessToken = await client.getAccessToken(resource.indicator, organization.id); + // Scope2 is removed because organization2 is not consented + expect(getAccessTokenPayload(accessToken)).toHaveProperty('scope', scope.name); + + await roleApi.cleanUp(); + await organizationApi.cleanUp(); + await deleteResource(resource.id); + await deleteUser(user.id); + }); + }); + afterAll(async () => { for (const application of applications.values()) { void deleteApplication(application.id); diff --git a/packages/schemas/src/types/consent.ts b/packages/schemas/src/types/consent.ts index 15e8b064936..a3eca479f01 100644 --- a/packages/schemas/src/types/consent.ts +++ b/packages/schemas/src/types/consent.ts @@ -40,7 +40,7 @@ export const applicationSignInExperienceGuard = ApplicationSignInExperiences.gua export const missingResourceScopesGuard = z.object({ // The original resource id has a maximum length of 21 restriction. We need to make it compatible with the logto reserved organization name. // use string here, as we do not care about the resource id length here. - resource: Resources.guard.pick({ name: true }).extend({ id: z.string() }), + resource: Resources.guard.pick({ name: true, indicator: true }).extend({ id: z.string() }), scopes: Scopes.guard.pick({ id: true, name: true, description: true }).array(), }); From ae5284b1d3be880bfc6b57cc469ffbc340f2c7f1 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 9 May 2024 08:42:31 +0000 Subject: [PATCH 356/687] chore(deps): update pnpm to v9 (#5727) * chore(deps): update pnpm to v9 * ci: fix alteration --------- Co-authored-by: Gao Sun --- ...eration-compatibility-integration-test.yml | 10 +- .github/workflows/changesets.yml | 2 + .github/workflows/commitlint.yml | 2 + .github/workflows/integration-test.yml | 8 +- .github/workflows/main.yml | 13 +- .github/workflows/master-codecov-report.yml | 2 + .github/workflows/release.yml | 4 + .github/workflows/upload-annotations.yml | 2 + Dockerfile | 2 +- package.json | 2 +- pnpm-lock.yaml | 19947 +++++++++------- 11 files changed, 11103 insertions(+), 8891 deletions(-) diff --git a/.github/workflows/alteration-compatibility-integration-test.yml b/.github/workflows/alteration-compatibility-integration-test.yml index f73c141d369..f245b8c5c5e 100644 --- a/.github/workflows/alteration-compatibility-integration-test.yml +++ b/.github/workflows/alteration-compatibility-integration-test.yml @@ -55,6 +55,7 @@ jobs: with: artifact-name: alteration-integration-test-${{ github.sha }} branch: ${{github.base_ref}} + pnpm-version: 9 run-logto: strategy: @@ -68,9 +69,10 @@ jobs: DB_URL: postgres://postgres:postgres@localhost:5432/postgres steps: - - uses: logto-io/actions-run-logto-integration-tests@v2 + - uses: logto-io/actions-run-logto-integration-tests@v3 with: branch: ${{github.base_ref}} - logto_artifact: alteration-integration-test-${{ github.sha }} - test_target: ${{ matrix.target }} - db_alteration_target: ${{github.head_ref}} + logto-artifact: alteration-integration-test-${{ github.sha }} + test-target: ${{ matrix.target }} + db-alteration-target: ${{github.head_ref}} + pnpm-version: 9 diff --git a/.github/workflows/changesets.yml b/.github/workflows/changesets.yml index 751c4f72689..0815cc3d372 100644 --- a/.github/workflows/changesets.yml +++ b/.github/workflows/changesets.yml @@ -19,6 +19,8 @@ jobs: - name: Setup Node and pnpm uses: silverhand-io/actions-node-pnpm-run-steps@v4 + with: + pnpm-version: 9 - name: Import GPG key uses: crazy-max/ghaction-import-gpg@v6 diff --git a/.github/workflows/commitlint.yml b/.github/workflows/commitlint.yml index 0ee63394e9e..4e031d6450f 100644 --- a/.github/workflows/commitlint.yml +++ b/.github/workflows/commitlint.yml @@ -22,6 +22,8 @@ jobs: - name: Setup Node and pnpm uses: silverhand-io/actions-node-pnpm-run-steps@v4 + with: + pnpm-version: 9 - name: Commitlint # Credit to https://stackoverflow.com/a/67365254/12514940 diff --git a/.github/workflows/integration-test.yml b/.github/workflows/integration-test.yml index 6fcd3f321cd..db27f49c963 100644 --- a/.github/workflows/integration-test.yml +++ b/.github/workflows/integration-test.yml @@ -21,6 +21,7 @@ jobs: - uses: logto-io/actions-package-logto-artifact@v2 with: artifact-name: integration-test-${{ github.sha }} + pnpm-version: 9 run-logto: strategy: @@ -34,7 +35,8 @@ jobs: DB_URL: postgres://postgres:postgres@localhost:5432/postgres steps: - - uses: logto-io/actions-run-logto-integration-tests@v2 + - uses: logto-io/actions-run-logto-integration-tests@v3 with: - logto_artifact: integration-test-${{ github.sha }} - test_target: ${{ matrix.target }} + logto-artifact: integration-test-${{ github.sha }} + test-target: ${{ matrix.target }} + pnpm-version: 9 diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index dcbed207d85..be545c5bfa3 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -20,6 +20,8 @@ jobs: - name: Setup Node and pnpm uses: silverhand-io/actions-node-pnpm-run-steps@v4 + with: + pnpm-version: 9 - name: Build run: pnpm ci:build @@ -32,6 +34,8 @@ jobs: - name: Setup Node and pnpm uses: silverhand-io/actions-node-pnpm-run-steps@v4 + with: + pnpm-version: 9 - name: Prepack run: pnpm prepack @@ -54,6 +58,8 @@ jobs: - name: Setup Node and pnpm uses: silverhand-io/actions-node-pnpm-run-steps@v4 + with: + pnpm-version: 9 - name: Build for test run: pnpm -r build:test @@ -120,6 +126,7 @@ jobs: - name: Setup Node and pnpm uses: silverhand-io/actions-node-pnpm-run-steps@v4 with: + pnpm-version: 9 run-install: false # ** Prepack packages ** @@ -129,7 +136,11 @@ jobs: - name: Prepack alteration working-directory: ./alteration - run: pnpm i && pnpm prepack + run: | + # Remove corepack commands once a new Logto release is out + corepack enable pnpm + corepack use pnpm@8 + pnpm i && pnpm prepack # ** End ** - name: Setup Postgres diff --git a/.github/workflows/master-codecov-report.yml b/.github/workflows/master-codecov-report.yml index 8c8aa00f388..9f1efb01c04 100644 --- a/.github/workflows/master-codecov-report.yml +++ b/.github/workflows/master-codecov-report.yml @@ -15,6 +15,8 @@ jobs: - name: Setup Node and pnpm uses: silverhand-io/actions-node-pnpm-run-steps@v4 + with: + pnpm-version: 9 - name: Build for test run: pnpm -r build:test diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 1c0ba29b6fc..c942800e52f 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -130,6 +130,8 @@ jobs: - name: Setup Node and pnpm uses: silverhand-io/actions-node-pnpm-run-steps@v4 + with: + pnpm-version: 9 - name: Import GPG key uses: crazy-max/ghaction-import-gpg@v6 @@ -160,6 +162,8 @@ jobs: - name: Setup Node and pnpm uses: silverhand-io/actions-node-pnpm-run-steps@v4 + with: + pnpm-version: 9 - name: Build run: pnpm -r build diff --git a/.github/workflows/upload-annotations.yml b/.github/workflows/upload-annotations.yml index 8e749111313..eba88c96325 100644 --- a/.github/workflows/upload-annotations.yml +++ b/.github/workflows/upload-annotations.yml @@ -23,6 +23,8 @@ jobs: - name: Setup Node and pnpm uses: silverhand-io/actions-node-pnpm-run-steps@v4 + with: + pnpm-version: 9 - name: Prepack run: pnpm prepack diff --git a/Dockerfile b/Dockerfile index d6029c1b7a0..7cbb6d9fdcf 100644 --- a/Dockerfile +++ b/Dockerfile @@ -7,7 +7,7 @@ ENV CI=true ENV PUPPETEER_SKIP_DOWNLOAD=true ### Install toolchain ### -RUN npm add --location=global pnpm@^8.0.0 +RUN npm add --location=global pnpm@^9.0.0 # https://github.com/nodejs/docker-node/blob/main/docs/BestPractices.md#node-gyp-alpine RUN apk add --no-cache python3 make g++ rsync diff --git a/package.json b/package.json index 55ff5b2b3bd..51d09398705 100644 --- a/package.json +++ b/package.json @@ -35,7 +35,7 @@ }, "engines": { "node": "^20.9.0", - "pnpm": "^8.10.0" + "pnpm": "^9.0.0" }, "pnpm": { "overrides": { diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index f474e325e5e..4fc91804bb5 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -1,4 +1,4 @@ -lockfileVersion: '6.0' +lockfileVersion: '9.0' settings: autoInstallPeers: true @@ -4112,40 +4112,8840 @@ importers: packages: - /@aashutoshrathi/word-wrap@1.2.6: + '@aashutoshrathi/word-wrap@1.2.6': resolution: {integrity: sha512-1Yjs2SvM8TflER/OD3cOjhWWOZb58A2t7wpE2S9XfBYTiIl+XFhQG2bjy4Pu1I+EAlCNUzRDYDdFwFYUKvXcIA==} engines: {node: '>=0.10.0'} - dev: true - /@ampproject/remapping@2.3.0: + '@ampproject/remapping@2.3.0': resolution: {integrity: sha512-30iZtAPgz+LTIYoeivqYo853f02jBYSd5uGnGpkFV0M3xOt9aN73erkgYAmZU43x4VfqcnLxW9Kpg3R5LC4YYw==} engines: {node: '>=6.0.0'} + + '@apidevtools/json-schema-ref-parser@9.0.6': + resolution: {integrity: sha512-M3YgsLjI0lZxvrpeGVk9Ap032W6TPQkH6pRAZz81Ac3WUNF79VQooAFnp8umjvVzUmD93NkogxEwbSce7qMsUg==} + + '@apidevtools/openapi-schemas@2.1.0': + resolution: {integrity: sha512-Zc1AlqrJlX3SlpupFGpiLi2EbteyP7fXmUOGup6/DnkRgjP9bgMM/ag+n91rsv0U1Gpz0H3VILA/o3bW7Ua6BQ==} + engines: {node: '>=10'} + + '@apidevtools/swagger-methods@3.0.2': + resolution: {integrity: sha512-QAkD5kK2b1WfjDS/UQn/qQkbwF31uqRjPTrsCs5ZG9BQGAkjwvqGFjjPqAuzac/IYzpPtRzjCP1WrTuAIjMrXg==} + + '@apidevtools/swagger-parser@10.1.0': + resolution: {integrity: sha512-9Kt7EuS/7WbMAUv2gSziqjvxwDbFSg3Xeyfuj5laUODX8o/k/CpsAKiQ8W7/R88eXFTMbJYg6+7uAmOWNKmwnw==} + peerDependencies: + openapi-types: '>=7' + + '@authenio/samlify-node-xmllint@2.0.0': + resolution: {integrity: sha512-V9cQ0CHqu3JwOmbSecGPUnzIES5kHxD00FEZKnWh90ksQUJG5/TscV2r9XLbKp7MlRMOSUfWxecM35xPSLFdSg==} + peerDependencies: + samlify: '>= 2.6.0' + + '@authenio/xml-encryption@2.0.2': + resolution: {integrity: sha512-cTlrKttbrRHEw3W+0/I609A2Matj5JQaRvfLtEIGZvlN0RaPi+3ANsMeqAyCAVlH/lUIW2tmtBlSMni74lcXeg==} + engines: {node: '>=12'} + + '@aws-crypto/crc32@3.0.0': + resolution: {integrity: sha512-IzSgsrxUcsrejQbPVilIKy16kAT52EwB6zSaI+M3xxIhKh5+aldEyvI+z6erM7TCLB2BJsFrtHjp6/4/sr+3dA==} + + '@aws-crypto/crc32c@3.0.0': + resolution: {integrity: sha512-ENNPPManmnVJ4BTXlOjAgD7URidbAznURqD0KvfREyc4o20DPYdEldU1f5cQ7Jbj0CJJSPaMIk/9ZshdB3210w==} + + '@aws-crypto/ie11-detection@3.0.0': + resolution: {integrity: sha512-341lBBkiY1DfDNKai/wXM3aujNBkXR7tq1URPQDL9wi3AUbI80NR74uF1TXHMm7po1AcnFk8iu2S2IeU/+/A+Q==} + + '@aws-crypto/sha1-browser@3.0.0': + resolution: {integrity: sha512-NJth5c997GLHs6nOYTzFKTbYdMNA6/1XlKVgnZoaZcQ7z7UJlOgj2JdbHE8tiYLS3fzXNCguct77SPGat2raSw==} + + '@aws-crypto/sha256-browser@3.0.0': + resolution: {integrity: sha512-8VLmW2B+gjFbU5uMeqtQM6Nj0/F1bro80xQXCW6CQBWgosFWXTx77aeOF5CAIAmbOK64SdMBJdNr6J41yP5mvQ==} + + '@aws-crypto/sha256-js@3.0.0': + resolution: {integrity: sha512-PnNN7os0+yd1XvXAy23CFOmTbMaDxgxXtTKHybrJ39Y8kGzBATgBFibWJKH6BhytLI/Zyszs87xCOBNyBig6vQ==} + + '@aws-crypto/supports-web-crypto@3.0.0': + resolution: {integrity: sha512-06hBdMwUAb2WFTuGG73LSC0wfPu93xWwo5vL2et9eymgmu3Id5vFAHBbajVWiGhPO37qcsdCap/FqXvJGJWPIg==} + + '@aws-crypto/util@3.0.0': + resolution: {integrity: sha512-2OJlpeJpCR48CC8r+uKVChzs9Iungj9wkZrl8Z041DWEWvyIHILYKCPNzJghKsivj+S3mLo6BVc7mBNzdxA46w==} + + '@aws-sdk/client-s3@3.556.0': + resolution: {integrity: sha512-6WF9Kuzz1/8zqX8hKBpqj9+FYwQ5uTsVcOKpTW94AMX2qtIeVRlwlnNnYyywWo61yqD3g59CMNHcqSsaqAwglg==} + engines: {node: '>=14.0.0'} + + '@aws-sdk/client-sesv2@3.556.0': + resolution: {integrity: sha512-CYbCVlMlXJ72r+DrBRjgqw+Dm2yVUA9d1rxZWjfBhMulaypbV0EIZK2xLwgcQ5LvdfKdrrFEsFcViDA6q0w3Zg==} + engines: {node: '>=14.0.0'} + + '@aws-sdk/client-sso-oidc@3.556.0': + resolution: {integrity: sha512-AXKd2TB6nNrksu+OfmHl8uI07PdgzOo4o8AxoRO8SHlwoMAGvcT9optDGVSYoVfgOKTymCoE7h8/UoUfPc11wQ==} + engines: {node: '>=14.0.0'} + peerDependencies: + '@aws-sdk/credential-provider-node': ^3.556.0 + + '@aws-sdk/client-sso@3.556.0': + resolution: {integrity: sha512-unXdWS7uvHqCcOyC1de+Fr8m3F2vMg2m24GPea0bg7rVGTYmiyn9mhUX11VCt+ozydrw+F50FQwL6OqoqPocmw==} + engines: {node: '>=14.0.0'} + + '@aws-sdk/client-sts@3.556.0': + resolution: {integrity: sha512-TsK3js7Suh9xEmC886aY+bv0KdLLYtzrcmVt6sJ/W6EnDXYQhBuKYFhp03NrN2+vSvMGpqJwR62DyfKe1G0QzQ==} + engines: {node: '>=14.0.0'} + peerDependencies: + '@aws-sdk/credential-provider-node': ^3.556.0 + + '@aws-sdk/core@3.556.0': + resolution: {integrity: sha512-vJaSaHw2kPQlo11j/Rzuz0gk1tEaKdz+2ser0f0qZ5vwFlANjt08m/frU17ctnVKC1s58bxpctO/1P894fHLrA==} + engines: {node: '>=14.0.0'} + + '@aws-sdk/credential-provider-env@3.535.0': + resolution: {integrity: sha512-XppwO8c0GCGSAvdzyJOhbtktSEaShg14VJKg8mpMa1XcgqzmcqqHQjtDWbx5rZheY1VdpXZhpEzJkB6LpQejpA==} + engines: {node: '>=14.0.0'} + + '@aws-sdk/credential-provider-http@3.552.0': + resolution: {integrity: sha512-vsmu7Cz1i45pFEqzVb4JcFmAmVnWFNLsGheZc8SCptlqCO5voETrZZILHYIl4cjKkSDk3pblBOf0PhyjqWW6WQ==} + engines: {node: '>=14.0.0'} + + '@aws-sdk/credential-provider-ini@3.556.0': + resolution: {integrity: sha512-0Nz4ErOlXhe3muxWYMbPwRMgfKmVbBp36BAE2uv/z5wTbfdBkcgUwaflEvlKCLUTdHzuZsQk+BFS/gVyaUeOuA==} + engines: {node: '>=14.0.0'} + + '@aws-sdk/credential-provider-node@3.556.0': + resolution: {integrity: sha512-s1xVtKjyGc60O8qcNIzS1X3H+pWEwEfZ7TgNznVDNyuXvLrlNWiAcigPWGl2aAkc8tGcsSG0Qpyw2KYC939LFg==} + engines: {node: '>=14.0.0'} + + '@aws-sdk/credential-provider-process@3.535.0': + resolution: {integrity: sha512-9O1OaprGCnlb/kYl8RwmH7Mlg8JREZctB8r9sa1KhSsWFq/SWO0AuJTyowxD7zL5PkeS4eTvzFFHWCa3OO5epA==} + engines: {node: '>=14.0.0'} + + '@aws-sdk/credential-provider-sso@3.556.0': + resolution: {integrity: sha512-ETuBgcnpfxqadEAqhQFWpKoV1C/NAgvs5CbBc5EJbelJ8f4prTdErIHjrRtVT8c02MXj92QwczsiNYd5IoOqyw==} + engines: {node: '>=14.0.0'} + + '@aws-sdk/credential-provider-web-identity@3.556.0': + resolution: {integrity: sha512-R/YAL8Uh8i+dzVjzMnbcWLIGeeRi2mioHVGnVF+minmaIkCiQMZg2HPrdlKm49El+RljT28Nl5YHRuiqzEIwMA==} + engines: {node: '>=14.0.0'} + + '@aws-sdk/middleware-bucket-endpoint@3.535.0': + resolution: {integrity: sha512-7sijlfQsc4UO9Fsl11mU26Y5f9E7g6UoNg/iJUBpC5pgvvmdBRO5UEhbB/gnqvOEPsBXyhmfzbstebq23Qdz7A==} + engines: {node: '>=14.0.0'} + + '@aws-sdk/middleware-expect-continue@3.535.0': + resolution: {integrity: sha512-hFKyqUBky0NWCVku8iZ9+PACehx0p6vuMw5YnZf8FVgHP0fode0b/NwQY6UY7oor/GftvRsAlRUAWGNFEGUpwA==} + engines: {node: '>=14.0.0'} + + '@aws-sdk/middleware-flexible-checksums@3.535.0': + resolution: {integrity: sha512-rBIzldY9jjRATxICDX7t77aW6ctqmVDgnuAOgbVT5xgHftt4o7PGWKoMvl/45hYqoQgxVFnCBof9bxkqSBebVA==} + engines: {node: '>=14.0.0'} + + '@aws-sdk/middleware-host-header@3.535.0': + resolution: {integrity: sha512-0h6TWjBWtDaYwHMQJI9ulafeS4lLaw1vIxRjbpH0svFRt6Eve+Sy8NlVhECfTU2hNz/fLubvrUxsXoThaLBIew==} + engines: {node: '>=14.0.0'} + + '@aws-sdk/middleware-location-constraint@3.535.0': + resolution: {integrity: sha512-SxfS9wfidUZZ+WnlKRTCRn3h+XTsymXRXPJj8VV6hNRNeOwzNweoG3YhQbTowuuNfXf89m9v6meYkBBtkdacKw==} + engines: {node: '>=14.0.0'} + + '@aws-sdk/middleware-logger@3.535.0': + resolution: {integrity: sha512-huNHpONOrEDrdRTvSQr1cJiRMNf0S52NDXtaPzdxiubTkP+vni2MohmZANMOai/qT0olmEVX01LhZ0ZAOgmg6A==} + engines: {node: '>=14.0.0'} + + '@aws-sdk/middleware-recursion-detection@3.535.0': + resolution: {integrity: sha512-am2qgGs+gwqmR4wHLWpzlZ8PWhm4ktj5bYSgDrsOfjhdBlWNxvPoID9/pDAz5RWL48+oH7I6SQzMqxXsFDikrw==} + engines: {node: '>=14.0.0'} + + '@aws-sdk/middleware-sdk-s3@3.556.0': + resolution: {integrity: sha512-4W/dnxqj1B6/uS/5Z+3UHaqDDGjNPgEVlqf5d3ToOFZ31ZfpANwhcCmyX39JklC4aolCEi9renQ5wHnTCC8K8g==} + engines: {node: '>=14.0.0'} + + '@aws-sdk/middleware-signing@3.556.0': + resolution: {integrity: sha512-kWrPmU8qd3gI5qzpuW9LtWFaH80cOz1ZJDavXx6PRpYZJ5JaKdUHghwfDlVTzzFYAeJmVsWIkPcLT5d5mY5ZTQ==} + engines: {node: '>=14.0.0'} + + '@aws-sdk/middleware-ssec@3.537.0': + resolution: {integrity: sha512-2QWMrbwd5eBy5KCYn9a15JEWBgrK2qFEKQN2lqb/6z0bhtevIOxIRfC99tzvRuPt6nixFQ+ynKuBjcfT4ZFrdQ==} + engines: {node: '>=14.0.0'} + + '@aws-sdk/middleware-user-agent@3.540.0': + resolution: {integrity: sha512-8Rd6wPeXDnOYzWj1XCmOKcx/Q87L0K1/EHqOBocGjLVbN3gmRxBvpmR1pRTjf7IsWfnnzN5btqtcAkfDPYQUMQ==} + engines: {node: '>=14.0.0'} + + '@aws-sdk/region-config-resolver@3.535.0': + resolution: {integrity: sha512-IXOznDiaItBjsQy4Fil0kzX/J3HxIOknEphqHbOfUf+LpA5ugcsxuQQONrbEQusCBnfJyymrldBvBhFmtlU9Wg==} + engines: {node: '>=14.0.0'} + + '@aws-sdk/signature-v4-multi-region@3.556.0': + resolution: {integrity: sha512-bWDSK0ggK7QzAOmPZGv29UAIZocL1MNY7XyOvm3P3P1U3tFMoIBilQQBLabXyHoZ9J3Ik0Vv4n95htUhRQ35ow==} + engines: {node: '>=14.0.0'} + + '@aws-sdk/token-providers@3.556.0': + resolution: {integrity: sha512-tvIiugNF0/+2wfuImMrpKjXMx4nCnFWQjQvouObny+wrif/PGqqQYrybwxPJDvzbd965bu1I+QuSv85/ug7xsg==} + engines: {node: '>=14.0.0'} + + '@aws-sdk/types@3.535.0': + resolution: {integrity: sha512-aY4MYfduNj+sRR37U7XxYR8wemfbKP6lx00ze2M2uubn7mZotuVrWYAafbMSXrdEMSToE5JDhr28vArSOoLcSg==} + engines: {node: '>=14.0.0'} + + '@aws-sdk/util-arn-parser@3.535.0': + resolution: {integrity: sha512-smVo29nUPAOprp8Z5Y3GHuhiOtw6c8/EtLCm5AVMtRsTPw4V414ZXL2H66tzmb5kEeSzQlbfBSBEdIFZoxO9kg==} + engines: {node: '>=14.0.0'} + + '@aws-sdk/util-endpoints@3.540.0': + resolution: {integrity: sha512-1kMyQFAWx6f8alaI6UT65/5YW/7pDWAKAdNwL6vuJLea03KrZRX3PMoONOSJpAS5m3Ot7HlWZvf3wZDNTLELZw==} + engines: {node: '>=14.0.0'} + + '@aws-sdk/util-locate-window@3.295.0': + resolution: {integrity: sha512-d/s+zhUx5Kh4l/ecMP/TBjzp1GR/g89Q4nWH6+wH5WgdHsK+LG+vmsk6mVNuP/8wsCofYG4NBqp5Ulbztbm9QA==} + engines: {node: '>=14.0.0'} + + '@aws-sdk/util-user-agent-browser@3.535.0': + resolution: {integrity: sha512-RWMcF/xV5n+nhaA/Ff5P3yNP3Kur/I+VNZngog4TEs92oB/nwOdAg/2JL8bVAhUbMrjTjpwm7PItziYFQoqyig==} + + '@aws-sdk/util-user-agent-node@3.535.0': + resolution: {integrity: sha512-dRek0zUuIT25wOWJlsRm97nTkUlh1NDcLsQZIN2Y8KxhwoXXWtJs5vaDPT+qAg+OpcNj80i1zLR/CirqlFg/TQ==} + engines: {node: '>=14.0.0'} + peerDependencies: + aws-crt: '>=1.0.0' + peerDependenciesMeta: + aws-crt: + optional: true + + '@aws-sdk/util-utf8-browser@3.188.0': + resolution: {integrity: sha512-jt627x0+jE+Ydr9NwkFstg3cUvgWh56qdaqAMDsqgRlKD21md/6G226z/Qxl7lb1VEW2LlmCx43ai/37Qwcj2Q==} + + '@aws-sdk/xml-builder@3.535.0': + resolution: {integrity: sha512-VXAq/Jz8KIrU84+HqsOJhIKZqG0PNTdi6n6PFQ4xJf44ZQHD/5C7ouH4qCFX5XgZXcgbRIcMVVYGC6Jye0dRng==} + engines: {node: '>=14.0.0'} + + '@azure/abort-controller@1.1.0': + resolution: {integrity: sha512-TrRLIoSQVzfAJX9H1JeFjzAoDGcoK1IYX1UImfceTZpsyYfWr09Ss1aHW1y5TrrR3iq6RZLBwJ3E24uwPhwahw==} + engines: {node: '>=12.0.0'} + + '@azure/abort-controller@2.1.2': + resolution: {integrity: sha512-nBrLsEWm4J2u5LpAPjxADTlq3trDgVZZXHNKabeXZtpq3d3AbN/KGO82R87rdDz5/lYB024rtEf10/q0urNgsA==} + engines: {node: '>=18.0.0'} + + '@azure/core-auth@1.7.2': + resolution: {integrity: sha512-Igm/S3fDYmnMq1uKS38Ae1/m37B3zigdlZw+kocwEhh5GjyKjPrXKO2J6rzpC1wAxrNil/jX9BJRqBshyjnF3g==} + engines: {node: '>=18.0.0'} + + '@azure/core-http@3.0.4': + resolution: {integrity: sha512-Fok9VVhMdxAFOtqiiAtg74fL0UJkt0z3D+ouUUxcRLzZNBioPRAMJFVxiWoJljYpXsRi4GDQHzQHDc9AiYaIUQ==} + engines: {node: '>=14.0.0'} + + '@azure/core-lro@2.5.1': + resolution: {integrity: sha512-JHQy/bA3NOz2WuzOi5zEk6n/TJdAropupxUT521JIJvW7EXV2YN2SFYZrf/2RHeD28QAClGdynYadZsbmP+nyQ==} + engines: {node: '>=14.0.0'} + + '@azure/core-paging@1.5.0': + resolution: {integrity: sha512-zqWdVIt+2Z+3wqxEOGzR5hXFZ8MGKK52x4vFLw8n58pR6ZfKRx3EXYTxTaYxYHc/PexPUTyimcTWFJbji9Z6Iw==} + engines: {node: '>=14.0.0'} + + '@azure/core-rest-pipeline@1.10.1': + resolution: {integrity: sha512-Kji9k6TOFRDB5ZMTw8qUf2IJ+CeJtsuMdAHox9eqpTf1cefiNMpzrfnF6sINEBZJsaVaWgQ0o48B6kcUH68niA==} + engines: {node: '>=14.0.0'} + + '@azure/core-tracing@1.0.0-preview.13': + resolution: {integrity: sha512-KxDlhXyMlh2Jhj2ykX6vNEU0Vou4nHr025KoSEiz7cS3BNiHNaZcdECk/DmLkEB0as5T7b/TpRcehJ5yV6NeXQ==} + engines: {node: '>=12.0.0'} + + '@azure/core-tracing@1.0.1': + resolution: {integrity: sha512-I5CGMoLtX+pI17ZdiFJZgxMJApsK6jjfm85hpgp3oazCdq5Wxgh4wMr7ge/TTWW1B5WBuvIOI1fMU/FrOAMKrw==} + engines: {node: '>=12.0.0'} + + '@azure/core-util@1.2.0': + resolution: {integrity: sha512-ffGIw+Qs8bNKNLxz5UPkz4/VBM/EZY07mPve1ZYFqYUdPwFqRj0RPk0U7LZMOfT7GCck9YjuT1Rfp1PApNl1ng==} + engines: {node: '>=14.0.0'} + + '@azure/logger@1.0.4': + resolution: {integrity: sha512-ustrPY8MryhloQj7OWGe+HrYx+aoiOxzbXTtgblbV3xwCqpzUK36phH3XNHQKj3EPonyFUuDTfR3qFhTEAuZEg==} + engines: {node: '>=14.0.0'} + + '@azure/msal-common@14.7.1': + resolution: {integrity: sha512-v96btzjM7KrAu4NSEdOkhQSTGOuNUIIsUdB8wlyB9cdgl5KqEKnTonHUZ8+khvZ6Ap542FCErbnTyDWl8lZ2rA==} + engines: {node: '>=0.8.0'} + + '@azure/msal-node@2.6.4': + resolution: {integrity: sha512-nNvEPx009/80UATCToF+29NZYocn01uKrB91xtFr7bSqkqO1PuQGXRyYwryWRztUrYZ1YsSbw9A+LmwOhpVvcg==} + engines: {node: '>=16'} + + '@azure/opentelemetry-instrumentation-azure-sdk@1.0.0-beta.5': + resolution: {integrity: sha512-fsUarKQDvjhmBO4nIfaZkfNSApm1hZBzcvpNbSrXdcUBxu7lRvKsV5DnwszX7cnhLyVOW9yl1uigtRQ1yDANjA==} + engines: {node: '>=14.0.0'} + + '@azure/storage-blob@12.17.0': + resolution: {integrity: sha512-sM4vpsCpcCApagRW5UIjQNlNylo02my2opgp0Emi8x888hZUvJ3dN69Oq20cEGXkMUWnoCrBaB0zyS3yeB87sQ==} + engines: {node: '>=14.0.0'} + + '@babel/code-frame@7.22.5': + resolution: {integrity: sha512-Xmwn266vad+6DAqEB2A6V/CcZVp62BbwVmcOJc2RPuwih1kw02TjQvWVWlcKGbBPd+8/0V5DEkOcizRGYsspYQ==} + engines: {node: '>=6.9.0'} + + '@babel/code-frame@7.24.2': + resolution: {integrity: sha512-y5+tLQyV8pg3fsiln67BVLD1P13Eg4lh5RW9mF0zUuvLrv9uIQ4MCL+CRT+FTsBlBjcIan6PGsLcBN0m3ClUyQ==} + engines: {node: '>=6.9.0'} + + '@babel/compat-data@7.24.4': + resolution: {integrity: sha512-vg8Gih2MLK+kOkHJp4gBEIkyaIi00jgWot2D9QOmmfLC8jINSOzmCLta6Bvz/JSBCqnegV0L80jhxkol5GWNfQ==} + engines: {node: '>=6.9.0'} + + '@babel/core@7.12.9': + resolution: {integrity: sha512-gTXYh3M5wb7FRXQy+FErKFAv90BnlOuNn1QkCK2lREoPAjrQCO49+HVSrFoe5uakFAF5eenS75KbO2vQiLrTMQ==} + engines: {node: '>=6.9.0'} + + '@babel/core@7.24.4': + resolution: {integrity: sha512-MBVlMXP+kkl5394RBLSxxk/iLTeVGuXTV3cIDXavPpMMqnSnt6apKgan/U8O3USWZCWZT/TbgfEpKa4uMgN4Dg==} + engines: {node: '>=6.9.0'} + + '@babel/generator@7.20.4': + resolution: {integrity: sha512-luCf7yk/cm7yab6CAW1aiFnmEfBJplb/JojV56MYEK7ziWfGmFlTfmL9Ehwfy4gFhbjBfWO1wj7/TuSbVNEEtA==} + engines: {node: '>=6.9.0'} + + '@babel/generator@7.24.4': + resolution: {integrity: sha512-Xd6+v6SnjWVx/nus+y0l1sxMOTOMBkyL4+BIdbALyatQnAe/SRVjANeDPSCYaX+i1iJmuGSKf3Z+E+V/va1Hvw==} + engines: {node: '>=6.9.0'} + + '@babel/helper-compilation-targets@7.23.6': + resolution: {integrity: sha512-9JB548GZoQVmzrFgp8o7KxdgkTGm6xs9DW0o/Pim72UDjzr5ObUQ6ZzYPqA+g9OTS2bBQoctLJrky0RDCAWRgQ==} + engines: {node: '>=6.9.0'} + + '@babel/helper-environment-visitor@7.22.20': + resolution: {integrity: sha512-zfedSIzFhat/gFhWfHtgWvlec0nqB9YEIVrpuwjruLlXfUSnA8cJB0miHKwqDnQ7d32aKo2xt88/xZptwxbfhA==} + engines: {node: '>=6.9.0'} + + '@babel/helper-function-name@7.23.0': + resolution: {integrity: sha512-OErEqsrxjZTJciZ4Oo+eoZqeW9UIiOcuYKRJA4ZAgV9myA+pOXhhmpfNCKjEH/auVfEYVFJ6y1Tc4r0eIApqiw==} + engines: {node: '>=6.9.0'} + + '@babel/helper-hoist-variables@7.22.5': + resolution: {integrity: sha512-wGjk9QZVzvknA6yKIUURb8zY3grXCcOZt+/7Wcy8O2uctxhplmUPkOdlgoNhmdVee2c92JXbf1xpMtVNbfoxRw==} + engines: {node: '>=6.9.0'} + + '@babel/helper-module-imports@7.24.3': + resolution: {integrity: sha512-viKb0F9f2s0BCS22QSF308z/+1YWKV/76mwt61NBzS5izMzDPwdq1pTrzf+Li3npBWX9KdQbkeCt1jSAM7lZqg==} + engines: {node: '>=6.9.0'} + + '@babel/helper-module-transforms@7.23.3': + resolution: {integrity: sha512-7bBs4ED9OmswdfDzpz4MpWgSrV7FXlc3zIagvLFjS5H+Mk7Snr21vQ6QwrsoCGMfNC4e4LQPdoULEt4ykz0SRQ==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0 + + '@babel/helper-plugin-utils@7.10.4': + resolution: {integrity: sha512-O4KCvQA6lLiMU9l2eawBPMf1xPP8xPfB3iEQw150hOVTqj/rfXz0ThTb4HEzqQfs2Bmo5Ay8BzxfzVtBrr9dVg==} + + '@babel/helper-plugin-utils@7.20.2': + resolution: {integrity: sha512-8RvlJG2mj4huQ4pZ+rU9lqKi9ZKiRmuvGuM2HlWmkmgOhbs6zEAw6IEiJ5cQqGbDzGZOhwuOQNtZMi/ENLjZoQ==} + engines: {node: '>=6.9.0'} + + '@babel/helper-simple-access@7.22.5': + resolution: {integrity: sha512-n0H99E/K+Bika3++WNL17POvo4rKWZ7lZEp1Q+fStVbUi8nxPQEBOlTmCOxW/0JsS56SKKQ+ojAe2pHKJHN35w==} + engines: {node: '>=6.9.0'} + + '@babel/helper-split-export-declaration@7.22.6': + resolution: {integrity: sha512-AsUnxuLhRYsisFiaJwvp1QF+I3KjD5FOxut14q/GzovUe6orHLesW2C7d754kRm53h5gqrz6sFl6sxc4BVtE/g==} + engines: {node: '>=6.9.0'} + + '@babel/helper-string-parser@7.19.4': + resolution: {integrity: sha512-nHtDoQcuqFmwYNYPz3Rah5ph2p8PFeFCsZk9A/48dPc/rGocJ5J3hAAZ7pb76VWX3fZKu+uEr/FhH5jLx7umrw==} + engines: {node: '>=6.9.0'} + + '@babel/helper-string-parser@7.23.4': + resolution: {integrity: sha512-803gmbQdqwdf4olxrX4AJyFBV/RTr3rSmOj0rKwesmzlfhYNDEs+/iOcznzpNWlJlIlTJC2QfPFcHB6DlzdVLQ==} + engines: {node: '>=6.9.0'} + + '@babel/helper-validator-identifier@7.22.20': + resolution: {integrity: sha512-Y4OZ+ytlatR8AI+8KZfKuL5urKp7qey08ha31L8b3BwewJAoJamTzyvxPR/5D+KkdJCGPq/+8TukHBlY10FX9A==} + engines: {node: '>=6.9.0'} + + '@babel/helper-validator-identifier@7.22.5': + resolution: {integrity: sha512-aJXu+6lErq8ltp+JhkJUfk1MTGyuA4v7f3pA+BJ5HLfNC6nAQ0Cpi9uOquUj8Hehg0aUiHzWQbOVJGao6ztBAQ==} + engines: {node: '>=6.9.0'} + + '@babel/helper-validator-option@7.23.5': + resolution: {integrity: sha512-85ttAOMLsr53VgXkTbkx8oA6YTfT4q7/HzXSLEYmjcSTJPMPQtvq1BD79Byep5xMUYbGRzEpDsjUf3dyp54IKw==} + engines: {node: '>=6.9.0'} + + '@babel/helpers@7.24.4': + resolution: {integrity: sha512-FewdlZbSiwaVGlgT1DPANDuCHaDMiOo+D/IDYRFYjHOuv66xMSJ7fQwwODwRNAPkADIO/z1EoF/l2BCWlWABDw==} + engines: {node: '>=6.9.0'} + + '@babel/highlight@7.22.5': + resolution: {integrity: sha512-BSKlD1hgnedS5XRnGOljZawtag7H1yPfQp0tdNJCHoH6AZ+Pcm9VvkrK59/Yy593Ypg0zMxH2BxD1VPYUQ7UIw==} + engines: {node: '>=6.9.0'} + + '@babel/highlight@7.24.2': + resolution: {integrity: sha512-Yac1ao4flkTxTteCDZLEvdxg2fZfz1v8M4QpaGypq/WPDqg3ijHYbDfs+LG5hvzSoqaSZ9/Z9lKSP3CjZjv+pA==} + engines: {node: '>=6.9.0'} + + '@babel/parser@7.24.0': + resolution: {integrity: sha512-QuP/FxEAzMSjXygs8v4N9dvdXzEHN4W1oF3PxuWAtPo08UdM17u89RDMgjLn/mlc56iM0HlLmVkO/wgR+rDgHg==} + engines: {node: '>=6.0.0'} + hasBin: true + + '@babel/parser@7.24.4': + resolution: {integrity: sha512-zTvEBcghmeBma9QIGunWevvBAp4/Qu9Bdq+2k0Ot4fVMD6v3dsC9WOcRSKk7tRRyBM/53yKMJko9xOatGQAwSg==} + engines: {node: '>=6.0.0'} + hasBin: true + + '@babel/plugin-proposal-object-rest-spread@7.12.1': + resolution: {integrity: sha512-s6SowJIjzlhx8o7lsFx5zmY4At6CTtDvgNQDdPzkBQucle58A6b/TTeEBYtyDgmcXjUTM+vE8YOGHZzzbc/ioA==} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-syntax-async-generators@7.8.4': + resolution: {integrity: sha512-tycmZxkGfZaxhMRbXlPXuVFpdWlXpir2W4AMhSJgRKzk/eDlIXOhb2LHWoLpDF7TEHylV5zNhykX6KAgHJmTNw==} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-syntax-bigint@7.8.3': + resolution: {integrity: sha512-wnTnFlG+YxQm3vDxpGE57Pj0srRU4sHE/mDkt1qv2YJJSeUAec2ma4WLUnUPeKjyrfntVwe/N6dCXpU+zL3Npg==} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-syntax-class-properties@7.12.13': + resolution: {integrity: sha512-fm4idjKla0YahUNgFNLCB0qySdsoPiZP3iQE3rky0mBUtMZ23yDJ9SJdg6dXTSDnulOVqiF3Hgr9nbXvXTQZYA==} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-syntax-import-meta@7.10.4': + resolution: {integrity: sha512-Yqfm+XDx0+Prh3VSeEQCPU81yC+JWZ2pDPFSS4ZdpfZhp4MkFMaDC1UqseovEKwSUpnIL7+vK+Clp7bfh0iD7g==} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-syntax-json-strings@7.8.3': + resolution: {integrity: sha512-lY6kdGpWHvjoe2vk4WrAapEuBR69EMxZl+RoGRhrFGNYVK8mOPAW8VfbT/ZgrFbXlDNiiaxQnAtgVCZ6jv30EA==} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-syntax-jsx@7.12.1': + resolution: {integrity: sha512-1yRi7yAtB0ETgxdY9ti/p2TivUxJkTdhu/ZbF9MshVGqOx1TdB3b7xCXs49Fupgg50N45KcAsRP/ZqWjs9SRjg==} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-syntax-jsx@7.18.6': + resolution: {integrity: sha512-6mmljtAedFGTWu2p/8WIORGwy+61PLgOMPOdazc7YoJ9ZCWUyFy3A6CpPkRKLKD1ToAesxX8KGEViAiLo9N+7Q==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-syntax-logical-assignment-operators@7.10.4': + resolution: {integrity: sha512-d8waShlpFDinQ5MtvGU9xDAOzKH47+FFoney2baFIoMr952hKOLp1HR7VszoZvOsV/4+RRszNY7D17ba0te0ig==} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-syntax-nullish-coalescing-operator@7.8.3': + resolution: {integrity: sha512-aSff4zPII1u2QD7y+F8oDsz19ew4IGEJg9SVW+bqwpwtfFleiQDMdzA/R+UlWDzfnHFCxxleFT0PMIrR36XLNQ==} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-syntax-numeric-separator@7.10.4': + resolution: {integrity: sha512-9H6YdfkcK/uOnY/K7/aA2xpzaAgkQn37yzWUMRK7OaPOqOpGS1+n0H5hxT9AUw9EsSjPW8SVyMJwYRtWs3X3ug==} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-syntax-object-rest-spread@7.8.3': + resolution: {integrity: sha512-XoqMijGZb9y3y2XskN+P1wUGiVwWZ5JmoDRwx5+3GmEplNyVM2s2Dg8ILFQm8rWM48orGy5YpI5Bl8U1y7ydlA==} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-syntax-optional-catch-binding@7.8.3': + resolution: {integrity: sha512-6VPD0Pc1lpTqw0aKoeRTMiB+kWhAoT24PA+ksWSBrFtl5SIRVpZlwN3NNPQjehA2E/91FV3RjLWoVTglWcSV3Q==} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-syntax-optional-chaining@7.8.3': + resolution: {integrity: sha512-KoK9ErH1MBlCPxV0VANkXW2/dw4vlbGDrFgz8bmUsBGYkFRcbRwMh6cIJubdPrkxRwuGdtCk0v/wPTKbQgBjkg==} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-syntax-top-level-await@7.14.5': + resolution: {integrity: sha512-hx++upLv5U1rgYfwe1xBQUhRmU41NEvpUvrp8jkrSCdvGSnM5/qdRMtylJ6PG5OFkBaHkbTAKTnd3/YyESRHFw==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-syntax-typescript@7.18.6': + resolution: {integrity: sha512-mAWAuq4rvOepWCBid55JuRNvpTNf2UGVgoz4JV0fXEKolsVZDzsa4NqCef758WZJj/GDu0gVGItjKFiClTAmZA==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-parameters@7.20.3': + resolution: {integrity: sha512-oZg/Fpx0YDrj13KsLyO8I/CX3Zdw7z0O9qOd95SqcoIzuqy/WTGWvePeHAnZCN54SfdyjHcb1S30gc8zlzlHcA==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/runtime@7.17.9': + resolution: {integrity: sha512-lSiBBvodq29uShpWGNbgFdKYNiFDo5/HIYsaCEY9ff4sb10x9jizo2+pRrSyF4jKZCXqgzuqBOQKbUm90gQwJg==} + engines: {node: '>=6.9.0'} + + '@babel/runtime@7.19.4': + resolution: {integrity: sha512-EXpLCrk55f+cYqmHsSR+yD/0gAIMxxA9QK9lnQWzhMCvt+YmoBN7Zx94s++Kv0+unHk39vxNO8t+CMA2WSS3wA==} + engines: {node: '>=6.9.0'} + + '@babel/runtime@7.21.0': + resolution: {integrity: sha512-xwII0//EObnq89Ji5AKYQaRYiW/nZ3llSv29d49IuxPhKbtJoLP+9QUUZ4nVragQVtaVGeZrpB+ZtG/Pdy/POw==} + engines: {node: '>=6.9.0'} + + '@babel/runtime@7.24.4': + resolution: {integrity: sha512-dkxf7+hn8mFBwKjs9bvBlArzLVxVbS8usaPUDd5p2a9JCL9tB8OaOVN1isD4+Xyk4ns89/xeOmbQvgdK7IIVdA==} + engines: {node: '>=6.9.0'} + + '@babel/template@7.18.10': + resolution: {integrity: sha512-TI+rCtooWHr3QJ27kJxfjutghu44DLnasDMwpDqCXVTal9RLp3RSYNh4NdBrRP2cQAoG9A8juOQl6P6oZG4JxA==} + engines: {node: '>=6.9.0'} + + '@babel/template@7.24.0': + resolution: {integrity: sha512-Bkf2q8lMB0AFpX0NFEqSbx1OkTHf0f+0j82mkw+ZpzBnkk7e9Ql0891vlfgi+kHwOk8tQjiQHpqh4LaSa0fKEA==} + engines: {node: '>=6.9.0'} + + '@babel/traverse@7.24.1': + resolution: {integrity: sha512-xuU6o9m68KeqZbQuDt2TcKSxUw/mrsvavlEqQ1leZ/B+C9tk6E4sRWy97WaXgvq5E+nU3cXMxv3WKOCanVMCmQ==} + engines: {node: '>=6.9.0'} + + '@babel/types@7.20.2': + resolution: {integrity: sha512-FnnvsNWgZCr232sqtXggapvlkk/tuwR/qhGzcmxI0GXLCjmPYQPzio2FbdlWuY6y1sHFfQKk+rRbUZ9VStQMog==} + engines: {node: '>=6.9.0'} + + '@babel/types@7.24.0': + resolution: {integrity: sha512-+j7a5c253RfKh8iABBhywc8NSfP5LURe7Uh4qpsh6jc+aLJguvmIUBdjSdEMQv2bENrCR5MfRdjGo7vzS/ob7w==} + engines: {node: '>=6.9.0'} + + '@bcoe/v8-coverage@0.2.3': + resolution: {integrity: sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==} + + '@cbor-extract/cbor-extract-darwin-arm64@2.2.0': + resolution: {integrity: sha512-P7swiOAdF7aSi0H+tHtHtr6zrpF3aAq/W9FXx5HektRvLTM2O89xCyXF3pk7pLc7QpaY7AoaE8UowVf9QBdh3w==} + cpu: [arm64] + os: [darwin] + + '@cbor-extract/cbor-extract-darwin-x64@2.2.0': + resolution: {integrity: sha512-1liF6fgowph0JxBbYnAS7ZlqNYLf000Qnj4KjqPNW4GViKrEql2MgZnAsExhY9LSy8dnvA4C0qHEBgPrll0z0w==} + cpu: [x64] + os: [darwin] + + '@cbor-extract/cbor-extract-linux-arm64@2.2.0': + resolution: {integrity: sha512-rQvhNmDuhjTVXSPFLolmQ47/ydGOFXtbR7+wgkSY0bdOxCFept1hvg59uiLPT2fVDuJFuEy16EImo5tE2x3RsQ==} + cpu: [arm64] + os: [linux] + + '@cbor-extract/cbor-extract-linux-arm@2.2.0': + resolution: {integrity: sha512-QeBcBXk964zOytiedMPQNZr7sg0TNavZeuUCD6ON4vEOU/25+pLhNN6EDIKJ9VLTKaZ7K7EaAriyYQ1NQ05s/Q==} + cpu: [arm] + os: [linux] + + '@cbor-extract/cbor-extract-linux-x64@2.2.0': + resolution: {integrity: sha512-cWLAWtT3kNLHSvP4RKDzSTX9o0wvQEEAj4SKvhWuOVZxiDAeQazr9A+PSiRILK1VYMLeDml89ohxCnUNQNQNCw==} + cpu: [x64] + os: [linux] + + '@cbor-extract/cbor-extract-win32-x64@2.2.0': + resolution: {integrity: sha512-l2M+Z8DO2vbvADOBNLbbh9y5ST1RY5sqkWOg/58GkUPBYou/cuNZ68SGQ644f1CvZ8kcOxyZtw06+dxWHIoN/w==} + cpu: [x64] + os: [win32] + + '@changesets/apply-release-plan@6.1.4': + resolution: {integrity: sha512-FMpKF1fRlJyCZVYHr3CbinpZZ+6MwvOtWUuO8uo+svcATEoc1zRDcj23pAurJ2TZ/uVz1wFHH6K3NlACy0PLew==} + + '@changesets/assemble-release-plan@5.2.4': + resolution: {integrity: sha512-xJkWX+1/CUaOUWTguXEbCDTyWJFECEhmdtbkjhn5GVBGxdP/JwaHBIU9sW3FR6gD07UwZ7ovpiPclQZs+j+mvg==} + + '@changesets/changelog-git@0.1.14': + resolution: {integrity: sha512-+vRfnKtXVWsDDxGctOfzJsPhaCdXRYoe+KyWYoq5X/GqoISREiat0l3L8B0a453B2B4dfHGcZaGyowHbp9BSaA==} + + '@changesets/cli@2.26.2': + resolution: {integrity: sha512-dnWrJTmRR8bCHikJHl9b9HW3gXACCehz4OasrXpMp7sx97ECuBGGNjJhjPhdZNCvMy9mn4BWdplI323IbqsRig==} + hasBin: true + + '@changesets/config@2.3.1': + resolution: {integrity: sha512-PQXaJl82CfIXddUOppj4zWu+987GCw2M+eQcOepxN5s+kvnsZOwjEJO3DH9eVy+OP6Pg/KFEWdsECFEYTtbg6w==} + + '@changesets/errors@0.1.4': + resolution: {integrity: sha512-HAcqPF7snsUJ/QzkWoKfRfXushHTu+K5KZLJWPb34s4eCZShIf8BFO3fwq6KU8+G7L5KdtN2BzQAXOSXEyiY9Q==} + + '@changesets/get-dependents-graph@1.3.6': + resolution: {integrity: sha512-Q/sLgBANmkvUm09GgRsAvEtY3p1/5OCzgBE5vX3vgb5CvW0j7CEljocx5oPXeQSNph6FXulJlXV3Re/v3K3P3Q==} + + '@changesets/get-release-plan@3.0.17': + resolution: {integrity: sha512-6IwKTubNEgoOZwDontYc2x2cWXfr6IKxP3IhKeK+WjyD6y3M4Gl/jdQvBw+m/5zWILSOCAaGLu2ZF6Q+WiPniw==} + + '@changesets/get-version-range-type@0.3.2': + resolution: {integrity: sha512-SVqwYs5pULYjYT4op21F2pVbcrca4qA/bAA3FmFXKMN7Y+HcO8sbZUTx3TAy2VXulP2FACd1aC7f2nTuqSPbqg==} + + '@changesets/git@2.0.0': + resolution: {integrity: sha512-enUVEWbiqUTxqSnmesyJGWfzd51PY4H7mH9yUw0hPVpZBJ6tQZFMU3F3mT/t9OJ/GjyiM4770i+sehAn6ymx6A==} + + '@changesets/logger@0.0.5': + resolution: {integrity: sha512-gJyZHomu8nASHpaANzc6bkQMO9gU/ib20lqew1rVx753FOxffnCrJlGIeQVxNWCqM+o6OOleCo/ivL8UAO5iFw==} + + '@changesets/parse@0.3.16': + resolution: {integrity: sha512-127JKNd167ayAuBjUggZBkmDS5fIKsthnr9jr6bdnuUljroiERW7FBTDNnNVyJ4l69PzR57pk6mXQdtJyBCJKg==} + + '@changesets/pre@1.0.14': + resolution: {integrity: sha512-dTsHmxQWEQekHYHbg+M1mDVYFvegDh9j/kySNuDKdylwfMEevTeDouR7IfHNyVodxZXu17sXoJuf2D0vi55FHQ==} + + '@changesets/read@0.5.9': + resolution: {integrity: sha512-T8BJ6JS6j1gfO1HFq50kU3qawYxa4NTbI/ASNVVCBTsKquy2HYwM9r7ZnzkiMe8IEObAJtUVGSrePCOxAK2haQ==} + + '@changesets/types@4.1.0': + resolution: {integrity: sha512-LDQvVDv5Kb50ny2s25Fhm3d9QSZimsoUGBsUioj6MC3qbMUCuC8GPIvk/M6IvXx3lYhAs0lwWUQLb+VIEUCECw==} + + '@changesets/types@5.2.1': + resolution: {integrity: sha512-myLfHbVOqaq9UtUKqR/nZA/OY7xFjQMdfgfqeZIBK4d0hA6pgxArvdv8M+6NUzzBsjWLOtvApv8YHr4qM+Kpfg==} + + '@changesets/write@0.2.3': + resolution: {integrity: sha512-Dbamr7AIMvslKnNYsLFafaVORx4H0pvCA2MHqgtNCySMe1blImEyAEOzDmcgKAkgz4+uwoLz7demIrX+JBr/Xw==} + + '@commitlint/cli@19.0.3': + resolution: {integrity: sha512-mGhh/aYPib4Vy4h+AGRloMY+CqkmtdeKPV9poMcZeImF5e3knQ5VYaSeAM0mEzps1dbKsHvABwaDpafLUuM96g==} + engines: {node: '>=v18'} + hasBin: true + + '@commitlint/config-conventional@19.0.3': + resolution: {integrity: sha512-vh0L8XeLaEzTe8VCxSd0gAFvfTK0RFolrzw4o431bIuWJfi/yRCHJlsDwus7wW2eJaFFDR0VFXJyjGyDQhi4vA==} + engines: {node: '>=v18'} + + '@commitlint/config-validator@19.0.3': + resolution: {integrity: sha512-2D3r4PKjoo59zBc2auodrSCaUnCSALCx54yveOFwwP/i2kfEAQrygwOleFWswLqK0UL/F9r07MFi5ev2ohyM4Q==} + engines: {node: '>=v18'} + + '@commitlint/ensure@19.0.3': + resolution: {integrity: sha512-SZEpa/VvBLoT+EFZVb91YWbmaZ/9rPH3ESrINOl0HD2kMYsjvl0tF7nMHh0EpTcv4+gTtZBAe1y/SS6/OhfZzQ==} + engines: {node: '>=v18'} + + '@commitlint/execute-rule@19.0.0': + resolution: {integrity: sha512-mtsdpY1qyWgAO/iOK0L6gSGeR7GFcdW7tIjcNFxcWkfLDF5qVbPHKuGATFqRMsxcO8OUKNj0+3WOHB7EHm4Jdw==} + engines: {node: '>=v18'} + + '@commitlint/format@19.0.3': + resolution: {integrity: sha512-QjjyGyoiVWzx1f5xOteKHNLFyhyweVifMgopozSgx1fGNrGV8+wp7k6n1t6StHdJ6maQJ+UUtO2TcEiBFRyR6Q==} + engines: {node: '>=v18'} + + '@commitlint/is-ignored@19.0.3': + resolution: {integrity: sha512-MqDrxJaRSVSzCbPsV6iOKG/Lt52Y+PVwFVexqImmYYFhe51iVJjK2hRhOG2jUAGiUHk4jpdFr0cZPzcBkSzXDQ==} + engines: {node: '>=v18'} + + '@commitlint/lint@19.0.3': + resolution: {integrity: sha512-uHPyRqIn57iIplYa5xBr6oNu5aPXKGC4WLeuHfqQHclwIqbJ33g3yA5fIA+/NYnp5ZM2EFiujqHFaVUYj6HlKA==} + engines: {node: '>=v18'} + + '@commitlint/load@19.0.3': + resolution: {integrity: sha512-18Tk/ZcDFRKIoKfEcl7kC+bYkEQ055iyKmGsYDoYWpKf6FUvBrP9bIWapuy/MB+kYiltmP9ITiUx6UXtqC9IRw==} + engines: {node: '>=v18'} + + '@commitlint/message@19.0.0': + resolution: {integrity: sha512-c9czf6lU+9oF9gVVa2lmKaOARJvt4soRsVmbR7Njwp9FpbBgste5i7l/2l5o8MmbwGh4yE1snfnsy2qyA2r/Fw==} + engines: {node: '>=v18'} + + '@commitlint/parse@19.0.3': + resolution: {integrity: sha512-Il+tNyOb8VDxN3P6XoBBwWJtKKGzHlitEuXA5BP6ir/3loWlsSqDr5aecl6hZcC/spjq4pHqNh0qPlfeWu38QA==} + engines: {node: '>=v18'} + + '@commitlint/read@19.0.3': + resolution: {integrity: sha512-b5AflTyAXkUx5qKw4TkjjcOccXZHql3JqMi522knTQktq2AubKXFz60Sws+K4FsefwPws6fGz9mqiI/NvsvxFA==} + engines: {node: '>=v18'} + + '@commitlint/resolve-extends@19.0.3': + resolution: {integrity: sha512-18BKmta8OC8+Ub+Q3QGM9l27VjQaXobloVXOrMvu8CpEwJYv62vC/t7Ka5kJnsW0tU9q1eMqJFZ/nN9T/cOaIA==} + engines: {node: '>=v18'} + + '@commitlint/rules@19.0.3': + resolution: {integrity: sha512-TspKb9VB6svklxNCKKwxhELn7qhtY1rFF8ls58DcFd0F97XoG07xugPjjbVnLqmMkRjZDbDIwBKt9bddOfLaPw==} + engines: {node: '>=v18'} + + '@commitlint/to-lines@19.0.0': + resolution: {integrity: sha512-vkxWo+VQU5wFhiP9Ub9Sre0FYe019JxFikrALVoD5UGa8/t3yOJEpEhxC5xKiENKKhUkTpEItMTRAjHw2SCpZw==} + engines: {node: '>=v18'} + + '@commitlint/top-level@19.0.0': + resolution: {integrity: sha512-KKjShd6u1aMGNkCkaX4aG1jOGdn7f8ZI8TR1VEuNqUOjWTOdcDSsmglinglJ18JTjuBX5I1PtjrhQCRcixRVFQ==} + engines: {node: '>=v18'} + + '@commitlint/types@19.0.3': + resolution: {integrity: sha512-tpyc+7i6bPG9mvaBbtKUeghfyZSDgWquIDfMgqYtTbmZ9Y9VzEm2je9EYcQ0aoz5o7NvGS+rcDec93yO08MHYA==} + engines: {node: '>=v18'} + + '@cspotcode/source-map-support@0.8.1': + resolution: {integrity: sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==} + engines: {node: '>=12'} + + '@csstools/css-parser-algorithms@2.6.1': + resolution: {integrity: sha512-ubEkAaTfVZa+WwGhs5jbo5Xfqpeaybr/RvWzvFxRs4jfq16wH8l8Ty/QEEpINxll4xhuGfdMbipRyz5QZh9+FA==} + engines: {node: ^14 || ^16 || >=18} + peerDependencies: + '@csstools/css-tokenizer': ^2.2.4 + + '@csstools/css-tokenizer@2.2.4': + resolution: {integrity: sha512-PuWRAewQLbDhGeTvFuq2oClaSCKPIBmHyIobCV39JHRYN0byDcUWJl5baPeNUcqrjtdMNqFooE0FGl31I3JOqw==} + engines: {node: ^14 || ^16 || >=18} + + '@csstools/media-query-list-parser@2.1.9': + resolution: {integrity: sha512-qqGuFfbn4rUmyOB0u8CVISIp5FfJ5GAR3mBrZ9/TKndHakdnm6pY0L/fbLcpPnrzwCyyTEZl1nUcXAYHEWneTA==} + engines: {node: ^14 || ^16 || >=18} + peerDependencies: + '@csstools/css-parser-algorithms': ^2.6.1 + '@csstools/css-tokenizer': ^2.2.4 + + '@csstools/selector-specificity@3.0.3': + resolution: {integrity: sha512-KEPNw4+WW5AVEIyzC80rTbWEUatTW2lXpN8+8ILC8PiPeWPjwUzrPZDIOZ2wwqDmeqOYTdSGyL3+vE5GC3FB3Q==} + engines: {node: ^14 || ^16 || >=18} + peerDependencies: + postcss-selector-parser: ^6.0.13 + + '@esbuild/aix-ppc64@0.20.2': + resolution: {integrity: sha512-D+EBOJHXdNZcLJRBkhENNG8Wji2kgc9AZ9KiPr1JuZjsNtyHzrsfLRrY0tk2H2aoFu6RANO1y1iPPUCDYWkb5g==} + engines: {node: '>=12'} + cpu: [ppc64] + os: [aix] + + '@esbuild/android-arm64@0.20.2': + resolution: {integrity: sha512-mRzjLacRtl/tWU0SvD8lUEwb61yP9cqQo6noDZP/O8VkwafSYwZ4yWy24kan8jE/IMERpYncRt2dw438LP3Xmg==} + engines: {node: '>=12'} + cpu: [arm64] + os: [android] + + '@esbuild/android-arm@0.20.2': + resolution: {integrity: sha512-t98Ra6pw2VaDhqNWO2Oph2LXbz/EJcnLmKLGBJwEwXX/JAN83Fym1rU8l0JUWK6HkIbWONCSSatf4sf2NBRx/w==} + engines: {node: '>=12'} + cpu: [arm] + os: [android] + + '@esbuild/android-x64@0.20.2': + resolution: {integrity: sha512-btzExgV+/lMGDDa194CcUQm53ncxzeBrWJcncOBxuC6ndBkKxnHdFJn86mCIgTELsooUmwUm9FkhSp5HYu00Rg==} + engines: {node: '>=12'} + cpu: [x64] + os: [android] + + '@esbuild/darwin-arm64@0.20.2': + resolution: {integrity: sha512-4J6IRT+10J3aJH3l1yzEg9y3wkTDgDk7TSDFX+wKFiWjqWp/iCfLIYzGyasx9l0SAFPT1HwSCR+0w/h1ES/MjA==} + engines: {node: '>=12'} + cpu: [arm64] + os: [darwin] + + '@esbuild/darwin-x64@0.20.2': + resolution: {integrity: sha512-tBcXp9KNphnNH0dfhv8KYkZhjc+H3XBkF5DKtswJblV7KlT9EI2+jeA8DgBjp908WEuYll6pF+UStUCfEpdysA==} + engines: {node: '>=12'} + cpu: [x64] + os: [darwin] + + '@esbuild/freebsd-arm64@0.20.2': + resolution: {integrity: sha512-d3qI41G4SuLiCGCFGUrKsSeTXyWG6yem1KcGZVS+3FYlYhtNoNgYrWcvkOoaqMhwXSMrZRl69ArHsGJ9mYdbbw==} + engines: {node: '>=12'} + cpu: [arm64] + os: [freebsd] + + '@esbuild/freebsd-x64@0.20.2': + resolution: {integrity: sha512-d+DipyvHRuqEeM5zDivKV1KuXn9WeRX6vqSqIDgwIfPQtwMP4jaDsQsDncjTDDsExT4lR/91OLjRo8bmC1e+Cw==} + engines: {node: '>=12'} + cpu: [x64] + os: [freebsd] + + '@esbuild/linux-arm64@0.20.2': + resolution: {integrity: sha512-9pb6rBjGvTFNira2FLIWqDk/uaf42sSyLE8j1rnUpuzsODBq7FvpwHYZxQ/It/8b+QOS1RYfqgGFNLRI+qlq2A==} + engines: {node: '>=12'} + cpu: [arm64] + os: [linux] + + '@esbuild/linux-arm@0.20.2': + resolution: {integrity: sha512-VhLPeR8HTMPccbuWWcEUD1Az68TqaTYyj6nfE4QByZIQEQVWBB8vup8PpR7y1QHL3CpcF6xd5WVBU/+SBEvGTg==} + engines: {node: '>=12'} + cpu: [arm] + os: [linux] + + '@esbuild/linux-ia32@0.20.2': + resolution: {integrity: sha512-o10utieEkNPFDZFQm9CoP7Tvb33UutoJqg3qKf1PWVeeJhJw0Q347PxMvBgVVFgouYLGIhFYG0UGdBumROyiig==} + engines: {node: '>=12'} + cpu: [ia32] + os: [linux] + + '@esbuild/linux-loong64@0.20.2': + resolution: {integrity: sha512-PR7sp6R/UC4CFVomVINKJ80pMFlfDfMQMYynX7t1tNTeivQ6XdX5r2XovMmha/VjR1YN/HgHWsVcTRIMkymrgQ==} + engines: {node: '>=12'} + cpu: [loong64] + os: [linux] + + '@esbuild/linux-mips64el@0.20.2': + resolution: {integrity: sha512-4BlTqeutE/KnOiTG5Y6Sb/Hw6hsBOZapOVF6njAESHInhlQAghVVZL1ZpIctBOoTFbQyGW+LsVYZ8lSSB3wkjA==} + engines: {node: '>=12'} + cpu: [mips64el] + os: [linux] + + '@esbuild/linux-ppc64@0.20.2': + resolution: {integrity: sha512-rD3KsaDprDcfajSKdn25ooz5J5/fWBylaaXkuotBDGnMnDP1Uv5DLAN/45qfnf3JDYyJv/ytGHQaziHUdyzaAg==} + engines: {node: '>=12'} + cpu: [ppc64] + os: [linux] + + '@esbuild/linux-riscv64@0.20.2': + resolution: {integrity: sha512-snwmBKacKmwTMmhLlz/3aH1Q9T8v45bKYGE3j26TsaOVtjIag4wLfWSiZykXzXuE1kbCE+zJRmwp+ZbIHinnVg==} + engines: {node: '>=12'} + cpu: [riscv64] + os: [linux] + + '@esbuild/linux-s390x@0.20.2': + resolution: {integrity: sha512-wcWISOobRWNm3cezm5HOZcYz1sKoHLd8VL1dl309DiixxVFoFe/o8HnwuIwn6sXre88Nwj+VwZUvJf4AFxkyrQ==} + engines: {node: '>=12'} + cpu: [s390x] + os: [linux] + + '@esbuild/linux-x64@0.20.2': + resolution: {integrity: sha512-1MdwI6OOTsfQfek8sLwgyjOXAu+wKhLEoaOLTjbijk6E2WONYpH9ZU2mNtR+lZ2B4uwr+usqGuVfFT9tMtGvGw==} + engines: {node: '>=12'} + cpu: [x64] + os: [linux] + + '@esbuild/netbsd-x64@0.20.2': + resolution: {integrity: sha512-K8/DhBxcVQkzYc43yJXDSyjlFeHQJBiowJ0uVL6Tor3jGQfSGHNNJcWxNbOI8v5k82prYqzPuwkzHt3J1T1iZQ==} + engines: {node: '>=12'} + cpu: [x64] + os: [netbsd] + + '@esbuild/openbsd-x64@0.20.2': + resolution: {integrity: sha512-eMpKlV0SThJmmJgiVyN9jTPJ2VBPquf6Kt/nAoo6DgHAoN57K15ZghiHaMvqjCye/uU4X5u3YSMgVBI1h3vKrQ==} + engines: {node: '>=12'} + cpu: [x64] + os: [openbsd] + + '@esbuild/sunos-x64@0.20.2': + resolution: {integrity: sha512-2UyFtRC6cXLyejf/YEld4Hajo7UHILetzE1vsRcGL3earZEW77JxrFjH4Ez2qaTiEfMgAXxfAZCm1fvM/G/o8w==} + engines: {node: '>=12'} + cpu: [x64] + os: [sunos] + + '@esbuild/win32-arm64@0.20.2': + resolution: {integrity: sha512-GRibxoawM9ZCnDxnP3usoUDO9vUkpAxIIZ6GQI+IlVmr5kP3zUq+l17xELTHMWTWzjxa2guPNyrpq1GWmPvcGQ==} + engines: {node: '>=12'} + cpu: [arm64] + os: [win32] + + '@esbuild/win32-ia32@0.20.2': + resolution: {integrity: sha512-HfLOfn9YWmkSKRQqovpnITazdtquEW8/SoHW7pWpuEeguaZI4QnCRW6b+oZTztdBnZOS2hqJ6im/D5cPzBTTlQ==} + engines: {node: '>=12'} + cpu: [ia32] + os: [win32] + + '@esbuild/win32-x64@0.20.2': + resolution: {integrity: sha512-N49X4lJX27+l9jbLKSqZ6bKNjzQvHaT8IIFUy+YIqmXQdjYCToGWwOItDrfby14c78aDd5NHQl29xingXfCdLQ==} + engines: {node: '>=12'} + cpu: [x64] + os: [win32] + + '@eslint-community/eslint-utils@4.4.0': + resolution: {integrity: sha512-1/sA4dwrzBAyeUoQ6oxahHKmrZvsnLCg4RfxW3ZFGGmQkSNQPFNLV9CUEFQP1x9EYXHTo5p6xdhZM1Ne9p/AfA==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + peerDependencies: + eslint: ^6.0.0 || ^7.0.0 || >=8.0.0 + + '@eslint-community/regexpp@4.10.0': + resolution: {integrity: sha512-Cu96Sd2By9mCNTx2iyKOmq10v22jUVQv0lQnlGNy16oE9589yE+QADPbrMGCkA51cKZSg3Pu/aTJVTGfL/qjUA==} + engines: {node: ^12.0.0 || ^14.0.0 || >=16.0.0} + + '@eslint/eslintrc@2.1.4': + resolution: {integrity: sha512-269Z39MS6wVJtsoUl10L60WdkhJVdPG24Q4eZTH3nnF6lpvSShEK3wQjDX9JRWAUPvPh7COouPpU9IrqaZFvtQ==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + + '@eslint/js@8.57.0': + resolution: {integrity: sha512-Ys+3g2TaW7gADOJzPt83SJtCDhMjndcDMFVQ/Tj9iA1BfJzFKD9mAUXT3OenpuPHbI6P/myECxRJrofUsDx/5g==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + + '@fontsource/roboto-mono@5.0.0': + resolution: {integrity: sha512-PNxomCUy0blr1gNkc2TXfm8zMqnTVAtYfVYKBss6pgjex7lHENhqdDslCPNLwJDDqqPsWgpQ6TrMWEh4OTAVxQ==} + + '@google-cloud/paginator@5.0.0': + resolution: {integrity: sha512-87aeg6QQcEPxGCOthnpUjvw4xAZ57G7pL8FS0C4e/81fr3FjkpUpibf1s2v5XGyGhUVGF4Jfg7yEcxqn2iUw1w==} + engines: {node: '>=14.0.0'} + + '@google-cloud/projectify@4.0.0': + resolution: {integrity: sha512-MmaX6HeSvyPbWGwFq7mXdo0uQZLGBYCwziiLIGq5JVX+/bdI3SAq6bP98trV5eTWfLuvsMcIC1YJOF2vfteLFA==} + engines: {node: '>=14.0.0'} + + '@google-cloud/promisify@4.0.0': + resolution: {integrity: sha512-Orxzlfb9c67A15cq2JQEyVc7wEsmFBmHjZWZYQMUyJ1qivXyMwdyNOs9odi79hze+2zqdTtu1E19IM/FtqZ10g==} + engines: {node: '>=14'} + + '@google-cloud/storage@7.10.0': + resolution: {integrity: sha512-aBNejLVzHpI7C8eJSMpBpfdq1lxvYuHqG+zy/xvs032RyPRxuu45DLMeXuAbgwyx1VBsxWGYifrPDx+O7hJrmw==} + engines: {node: '>=14'} + + '@hapi/hoek@9.3.0': + resolution: {integrity: sha512-/c6rf4UJlmHlC9b5BaNvzAcFv7HZ2QHaV0D4/HNlBdvFnvQq8RI4kYdhyPCl7Xj+oWvTWQ8ujhqS53LIgAe6KQ==} + + '@hapi/topo@5.1.0': + resolution: {integrity: sha512-foQZKJig7Ob0BMAYBfcJk8d77QtOe7Wo4ox7ff1lQYoNNAb6jwcY1ncdoy2e9wQZzvNy7ODZCYJkK8kzmcAnAg==} + + '@hexagon/base64@1.1.28': + resolution: {integrity: sha512-lhqDEAvWixy3bZ+UOYbPwUbBkwBq5C1LAJ/xPC8Oi+lL54oyakv/npbA0aU2hgCsx/1NUd4IBvV03+aUBWxerw==} + + '@humanwhocodes/config-array@0.11.14': + resolution: {integrity: sha512-3T8LkOmg45BV5FICb15QQMsyUSWrQ8AygVfC7ZG32zOalnqrilm018ZVCw0eapXux8FtA33q8PSRSstjee3jSg==} + engines: {node: '>=10.10.0'} + + '@humanwhocodes/module-importer@1.0.1': + resolution: {integrity: sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==} + engines: {node: '>=12.22'} + + '@humanwhocodes/object-schema@2.0.3': + resolution: {integrity: sha512-93zYdMES/c1D69yZiKDBj0V24vqNzB/koF26KPaagAfd3P/4gUlh3Dys5ogAK+Exi9QyzlD8x/08Zt7wIKcDcA==} + + '@icons/material@0.2.4': + resolution: {integrity: sha512-QPcGmICAPbGLGb6F/yNf/KzKqvFx8z5qx3D1yFqVAjoFmXK35EgyW+cJ57Te3CNsmzblwtzakLGFqHPqrfb4Tw==} + peerDependencies: + react: '*' + + '@isaacs/cliui@8.0.2': + resolution: {integrity: sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==} + engines: {node: '>=12'} + + '@isaacs/fs-minipass@4.0.1': + resolution: {integrity: sha512-wgm9Ehl2jpeqP3zw/7mo3kRHFp5MEDhqAdwy1fTGkHAwnkGOVsgpvQhL8B5n1qlb01jV3n/bI0ZfZp5lWA1k4w==} + engines: {node: '>=18.0.0'} + + '@istanbuljs/load-nyc-config@1.1.0': + resolution: {integrity: sha512-VjeHSlIzpv/NyD3N0YuHfXOPDIixcA1q2ZV98wsMqcYlPmv2n3Yb2lYP9XMElnaFVXg5A7YLTeLu6V84uQDjmQ==} + engines: {node: '>=8'} + + '@istanbuljs/schema@0.1.3': + resolution: {integrity: sha512-ZXRY4jNvVgSVQ8DL3LTcakaAtXwTVUxE81hslsyD2AtoXW/wVob10HkOJ1X/pAlcI7D+2YoZKg5do8G/w6RYgA==} + engines: {node: '>=8'} + + '@jest/console@29.5.0': + resolution: {integrity: sha512-NEpkObxPwyw/XxZVLPmAGKE89IQRp4puc6IQRPru6JKd1M3fW9v1xM1AnzIJE65hbCkzQAdnL8P47e9hzhiYLQ==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + '@jest/console@29.7.0': + resolution: {integrity: sha512-5Ni4CU7XHQi32IJ398EEP4RrB8eV09sXP2ROqD4bksHrnTree52PsxvX8tpL8LvTZ3pFzXyPbNQReSN41CAhOg==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + '@jest/core@29.7.0': + resolution: {integrity: sha512-n7aeXWKMnGtDA48y8TLWJPJmLmmZ642Ceo78cYWEpiD7FzDgmNDV/GCVRorPABdXLJZ/9wzzgZAlHjXjxDHGsg==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + peerDependencies: + node-notifier: ^8.0.1 || ^9.0.0 || ^10.0.0 + peerDependenciesMeta: + node-notifier: + optional: true + + '@jest/create-cache-key-function@27.5.1': + resolution: {integrity: sha512-dmH1yW+makpTSURTy8VzdUwFnfQh1G8R+DxO2Ho2FFmBbKFEVm+3jWdvFhE2VqB/LATCTokkP0dotjyQyw5/AQ==} + engines: {node: ^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0} + + '@jest/environment@29.5.0': + resolution: {integrity: sha512-5FXw2+wD29YU1d4I2htpRX7jYnAyTRjP2CsXQdo9SAM8g3ifxWPSV0HnClSn71xwctr0U3oZIIH+dtbfmnbXVQ==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + '@jest/environment@29.7.0': + resolution: {integrity: sha512-aQIfHDq33ExsN4jP1NWGXhxgQ/wixs60gDiKO+XVMd8Mn0NWPWgc34ZQDTb2jKaUWQ7MuwoitXAsN2XVXNMpAw==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + '@jest/expect-utils@29.7.0': + resolution: {integrity: sha512-GlsNBWiFQFCVi9QVSx7f5AgMeLxe9YCCs5PuP2O2LdjDAA8Jh9eX7lA1Jq/xdXw3Wb3hyvlFNfZIfcRetSzYcA==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + '@jest/expect@29.7.0': + resolution: {integrity: sha512-8uMeAMycttpva3P1lBHB8VciS9V0XAr3GymPpipdyQXbBcuhkLQOSe8E/p92RyAdToS6ZD1tFkX+CkhoECE0dQ==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + '@jest/fake-timers@29.5.0': + resolution: {integrity: sha512-9ARvuAAQcBwDAqOnglWq2zwNIRUDtk/SCkp/ToGEhFv5r86K21l+VEs0qNTaXtyiY0lEePl3kylijSYJQqdbDg==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + '@jest/fake-timers@29.7.0': + resolution: {integrity: sha512-q4DH1Ha4TTFPdxLsqDXK1d3+ioSL7yL5oCMJZgDYm6i+6CygW5E5xVr/D1HdsGxjt1ZWSfUAs9OxSB/BNelWrQ==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + '@jest/globals@29.7.0': + resolution: {integrity: sha512-mpiz3dutLbkW2MNFubUGUEVLkTGiqW6yLVTA+JbP6fI6J5iL9Y0Nlg8k95pcF8ctKwCS7WVxteBs29hhfAotzQ==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + '@jest/reporters@29.7.0': + resolution: {integrity: sha512-DApq0KJbJOEzAFYjHADNNxAE3KbhxQB1y5Kplb5Waqw6zVbuWatSnMjE5gs8FUgEPmNsnZA3NCWl9NG0ia04Pg==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + peerDependencies: + node-notifier: ^8.0.1 || ^9.0.0 || ^10.0.0 + peerDependenciesMeta: + node-notifier: + optional: true + + '@jest/schemas@29.0.0': + resolution: {integrity: sha512-3Ab5HgYIIAnS0HjqJHQYZS+zXc4tUmTmBH3z83ajI6afXp8X3ZtdLX+nXx+I7LNkJD7uN9LAVhgnjDgZa2z0kA==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + '@jest/schemas@29.4.3': + resolution: {integrity: sha512-VLYKXQmtmuEz6IxJsrZwzG9NvtkQsWNnWMsKxqWNu3+CnfzJQhp0WDDKWLVV9hLKr0l3SLLFRqcYHjhtyuDVxg==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + '@jest/schemas@29.6.3': + resolution: {integrity: sha512-mo5j5X+jIZmJQveBKeS/clAueipV7KgiX1vMgCxam1RNYiqE1w62n0/tJJnHtjW8ZHcQco5gY85jA3mi0L+nSA==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + '@jest/source-map@29.6.3': + resolution: {integrity: sha512-MHjT95QuipcPrpLM+8JMSzFx6eHp5Bm+4XeFDJlwsvVBjmKNiIAvasGK2fxz2WbGRlnvqehFbh07MMa7n3YJnw==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + '@jest/test-result@29.5.0': + resolution: {integrity: sha512-fGl4rfitnbfLsrfx1uUpDEESS7zM8JdgZgOCQuxQvL1Sn/I6ijeAVQWGfXI9zb1i9Mzo495cIpVZhA0yr60PkQ==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + '@jest/test-result@29.7.0': + resolution: {integrity: sha512-Fdx+tv6x1zlkJPcWXmMDAG2HBnaR9XPSd5aDWQVsfrZmLVT3lU1cwyxLgRmXR9yrq4NBoEm9BMsfgFzTQAbJYA==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + '@jest/test-sequencer@29.5.0': + resolution: {integrity: sha512-yPafQEcKjkSfDXyvtgiV4pevSeyuA6MQr6ZIdVkWJly9vkqjnFfcfhRQqpD5whjoU8EORki752xQmjaqoFjzMQ==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + '@jest/test-sequencer@29.7.0': + resolution: {integrity: sha512-GQwJ5WZVrKnOJuiYiAF52UNUJXgTZx1NHjFSEB0qEMmSZKAkdMoIzw/Cj6x6NF4AvV23AUqDpFzQkN/eYCYTxw==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + '@jest/transform@29.7.0': + resolution: {integrity: sha512-ok/BTPFzFKVMwO5eOHRrvnBVHdRy9IrsrW1GpMaQ9MCnilNLXQKmAX8s1YXDFaai9xJpac2ySzV0YeRRECr2Vw==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + '@jest/types@27.5.1': + resolution: {integrity: sha512-Cx46iJ9QpwQTjIdq5VJu2QTMMs3QlEjI0x1QbBP5W1+nMzyc2XmimiRR/CbX9TO0cPTeUlxWMOu8mslYsJ8DEw==} + engines: {node: ^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0} + + '@jest/types@29.1.2': + resolution: {integrity: sha512-DcXGtoTykQB5jiwCmVr8H4vdg2OJhQex3qPkG+ISyDO7xQXbt/4R6dowcRyPemRnkH7JoHvZuxPBdlq+9JxFCg==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + '@jest/types@29.5.0': + resolution: {integrity: sha512-qbu7kN6czmVRc3xWFQcAN03RAUamgppVUdXrvl1Wr3jlNF93o9mJbGcDWrwGB6ht44u7efB1qCFgVQmca24Uog==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + '@jest/types@29.6.3': + resolution: {integrity: sha512-u3UPsIilWKOM3F9CXtrG8LEJmNxwoCQC/XVj4IKYXvvpx7QIi/Kg1LI5uDmDpKlac62NUtX7eLjRh+jVZcLOzw==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + '@jridgewell/gen-mapping@0.3.5': + resolution: {integrity: sha512-IzL8ZoEDIBRWEzlCcRhOaCupYyN5gdIK+Q6fbFdPDg6HqX6jpkItn7DFIpW9LQzXG6Df9sA7+OKnq0qlz/GaQg==} + engines: {node: '>=6.0.0'} + + '@jridgewell/resolve-uri@3.1.0': + resolution: {integrity: sha512-F2msla3tad+Mfht5cJq7LSXcdudKTWCVYUgw6pLFOOHSTtZlj6SWNYAp+AhuqLmWdBO2X5hPrLcu8cVP8fy28w==} + engines: {node: '>=6.0.0'} + + '@jridgewell/set-array@1.2.1': + resolution: {integrity: sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A==} + engines: {node: '>=6.0.0'} + + '@jridgewell/sourcemap-codec@1.4.14': + resolution: {integrity: sha512-XPSJHWmi394fuUuzDnGz1wiKqWfo1yXecHQMRf2l6hztTO+nPru658AyDngaBe7isIxEkRsPR3FZh+s7iVa4Uw==} + + '@jridgewell/sourcemap-codec@1.4.15': + resolution: {integrity: sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==} + + '@jridgewell/trace-mapping@0.3.18': + resolution: {integrity: sha512-w+niJYzMHdd7USdiH2U6869nqhD2nbfZXND5Yp93qIbEmnDNk7PD48o+YchRVpzMU7M6jVCbenTR7PA1FLQ9pA==} + + '@jridgewell/trace-mapping@0.3.25': + resolution: {integrity: sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==} + + '@jridgewell/trace-mapping@0.3.9': + resolution: {integrity: sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==} + + '@jsdevtools/ono@7.1.3': + resolution: {integrity: sha512-4JQNk+3mVzK3xh2rqd6RB4J46qUR19azEHBneZyTZM+c456qOrbbM/5xcR8huNCCcbVt7+UmizG6GuUvPvKUYg==} + + '@koa/cors@5.0.0': + resolution: {integrity: sha512-x/iUDjcS90W69PryLDIMgFyV21YLTnG9zOpPXS7Bkt2b8AsY3zZsIpOLBkYr9fBcF3HbkKaER5hOBZLfpLgYNw==} + engines: {node: '>= 14.0.0'} + + '@koa/router@12.0.1': + resolution: {integrity: sha512-ribfPYfHb+Uw3b27Eiw6NPqjhIhTpVFzEWLwyc/1Xp+DCdwRRyIlAUODX+9bPARF6aQtUu1+/PHzdNvRzcs/+Q==} + engines: {node: '>= 12'} + + '@lezer/common@0.15.12': + resolution: {integrity: sha512-edfwCxNLnzq5pBA/yaIhwJ3U3Kz8VAUOTRg0hhxaizaI1N+qxV7EXDv/kLCkLeq2RzSFvxexlaj5Mzfn2kY0Ig==} + + '@lezer/lr@0.15.8': + resolution: {integrity: sha512-bM6oE6VQZ6hIFxDNKk8bKPa14hqFrV07J/vHGOeiAbJReIaQXmkVb6xQu4MR+JBTLa5arGRyAAjJe1qaQt3Uvg==} + + '@lmdb/lmdb-darwin-arm64@2.7.11': + resolution: {integrity: sha512-r6+vYq2vKzE+vgj/rNVRMwAevq0+ZR9IeMFIqcSga+wMtMdXQ27KqQ7uS99/yXASg29bos7yHP3yk4x6Iio0lw==} + cpu: [arm64] + os: [darwin] + + '@lmdb/lmdb-darwin-x64@2.7.11': + resolution: {integrity: sha512-jhj1aB4K8ycRL1HOQT5OtzlqOq70jxUQEWRN9Gqh3TIDN30dxXtiHi6EWF516tzw6v2+3QqhDMJh8O6DtTGG8Q==} + cpu: [x64] + os: [darwin] + + '@lmdb/lmdb-linux-arm64@2.7.11': + resolution: {integrity: sha512-7xGEfPPbmVJWcY2Nzqo11B9Nfxs+BAsiiaY/OcT4aaTDdykKeCjvKMQJA3KXCtZ1AtiC9ljyGLi+BfUwdulY5A==} + cpu: [arm64] + os: [linux] + + '@lmdb/lmdb-linux-arm@2.7.11': + resolution: {integrity: sha512-dHfLFVSrw/v5X5lkwp0Vl7+NFpEeEYKfMG2DpdFJnnG1RgHQZngZxCaBagFoaJGykRpd2DYF1AeuXBFrAUAXfw==} + cpu: [arm] + os: [linux] + + '@lmdb/lmdb-linux-x64@2.7.11': + resolution: {integrity: sha512-vUKI3JrREMQsXX8q0Eq5zX2FlYCKWMmLiCyyJNfZK0Uyf14RBg9VtB3ObQ41b4swYh2EWaltasWVe93Y8+KDng==} + cpu: [x64] + os: [linux] + + '@lmdb/lmdb-win32-x64@2.7.11': + resolution: {integrity: sha512-BJwkHlSUgtB+Ei52Ai32M1AOMerSlzyIGA/KC4dAGL+GGwVMdwG8HGCOA2TxP3KjhbgDPMYkv7bt/NmOmRIFng==} + cpu: [x64] + os: [win32] + + '@logto/affiliate@0.1.0': + resolution: {integrity: sha512-yDWSZMI2Qo/xoYU92tnwSP/gnSvq8+CLK5DqD/4brO42QJa7xjt7eA+HSyuMmSUrKffY2nP3riU81gs+nR8DkA==} + engines: {node: ^18.12.0} + + '@logto/browser@2.2.10': + resolution: {integrity: sha512-y6NauaxctqpfApccP6uFVmpg/vG1OhsDVLD4Pdpzbmj3whl63Nb17yxSTQHt4eYNKmSZJ2SzudAnMnVEYD91iQ==} + + '@logto/client@2.6.6': + resolution: {integrity: sha512-QT7jMnzEIWHBNrf9/M8p1OErRBbbNZjoekXGji5aZCyUh975hh8+GEBL21HV71FT3H/5Cq4Gf1GzUbAIW3izMA==} + + '@logto/cloud@0.2.5-e5d8200': + resolution: {integrity: sha512-/ZPaiIU7ORfKtNqsopVg4jxDt/sM6CGAGny06ppv/2FNsL7h8rX6JXOUyyKmT6ffCh/K/5s2HZe7v86zx5gENQ==} + engines: {node: ^20.9.0} + + '@logto/js@4.1.1': + resolution: {integrity: sha512-+RgthBvDw30UojirtAjZeHNfOwDQVURmpjcIBYTIf6afx5F5jJq8b1D/eaFbrCFrmXmatkT2iN7X8kYHui86WQ==} + + '@logto/node@2.4.7': + resolution: {integrity: sha512-AlANeqY1NIt93EBcRzrTmyAVHXOHpszTJK+qe1ok50rmZlTmX2p7yQvrg0/Ehwf/+4Rla5vooAR+HIFMaOmPpQ==} + + '@logto/react@3.0.8': + resolution: {integrity: sha512-p3pV4rX4g8ZwHQ159mxI+pP3Bwome47dNEmP1hI8/10WqdIPXGYTnfYn5c2l4Y2DyslYyK3ur2Sy4i4K6ept9A==} + peerDependencies: + react: '>=16.8.0 || ^18.0.0' + + '@manypkg/find-root@1.1.0': + resolution: {integrity: sha512-mki5uBvhHzO8kYYix/WRy2WX8S3B5wdVSc9D6KcU5lQNglP2yt58/VfLuAK49glRXChosY8ap2oJ1qgma3GUVA==} + + '@manypkg/get-packages@1.1.3': + resolution: {integrity: sha512-fo+QhuU3qE/2TQMQmbVMqaQ6EWbMhi4ABWP+O4AM1NqPBuy0OrApV5LO6BrrgnhtAHS2NH6RrVk9OL181tTi8A==} + + '@mdx-js/mdx@1.6.22': + resolution: {integrity: sha512-AMxuLxPz2j5/6TpF/XSdKpQP1NlG0z11dFOlq+2IP/lSgl11GY8ji6S/rgsViN/L0BDvHvUMruRb7ub+24LUYA==} + + '@mdx-js/react@1.6.22': + resolution: {integrity: sha512-TDoPum4SHdfPiGSAaRBw7ECyI8VaHpK8GJugbJIJuqyh6kzw9ZLJZW3HGL3NNrJGxcAixUvqROm+YuQOo5eXtg==} + peerDependencies: + react: ^16.13.1 || ^17.0.0 || ^18.0.0 + + '@mdx-js/util@1.6.22': + resolution: {integrity: sha512-H1rQc1ZOHANWBvPcW+JpGwr+juXSxM8Q8YCkm3GhZd8REu1fHR3z99CErO1p9pkcfcxZnMdIZdIsXkOHY0NilA==} + + '@microsoft/applicationinsights-web-snippet@1.0.1': + resolution: {integrity: sha512-2IHAOaLauc8qaAitvWS+U931T+ze+7MNWrDHY47IENP5y2UA0vqJDu67kWZDdpCN1fFC77sfgfB+HV7SrKshnQ==} + + '@mischnic/json-sourcemap@0.1.0': + resolution: {integrity: sha512-dQb3QnfNqmQNYA4nFSN/uLaByIic58gOXq4Y4XqLOWmOrw73KmJPt/HLyG0wvn1bnR6mBKs/Uwvkh+Hns1T0XA==} + engines: {node: '>=12.0.0'} + + '@monaco-editor/loader@1.4.0': + resolution: {integrity: sha512-00ioBig0x642hytVspPl7DbQyaSWRaolYie/UFNjoTdvoKPzo6xrXLhTk9ixgIKcLH5b5vDOjVNiGyY+uDCUlg==} + peerDependencies: + monaco-editor: '>= 0.21.0 < 1' + + '@monaco-editor/react@4.6.0': + resolution: {integrity: sha512-RFkU9/i7cN2bsq/iTkurMWOEErmYcY6JiQI3Jn+WeR/FGISH8JbHERjpS9oRuSOPvDMJI0Z8nJeKkbOs9sBYQw==} + peerDependencies: + monaco-editor: '>= 0.25.0 < 1' + react: ^16.8.0 || ^17.0.0 || ^18.0.0 + react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0 + + '@msgpackr-extract/msgpackr-extract-darwin-arm64@3.0.2': + resolution: {integrity: sha512-9bfjwDxIDWmmOKusUcqdS4Rw+SETlp9Dy39Xui9BEGEk19dDwH0jhipwFzEff/pFg95NKymc6TOTbRKcWeRqyQ==} + cpu: [arm64] + os: [darwin] + + '@msgpackr-extract/msgpackr-extract-darwin-x64@3.0.2': + resolution: {integrity: sha512-lwriRAHm1Yg4iDf23Oxm9n/t5Zpw1lVnxYU3HnJPTi2lJRkKTrps1KVgvL6m7WvmhYVt/FIsssWay+k45QHeuw==} + cpu: [x64] + os: [darwin] + + '@msgpackr-extract/msgpackr-extract-linux-arm64@3.0.2': + resolution: {integrity: sha512-FU20Bo66/f7He9Fp9sP2zaJ1Q8L9uLPZQDub/WlUip78JlPeMbVL8546HbZfcW9LNciEXc8d+tThSJjSC+tmsg==} + cpu: [arm64] + os: [linux] + + '@msgpackr-extract/msgpackr-extract-linux-arm@3.0.2': + resolution: {integrity: sha512-MOI9Dlfrpi2Cuc7i5dXdxPbFIgbDBGgKR5F2yWEa6FVEtSWncfVNKW5AKjImAQ6CZlBK9tympdsZJ2xThBiWWA==} + cpu: [arm] + os: [linux] + + '@msgpackr-extract/msgpackr-extract-linux-x64@3.0.2': + resolution: {integrity: sha512-gsWNDCklNy7Ajk0vBBf9jEx04RUxuDQfBse918Ww+Qb9HCPoGzS+XJTLe96iN3BVK7grnLiYghP/M4L8VsaHeA==} + cpu: [x64] + os: [linux] + + '@msgpackr-extract/msgpackr-extract-win32-x64@3.0.2': + resolution: {integrity: sha512-O+6Gs8UeDbyFpbSh2CPEz/UOrrdWPTBYNblZK5CxxLisYt4kGX3Sc+czffFonyjiGSq3jWLwJS/CCJc7tBr4sQ==} + cpu: [x64] + os: [win32] + + '@nodelib/fs.scandir@2.1.5': + resolution: {integrity: sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==} + engines: {node: '>= 8'} + + '@nodelib/fs.stat@2.0.5': + resolution: {integrity: sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==} + engines: {node: '>= 8'} + + '@nodelib/fs.walk@1.2.8': + resolution: {integrity: sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==} + engines: {node: '>= 8'} + + '@opentelemetry/api@1.8.0': + resolution: {integrity: sha512-I/s6F7yKUDdtMsoBWXJe8Qz40Tui5vsuKCWJEWVL+5q9sSWRzzx6v2KeNsOBEwd94j0eWkpWCH4yB6rZg9Mf0w==} + engines: {node: '>=8.0.0'} + + '@opentelemetry/core@1.23.0': + resolution: {integrity: sha512-hdQ/a9TMzMQF/BO8Cz1juA43/L5YGtCSiKoOHmrTEf7VMDAZgy8ucpWx3eQTnQ3gBloRcWtzvcrMZABC3PTSKQ==} + engines: {node: '>=14'} + peerDependencies: + '@opentelemetry/api': '>=1.0.0 <1.9.0' + + '@opentelemetry/instrumentation@0.41.2': + resolution: {integrity: sha512-rxU72E0pKNH6ae2w5+xgVYZLzc5mlxAbGzF4shxMVK8YC2QQsfN38B2GPbj0jvrKWWNUElfclQ+YTykkNg/grw==} + engines: {node: '>=14'} + peerDependencies: + '@opentelemetry/api': ^1.3.0 + + '@opentelemetry/resources@1.23.0': + resolution: {integrity: sha512-iPRLfVfcEQynYGo7e4Di+ti+YQTAY0h5mQEUJcHlU9JOqpb4x965O6PZ+wMcwYVY63G96KtdS86YCM1BF1vQZg==} + engines: {node: '>=14'} + peerDependencies: + '@opentelemetry/api': '>=1.0.0 <1.9.0' + + '@opentelemetry/sdk-trace-base@1.23.0': + resolution: {integrity: sha512-PzBmZM8hBomUqvCddF/5Olyyviayka44O5nDWq673np3ctnvwMOvNrsUORZjKja1zJbwEuD9niAGbnVrz3jwRQ==} + engines: {node: '>=14'} + peerDependencies: + '@opentelemetry/api': '>=1.0.0 <1.9.0' + + '@opentelemetry/semantic-conventions@1.23.0': + resolution: {integrity: sha512-MiqFvfOzfR31t8cc74CTP1OZfz7MbqpAnLCra8NqQoaHJX6ncIRTdYOQYBDQ2uFISDq0WY8Y9dDTWvsgzzBYRg==} + engines: {node: '>=14'} + + '@otplib/core@12.0.1': + resolution: {integrity: sha512-4sGntwbA/AC+SbPhbsziRiD+jNDdIzsZ3JUyfZwjtKyc/wufl1pnSIaG4Uqx8ymPagujub0o92kgBnB89cuAMA==} + + '@otplib/plugin-crypto@12.0.1': + resolution: {integrity: sha512-qPuhN3QrT7ZZLcLCyKOSNhuijUi9G5guMRVrxq63r9YNOxxQjPm59gVxLM+7xGnHnM6cimY57tuKsjK7y9LM1g==} + + '@otplib/plugin-thirty-two@12.0.1': + resolution: {integrity: sha512-MtT+uqRso909UkbrrYpJ6XFjj9D+x2Py7KjTO9JDPhL0bJUYVu5kFP4TFZW4NFAywrAtFRxOVY261u0qwb93gA==} + + '@otplib/preset-default@12.0.1': + resolution: {integrity: sha512-xf1v9oOJRyXfluBhMdpOkr+bsE+Irt+0D5uHtvg6x1eosfmHCsCC6ej/m7FXiWqdo0+ZUI6xSKDhJwc8yfiOPQ==} + + '@otplib/preset-v11@12.0.1': + resolution: {integrity: sha512-9hSetMI7ECqbFiKICrNa4w70deTUfArtwXykPUvSHWOdzOlfa9ajglu7mNCntlvxycTiOAXkQGwjQCzzDEMRMg==} + + '@parcel/bundler-default@2.9.3': + resolution: {integrity: sha512-JjJK8dq39/UO/MWI/4SCbB1t/qgpQRFnFDetAAAezQ8oN++b24u1fkMDa/xqQGjbuPmGeTds5zxGgYs7id7PYg==} + engines: {node: '>= 12.0.0', parcel: ^2.9.3} + + '@parcel/cache@2.9.3': + resolution: {integrity: sha512-Bj/H2uAJJSXtysG7E/x4EgTrE2hXmm7td/bc97K8M9N7+vQjxf7xb0ebgqe84ePVMkj4MVQSMEJkEucXVx4b0Q==} + engines: {node: '>= 12.0.0'} + peerDependencies: + '@parcel/core': ^2.9.3 + + '@parcel/codeframe@2.9.3': + resolution: {integrity: sha512-z7yTyD6h3dvduaFoHpNqur74/2yDWL++33rjQjIjCaXREBN6dKHoMGMizzo/i4vbiI1p9dDox2FIDEHCMQxqdA==} + engines: {node: '>= 12.0.0'} + + '@parcel/compressor-brotli@2.9.3': + resolution: {integrity: sha512-yLxTous+fPIaw8v8kR5UdWLzJTL7e3ISThNWsu9w9L4vqK0DUUIUePvwZjSNiYQcxFu9L/1X3vlKSzHv3TvS0Q==} + engines: {node: '>= 12.0.0', parcel: ^2.9.3} + + '@parcel/compressor-gzip@2.9.3': + resolution: {integrity: sha512-ffQDpPlr3XzqDa/Gwgj7kFPMKYPHnpTZCYnoFW0zzHJTI0umDUULb2XHRke804yiHplKA6fcj2TQjC5FU1beYw==} + engines: {node: '>= 12.0.0', parcel: ^2.9.3} + + '@parcel/compressor-raw@2.9.3': + resolution: {integrity: sha512-jz3t4/ICMsHEqgiTmv5i1DJva2k5QRpZlBELVxfY+QElJTVe8edKJ0TiKcBxh2hx7sm4aUigGmp7JiqqHRRYmA==} + engines: {node: '>= 12.0.0', parcel: ^2.9.3} + + '@parcel/config-default@2.9.3': + resolution: {integrity: sha512-tqN5tF7QnVABDZAu76co5E6N8mA9n8bxiWdK4xYyINYFIEHgX172oRTqXTnhEMjlMrdmASxvnGlbaPBaVnrCTw==} + peerDependencies: + '@parcel/core': ^2.9.3 + + '@parcel/core@2.9.3': + resolution: {integrity: sha512-4KlM1Zr/jpsqWuMXr2zmGsaOUs1zMMFh9vfCNKRZkptf+uk8I3sugHbNdo+F5B+4e2yMuOEb1zgAmvJLeuH6ww==} + engines: {node: '>= 12.0.0'} + + '@parcel/diagnostic@2.9.3': + resolution: {integrity: sha512-6jxBdyB3D7gP4iE66ghUGntWt2v64E6EbD4AetZk+hNJpgudOOPsKTovcMi/i7I4V0qD7WXSF4tvkZUoac0jwA==} + engines: {node: '>= 12.0.0'} + + '@parcel/events@2.9.3': + resolution: {integrity: sha512-K0Scx+Bx9f9p1vuShMzNwIgiaZUkxEnexaKYHYemJrM7pMAqxIuIqhnvwurRCsZOVLUJPDDNJ626cWTc5vIq+A==} + engines: {node: '>= 12.0.0'} + + '@parcel/fs-search@2.9.3': + resolution: {integrity: sha512-nsNz3bsOpwS+jphcd+XjZL3F3PDq9lik0O8HPm5f6LYkqKWT+u/kgQzA8OkAHCR3q96LGiHxUywHPEBc27vI4Q==} + engines: {node: '>= 12.0.0'} + + '@parcel/fs@2.9.3': + resolution: {integrity: sha512-/PrRKgCRw22G7rNPSpgN3Q+i2nIkZWuvIOAdMG4KWXC4XLp8C9jarNaWd5QEQ75amjhQSl3oUzABzkdCtkKrgg==} + engines: {node: '>= 12.0.0'} + peerDependencies: + '@parcel/core': ^2.9.3 + + '@parcel/graph@2.9.3': + resolution: {integrity: sha512-3LmRJmF8+OprAr6zJT3X2s8WAhLKkrhi6RsFlMWHifGU5ED1PFcJWFbOwJvSjcAhMQJP0fErcFIK1Ludv3Vm3g==} + engines: {node: '>= 12.0.0'} + + '@parcel/hash@2.9.3': + resolution: {integrity: sha512-qlH5B85XLzVAeijgKPjm1gQu35LoRYX/8igsjnN8vOlbc3O8BYAUIutU58fbHbtE8MJPbxQQUw7tkTjeoujcQQ==} + engines: {node: '>= 12.0.0'} + + '@parcel/logger@2.9.3': + resolution: {integrity: sha512-5FNBszcV6ilGFcijEOvoNVG6IUJGsnMiaEnGQs7Fvc1dktTjEddnoQbIYhcSZL63wEmzBZOgkT5yDMajJ/41jw==} + engines: {node: '>= 12.0.0'} + + '@parcel/markdown-ansi@2.9.3': + resolution: {integrity: sha512-/Q4X8F2aN8UNjAJrQ5NfK2OmZf6shry9DqetUSEndQ0fHonk78WKt6LT0zSKEBEW/bB/bXk6mNMsCup6L8ibjQ==} + engines: {node: '>= 12.0.0'} + + '@parcel/namer-default@2.9.3': + resolution: {integrity: sha512-1ynFEcap48/Ngzwwn318eLYpLUwijuuZoXQPCsEQ21OOIOtfhFQJaPwXTsw6kRitshKq76P2aafE0BioGSqxcA==} + engines: {node: '>= 12.0.0', parcel: ^2.9.3} + + '@parcel/node-resolver-core@3.0.3': + resolution: {integrity: sha512-AjxNcZVHHJoNT/A99PKIdFtwvoze8PAiC3yz8E/dRggrDIOboUEodeQYV5Aq++aK76uz/iOP0tST2T8A5rhb1A==} + engines: {node: '>= 12.0.0'} + + '@parcel/optimizer-css@2.9.3': + resolution: {integrity: sha512-RK1QwcSdWDNUsFvuLy0hgnYKtPQebzCb0vPPzqs6LhL+vqUu9utOyRycGaQffHCkHVQP6zGlN+KFssd7YtFGhA==} + engines: {node: '>= 12.0.0', parcel: ^2.9.3} + + '@parcel/optimizer-htmlnano@2.9.3': + resolution: {integrity: sha512-9g/KBck3c6DokmJfvJ5zpHFBiCSolaGrcsTGx8C3YPdCTVTI9P1TDCwUxvAr4LjpcIRSa82wlLCI+nF6sSgxKA==} + engines: {node: '>= 12.0.0', parcel: ^2.9.3} + + '@parcel/optimizer-image@2.9.3': + resolution: {integrity: sha512-530YzthE7kmecnNhPbkAK+26yQNt69pfJrgE0Ev0BZaM1Wu2+33nki7o8qvkTkikhPrurEJLGIXt1qKmbKvCbA==} + engines: {node: '>= 12.0.0', parcel: ^2.9.3} + peerDependencies: + '@parcel/core': ^2.9.3 + + '@parcel/optimizer-svgo@2.9.3': + resolution: {integrity: sha512-ytQS0wY5JJhWU4mL0wfhYDUuHcfuw+Gy2+JcnTm1t1AZXHlOTbU6EzRWNqBShsgXjvdrQQXizAe3B6GFFlFJVQ==} + engines: {node: '>= 12.0.0', parcel: ^2.9.3} + + '@parcel/optimizer-swc@2.9.3': + resolution: {integrity: sha512-GQINNeqtdpL1ombq/Cpwi6IBk02wKJ/JJbYbyfHtk8lxlq13soenpwOlzJ5T9D2fdG+FUhai9NxpN5Ss4lNoAg==} + engines: {node: '>= 12.0.0', parcel: ^2.9.3} + + '@parcel/package-manager@2.9.3': + resolution: {integrity: sha512-NH6omcNTEupDmW4Lm1e4NUYBjdqkURxgZ4CNESESInHJe6tblVhNB8Rpr1ar7zDar7cly9ILr8P6N3Ei7bTEjg==} + engines: {node: '>= 12.0.0'} + peerDependencies: + '@parcel/core': ^2.9.3 + + '@parcel/packager-css@2.9.3': + resolution: {integrity: sha512-mePiWiYZOULY6e1RdAIJyRoYqXqGci0srOaVZYaP7mnrzvJgA63kaZFFsDiEWghunQpMUuUjM2x/vQVHzxmhKQ==} + engines: {node: '>= 12.0.0', parcel: ^2.9.3} + + '@parcel/packager-html@2.9.3': + resolution: {integrity: sha512-0Ex+O0EaZf9APNERRNGgGto02hFJ6f5RQEvRWBK55WAV1rXeU+kpjC0c0qZvnUaUtXfpWMsEBkevJCwDkUMeMg==} + engines: {node: '>= 12.0.0', parcel: ^2.9.3} + + '@parcel/packager-js@2.9.3': + resolution: {integrity: sha512-V5xwkoE3zQ3R+WqAWhA1KGQ791FvJeW6KonOlMI1q76Djjgox68hhObqcLu66AmYNhR2R/wUpkP18hP2z8dSFw==} + engines: {node: '>= 12.0.0', parcel: ^2.9.3} + + '@parcel/packager-raw@2.9.3': + resolution: {integrity: sha512-oPQTNoYanQ2DdJyL61uPYK2py83rKOT8YVh2QWAx0zsSli6Kiy64U3+xOCYWgDVCrHw9+9NpQMuAdSiFg4cq8g==} + engines: {node: '>= 12.0.0', parcel: ^2.9.3} + + '@parcel/packager-svg@2.9.3': + resolution: {integrity: sha512-p/Ya6UO9DAkaCUFxfFGyeHZDp9YPAlpdnh1OChuwqSFOXFjjeXuoK4KLT+ZRalVBo2Jo8xF70oKMZw4MVvaL7Q==} + engines: {node: '>= 12.0.0', parcel: ^2.9.3} + + '@parcel/plugin@2.9.3': + resolution: {integrity: sha512-qN85Gqr2GMuxX1dT1mnuO9hOcvlEv1lrYrCxn7CJN2nUhbwcfG+LEvcrCzCOJ6XtIHm+ZBV9h9p7FfoPLvpw+g==} + engines: {node: '>= 12.0.0'} + + '@parcel/profiler@2.9.3': + resolution: {integrity: sha512-pyHc9lw8VZDfgZoeZWZU9J0CVEv1Zw9O5+e0DJPDPHuXJYr72ZAOhbljtU3owWKAeW+++Q2AZWkbUGEOjI/e6g==} + engines: {node: '>= 12.0.0'} + + '@parcel/reporter-cli@2.9.3': + resolution: {integrity: sha512-pZiEvQpuXFuQBafMHxkDmwH8CnnK9sWHwa3bSbsnt385aUahtE8dpY0LKt+K1zfB6degKoczN6aWVj9WycQuZQ==} + engines: {node: '>= 12.0.0', parcel: ^2.9.3} + + '@parcel/reporter-dev-server@2.9.3': + resolution: {integrity: sha512-s6eboxdLEtRSvG52xi9IiNbcPKC0XMVmvTckieue2EqGDbDcaHQoHmmwkk0rNq0/Z/UxelGcQXoIYC/0xq3ykQ==} + engines: {node: '>= 12.0.0', parcel: ^2.9.3} + + '@parcel/reporter-tracer@2.9.3': + resolution: {integrity: sha512-9cXpKWk0m6d6d+4+TlAdOe8XIPaFEIKGWMWG+5SFAQE08u3olet4PSvd49F4+ZZo5ftRE7YI3j6xNbXvJT8KGw==} + engines: {node: '>= 12.0.0', parcel: ^2.9.3} + + '@parcel/resolver-default@2.9.3': + resolution: {integrity: sha512-8ESJk1COKvDzkmOnppNXoDamNMlYVIvrKc2RuFPmp8nKVj47R6NwMgvwxEaatyPzvkmyTpq5RvG9I3HFc+r4Cw==} + engines: {node: '>= 12.0.0', parcel: ^2.9.3} + + '@parcel/runtime-browser-hmr@2.9.3': + resolution: {integrity: sha512-EgiDIDrVAWpz7bOzWXqVinQkaFjLwT34wsonpXAbuI7f7r00d52vNAQC9AMu+pTijA3gyKoJ+Q4NWPMZf7ACDA==} + engines: {node: '>= 12.0.0', parcel: ^2.9.3} + + '@parcel/runtime-js@2.9.3': + resolution: {integrity: sha512-EvIy+qXcKnB5qxHhe96zmJpSAViNVXHfQI5RSdZ2a7CPwORwhTI+zPNT9sb7xb/WwFw/WuTTgzT40b41DceU6Q==} + engines: {node: '>= 12.0.0', parcel: ^2.9.3} + + '@parcel/runtime-react-refresh@2.9.3': + resolution: {integrity: sha512-XBgryZQIyCmi6JwEfMUCmINB3l1TpTp9a2iFxmYNpzHlqj4Ve0saKaqWOVRLvC945ZovWIBzcSW2IYqWKGtbAA==} + engines: {node: '>= 12.0.0', parcel: ^2.9.3} + + '@parcel/runtime-service-worker@2.9.3': + resolution: {integrity: sha512-qLJLqv1mMdWL7gyh8aKBFFAuEiJkhUUgLKpdn6eSfH/R7kTtb76WnOwqUrhvEI9bZFUM/8Pa1bzJnPpqSOM+Sw==} + engines: {node: '>= 12.0.0', parcel: ^2.9.3} + + '@parcel/source-map@2.1.1': + resolution: {integrity: sha512-Ejx1P/mj+kMjQb8/y5XxDUn4reGdr+WyKYloBljpppUy8gs42T+BNoEOuRYqDVdgPc6NxduzIDoJS9pOFfV5Ew==} + engines: {node: ^12.18.3 || >=14} + + '@parcel/transformer-babel@2.9.3': + resolution: {integrity: sha512-pURtEsnsp3h6tOBDuzh9wRvVtw4PgIlqwAArIWdrG7iwqOUYv9D8ME4+ePWEu7MQWAp58hv9pTJtqWv4T+Sq8A==} + engines: {node: '>= 12.0.0', parcel: ^2.9.3} + + '@parcel/transformer-css@2.9.3': + resolution: {integrity: sha512-duWMdbEBBPjg3fQdXF16iWIdThetDZvCs2TpUD7xOlXH6kR0V5BJy8ONFT15u1RCqIV9hSNGaS3v3I9YRNY5zQ==} + engines: {node: '>= 12.0.0', parcel: ^2.9.3} + + '@parcel/transformer-html@2.9.3': + resolution: {integrity: sha512-0NU4omcHzFXA1seqftAXA2KNZaMByoKaNdXnLgBgtCGDiYvOcL+6xGHgY6pw9LvOh5um10KI5TxSIMILoI7VtA==} + engines: {node: '>= 12.0.0', parcel: ^2.9.3} + + '@parcel/transformer-image@2.9.3': + resolution: {integrity: sha512-7CEe35RaPadQzLIuxzTtIxnItvOoy46hcbXtOdDt6lmVa4omuOygZYRIya2lsGIP4JHvAaALMb5nt99a1uTwJg==} + engines: {node: '>= 12.0.0', parcel: ^2.9.3} + peerDependencies: + '@parcel/core': ^2.9.3 + + '@parcel/transformer-js@2.9.3': + resolution: {integrity: sha512-Z2MVVg5FYcPOfxlUwxqb5l9yjTMEqE3KI3zq2MBRUme6AV07KxLmCDF23b6glzZlHWQUE8MXzYCTAkOPCcPz+Q==} + engines: {node: '>= 12.0.0', parcel: ^2.9.3} + peerDependencies: + '@parcel/core': ^2.9.3 + + '@parcel/transformer-json@2.9.3': + resolution: {integrity: sha512-yNL27dbOLhkkrjaQjiQ7Im9VOxmkfuuSNSmS0rA3gEjVcm07SLKRzWkAaPnyx44Lb6bzyOTWwVrb9aMmxgADpA==} + engines: {node: '>= 12.0.0', parcel: ^2.9.3} + + '@parcel/transformer-mdx@2.9.3': + resolution: {integrity: sha512-SE3mnCPefhS3p3pWLMUvQmMf4tHfVLqTxVLikrKR1WRwhIBzuYEm9UbayDadZPmGB9JYE4QIQKGCeDa97geyAg==} + engines: {node: '>= 12.0.0', parcel: ^2.9.3} + peerDependencies: + '@mdx-js/react': ^1.6.22 + + '@parcel/transformer-postcss@2.9.3': + resolution: {integrity: sha512-HoDvPqKzhpmvMmHqQhDnt8F1vH61m6plpGiYaYnYv2Om4HHi5ZIq9bO+9QLBnTKfaZ7ndYSefTKOxTYElg7wyw==} + engines: {node: '>= 12.0.0', parcel: ^2.9.3} + + '@parcel/transformer-posthtml@2.9.3': + resolution: {integrity: sha512-2fQGgrzRmaqbWf3y2/T6xhqrNjzqMMKksqJzvc8TMfK6f2kg3Ddjv158eaSW2JdkV39aY7tvAOn5f1uzo74BMA==} + engines: {node: '>= 12.0.0', parcel: ^2.9.3} + + '@parcel/transformer-raw@2.9.3': + resolution: {integrity: sha512-oqdPzMC9QzWRbY9J6TZEqltknjno+dY24QWqf8ondmdF2+W+/2mRDu59hhCzQrqUHgTq4FewowRZmSfpzHxwaQ==} + engines: {node: '>= 12.0.0', parcel: ^2.9.3} + + '@parcel/transformer-react-refresh-wrap@2.9.3': + resolution: {integrity: sha512-cb9NyU6oJlDblFIlzqIE8AkvRQVGl2IwJNKwD4PdE7Y6sq2okGEPG4hOw3k/Y9JVjM4/2pUORqvjSRhWwd9oVQ==} + engines: {node: '>= 12.0.0', parcel: ^2.9.3} + + '@parcel/transformer-sass@2.9.3': + resolution: {integrity: sha512-i9abj9bKg3xCHghJyTM3rUVxIEn9n1Rl+DFdpyNAD8VZ52COfOshFDQOWNuhU1hEnJOFYCjnfcO0HRTsg3dWmg==} + engines: {node: '>= 12.0.0', parcel: ^2.9.3} + + '@parcel/transformer-svg-react@2.9.3': + resolution: {integrity: sha512-RXmCn58CkCBhpsS1AaRBrSRla0U5JN3r3hb7kQvEb+d7chGnsxCCWsBxtlrxPUjoUFLdQli9rhpCTkiyOBXY2A==} + engines: {node: '>= 12.0.0', parcel: ^2.9.3} + + '@parcel/transformer-svg@2.9.3': + resolution: {integrity: sha512-ypmE+dzB09IMCdEAkOsSxq1dEIm2A3h67nAFz4qbfHbwNgXBUuy/jB3ZMwXN/cO0f7SBh/Ap8Jhq6vmGqB5tWw==} + engines: {node: '>= 12.0.0', parcel: ^2.9.3} + + '@parcel/types@2.9.3': + resolution: {integrity: sha512-NSNY8sYtRhvF1SqhnIGgGvJocyWt1K8Tnw5cVepm0g38ywtX6mwkBvMkmeehXkII4mSUn+frD9wGsydTunezvA==} + + '@parcel/utils@2.9.3': + resolution: {integrity: sha512-cesanjtj/oLehW8Waq9JFPmAImhoiHX03ihc3JTWkrvJYSbD7wYKCDgPAM3JiRAqvh1LZ6P699uITrYWNoRLUg==} + engines: {node: '>= 12.0.0'} + + '@parcel/watcher@2.0.7': + resolution: {integrity: sha512-gc3hoS6e+2XdIQ4HHljDB1l0Yx2EWh/sBBtCEFNKGSMlwASWeAQsOY/fPbxOBcZ/pg0jBh4Ga+4xHlZc4faAEQ==} + engines: {node: '>= 10.0.0'} + + '@parcel/workers@2.9.3': + resolution: {integrity: sha512-zRrDuZJzTevrrwElYosFztgldhqW6G9q5zOeQXfVQFkkEJCNfg36ixeiofKRU8uu2x+j+T6216mhMNB6HiuY+w==} + engines: {node: '>= 12.0.0'} + peerDependencies: + '@parcel/core': ^2.9.3 + + '@peculiar/asn1-android@2.3.10': + resolution: {integrity: sha512-z9Rx9cFJv7UUablZISe7uksNbFJCq13hO0yEAOoIpAymALTLlvUOSLnGiQS7okPaM5dP42oTLhezH6XDXRXjGw==} + + '@peculiar/asn1-ecc@2.3.8': + resolution: {integrity: sha512-Ah/Q15y3A/CtxbPibiLM/LKcMbnLTdUdLHUgdpB5f60sSvGkXzxJCu5ezGTFHogZXWNX3KSmYqilCrfdmBc6pQ==} + + '@peculiar/asn1-rsa@2.3.8': + resolution: {integrity: sha512-ES/RVEHu8VMYXgrg3gjb1m/XG0KJWnV4qyZZ7mAg7rrF3VTmRbLxO8mk+uy0Hme7geSMebp+Wvi2U6RLLEs12Q==} + + '@peculiar/asn1-schema@2.3.8': + resolution: {integrity: sha512-ULB1XqHKx1WBU/tTFIA+uARuRoBVZ4pNdOA878RDrRbBfBGcSzi5HBkdScC6ZbHn8z7L8gmKCgPC1LHRrP46tA==} + + '@peculiar/asn1-x509@2.3.8': + resolution: {integrity: sha512-voKxGfDU1c6r9mKiN5ZUsZWh3Dy1BABvTM3cimf0tztNwyMJPhiXY94eRTgsMQe6ViLfT6EoXxkWVzcm3mFAFw==} + + '@pkgjs/parseargs@0.11.0': + resolution: {integrity: sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==} + engines: {node: '>=14'} + + '@pkgr/core@0.1.1': + resolution: {integrity: sha512-cq8o4cWH0ibXh9VGi5P20Tu9XF/0fFXl9EUinr9QfTM7a7p0oTA4iJRCQWppXR1Pg8dSM0UCItCkPwsk9qWWYA==} + engines: {node: ^12.20.0 || ^14.18.0 || >=16.0.0} + + '@puppeteer/browsers@2.2.2': + resolution: {integrity: sha512-hZ/JhxPIceWaGSEzUZp83/8M49CoxlkuThfTR7t4AoCu5+ZvJ3vktLm60Otww2TXeROB5igiZ8D9oPQh6ckBVg==} + engines: {node: '>=18'} + hasBin: true + + '@react-dnd/asap@5.0.0': + resolution: {integrity: sha512-czNGSkNPZgxapKz1a8zj/C5me5MpVpN4wlXDQIMF4wDUuFJ37x7beakc4S7C1xKilHA4tgT9zZb4U64BdT/E5g==} + + '@react-dnd/invariant@4.0.0': + resolution: {integrity: sha512-tjPrh294NbH6Gj1YP1of6JYEe3+sm0Wy7YA1ImG6YghlZe3n8F+fBx1yIrA5dVJCuUh6pBp4XO7/lcSq7oLL0A==} + + '@react-dnd/shallowequal@4.0.0': + resolution: {integrity: sha512-Yykovind6xzqAqd0t5umrdAGPlGLTE80cy80UkEnbt8Zv5zEYTFzJSNPQ81TY8BSpRreubu1oE54iHBv2UVnTQ==} + + '@react-spring/animated@9.6.1': + resolution: {integrity: sha512-ls/rJBrAqiAYozjLo5EPPLLOb1LM0lNVQcXODTC1SMtS6DbuBCPaKco5svFUQFMP2dso3O+qcC4k9FsKc0KxMQ==} + peerDependencies: + react: ^16.8.0 || ^17.0.0 || ^18.0.0 + + '@react-spring/core@9.6.1': + resolution: {integrity: sha512-3HAAinAyCPessyQNNXe5W0OHzRfa8Yo5P748paPcmMowZ/4sMfaZ2ZB6e5x5khQI8NusOHj8nquoutd6FRY5WQ==} + peerDependencies: + react: ^16.8.0 || ^17.0.0 || ^18.0.0 + + '@react-spring/rafz@9.6.1': + resolution: {integrity: sha512-v6qbgNRpztJFFfSE3e2W1Uz+g8KnIBs6SmzCzcVVF61GdGfGOuBrbjIcp+nUz301awVmREKi4eMQb2Ab2gGgyQ==} + + '@react-spring/shared@9.6.1': + resolution: {integrity: sha512-PBFBXabxFEuF8enNLkVqMC9h5uLRBo6GQhRMQT/nRTnemVENimgRd+0ZT4yFnAQ0AxWNiJfX3qux+bW2LbG6Bw==} + peerDependencies: + react: ^16.8.0 || ^17.0.0 || ^18.0.0 + + '@react-spring/types@9.6.1': + resolution: {integrity: sha512-POu8Mk0hIU3lRXB3bGIGe4VHIwwDsQyoD1F394OK7STTiX9w4dG3cTLljjYswkQN+hDSHRrj4O36kuVa7KPU8Q==} + + '@react-spring/web@9.6.1': + resolution: {integrity: sha512-X2zR6q2Z+FjsWfGAmAXlQaoUHbPmfuCaXpuM6TcwXPpLE1ZD4A1eys/wpXboFQmDkjnrlTmKvpVna1MjWpZ5Hw==} + peerDependencies: + react: ^16.8.0 || ^17.0.0 || ^18.0.0 + react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0 + + '@redis/bloom@1.2.0': + resolution: {integrity: sha512-HG2DFjYKbpNmVXsa0keLHp/3leGJz1mjh09f2RLGGLQZzSHpkmZWuwJbAvo3QcRY8p80m5+ZdXZdYOSBLlp7Cg==} + peerDependencies: + '@redis/client': ^1.0.0 + + '@redis/client@1.5.6': + resolution: {integrity: sha512-dFD1S6je+A47Lj22jN/upVU2fj4huR7S9APd7/ziUXsIXDL+11GPYti4Suv5y8FuXaN+0ZG4JF+y1houEJ7ToA==} + engines: {node: '>=14'} + + '@redis/graph@1.1.0': + resolution: {integrity: sha512-16yZWngxyXPd+MJxeSr0dqh2AIOi8j9yXKcKCwVaKDbH3HTuETpDVPcLujhFYVPtYrngSco31BUcSa9TH31Gqg==} + peerDependencies: + '@redis/client': ^1.0.0 + + '@redis/json@1.0.4': + resolution: {integrity: sha512-LUZE2Gdrhg0Rx7AN+cZkb1e6HjoSKaeeW8rYnt89Tly13GBI5eP4CwDVr+MY8BAYfCg4/N15OUrtLoona9uSgw==} + peerDependencies: + '@redis/client': ^1.0.0 + + '@redis/search@1.1.2': + resolution: {integrity: sha512-/cMfstG/fOh/SsE+4/BQGeuH/JJloeWuH+qJzM8dbxuWvdWibWAOAHHCZTMPhV3xIlH4/cUEIA8OV5QnYpaVoA==} + peerDependencies: + '@redis/client': ^1.0.0 + + '@redis/time-series@1.0.4': + resolution: {integrity: sha512-ThUIgo2U/g7cCuZavucQTQzA9g9JbDDY2f64u3AbAoz/8vE2lt2U37LamDUVChhaDA3IRT9R6VvJwqnUfTJzng==} + peerDependencies: + '@redis/client': ^1.0.0 + + '@remix-run/router@1.5.0': + resolution: {integrity: sha512-bkUDCp8o1MvFO+qxkODcbhSqRa6P2GXgrGZVpt0dCXNW2HCSCqYI0ZoAqEOSAjRWmmlKcYgFvN4B4S+zo/f8kg==} + engines: {node: '>=14'} + + '@rollup/plugin-commonjs@25.0.7': + resolution: {integrity: sha512-nEvcR+LRjEjsaSsc4x3XZfCCvZIaSMenZu/OiwOKGN2UhQpAYI7ru7czFvyWbErlpoGjnSX3D5Ch5FcMA3kRWQ==} + engines: {node: '>=14.0.0'} + peerDependencies: + rollup: ^2.68.0||^3.0.0||^4.0.0 + peerDependenciesMeta: + rollup: + optional: true + + '@rollup/plugin-json@6.1.0': + resolution: {integrity: sha512-EGI2te5ENk1coGeADSIwZ7G2Q8CJS2sF120T7jLw4xFw9n7wIOXHo+kIYRAoVpJAN+kmqZSoO3Fp4JtoNF4ReA==} + engines: {node: '>=14.0.0'} + peerDependencies: + rollup: ^1.20.0||^2.0.0||^3.0.0||^4.0.0 + peerDependenciesMeta: + rollup: + optional: true + + '@rollup/plugin-node-resolve@15.2.3': + resolution: {integrity: sha512-j/lym8nf5E21LwBT4Df1VD6hRO2L2iwUeUmP7litikRsVp1H6NWx20NEp0Y7su+7XGc476GnXXc4kFeZNGmaSQ==} + engines: {node: '>=14.0.0'} + peerDependencies: + rollup: ^2.78.0||^3.0.0||^4.0.0 + peerDependenciesMeta: + rollup: + optional: true + + '@rollup/plugin-typescript@11.1.6': + resolution: {integrity: sha512-R92yOmIACgYdJ7dJ97p4K69I8gg6IEHt8M7dUBxN3W6nrO8uUxX5ixl0yU/N3aZTi8WhPuICvOHXQvF6FaykAA==} + engines: {node: '>=14.0.0'} + peerDependencies: + rollup: ^2.14.0||^3.0.0||^4.0.0 + tslib: '*' + typescript: '>=3.7.0' + peerDependenciesMeta: + rollup: + optional: true + tslib: + optional: true + + '@rollup/pluginutils@5.1.0': + resolution: {integrity: sha512-XTIWOPPcpvyKI6L1NHo0lFlCyznUEyPmPY1mc3KpPVDYulHSTvyeLNVW00QTLIAFNhR3kYnJTQHeGqU4M3n09g==} + engines: {node: '>=14.0.0'} + peerDependencies: + rollup: ^1.20.0||^2.0.0||^3.0.0||^4.0.0 + peerDependenciesMeta: + rollup: + optional: true + + '@rollup/rollup-android-arm-eabi@4.12.0': + resolution: {integrity: sha512-+ac02NL/2TCKRrJu2wffk1kZ+RyqxVUlbjSagNgPm94frxtr+XDL12E5Ll1enWskLrtrZ2r8L3wED1orIibV/w==} + cpu: [arm] + os: [android] + + '@rollup/rollup-android-arm-eabi@4.14.3': + resolution: {integrity: sha512-X9alQ3XM6I9IlSlmC8ddAvMSyG1WuHk5oUnXGw+yUBs3BFoTizmG1La/Gr8fVJvDWAq+zlYTZ9DBgrlKRVY06g==} + cpu: [arm] + os: [android] + + '@rollup/rollup-android-arm64@4.12.0': + resolution: {integrity: sha512-OBqcX2BMe6nvjQ0Nyp7cC90cnumt8PXmO7Dp3gfAju/6YwG0Tj74z1vKrfRz7qAv23nBcYM8BCbhrsWqO7PzQQ==} + cpu: [arm64] + os: [android] + + '@rollup/rollup-android-arm64@4.14.3': + resolution: {integrity: sha512-eQK5JIi+POhFpzk+LnjKIy4Ks+pwJ+NXmPxOCSvOKSNRPONzKuUvWE+P9JxGZVxrtzm6BAYMaL50FFuPe0oWMQ==} + cpu: [arm64] + os: [android] + + '@rollup/rollup-darwin-arm64@4.12.0': + resolution: {integrity: sha512-X64tZd8dRE/QTrBIEs63kaOBG0b5GVEd3ccoLtyf6IdXtHdh8h+I56C2yC3PtC9Ucnv0CpNFJLqKFVgCYe0lOQ==} + cpu: [arm64] + os: [darwin] + + '@rollup/rollup-darwin-arm64@4.14.3': + resolution: {integrity: sha512-Od4vE6f6CTT53yM1jgcLqNfItTsLt5zE46fdPaEmeFHvPs5SjZYlLpHrSiHEKR1+HdRfxuzXHjDOIxQyC3ptBA==} + cpu: [arm64] + os: [darwin] + + '@rollup/rollup-darwin-x64@4.12.0': + resolution: {integrity: sha512-cc71KUZoVbUJmGP2cOuiZ9HSOP14AzBAThn3OU+9LcA1+IUqswJyR1cAJj3Mg55HbjZP6OLAIscbQsQLrpgTOg==} + cpu: [x64] + os: [darwin] + + '@rollup/rollup-darwin-x64@4.14.3': + resolution: {integrity: sha512-0IMAO21axJeNIrvS9lSe/PGthc8ZUS+zC53O0VhF5gMxfmcKAP4ESkKOCwEi6u2asUrt4mQv2rjY8QseIEb1aw==} + cpu: [x64] + os: [darwin] + + '@rollup/rollup-linux-arm-gnueabihf@4.12.0': + resolution: {integrity: sha512-a6w/Y3hyyO6GlpKL2xJ4IOh/7d+APaqLYdMf86xnczU3nurFTaVN9s9jOXQg97BE4nYm/7Ga51rjec5nfRdrvA==} + cpu: [arm] + os: [linux] + + '@rollup/rollup-linux-arm-gnueabihf@4.14.3': + resolution: {integrity: sha512-ge2DC7tHRHa3caVEoSbPRJpq7azhG+xYsd6u2MEnJ6XzPSzQsTKyXvh6iWjXRf7Rt9ykIUWHtl0Uz3T6yXPpKw==} + cpu: [arm] + os: [linux] + + '@rollup/rollup-linux-arm-musleabihf@4.14.3': + resolution: {integrity: sha512-ljcuiDI4V3ySuc7eSk4lQ9wU8J8r8KrOUvB2U+TtK0TiW6OFDmJ+DdIjjwZHIw9CNxzbmXY39wwpzYuFDwNXuw==} + cpu: [arm] + os: [linux] + + '@rollup/rollup-linux-arm64-gnu@4.12.0': + resolution: {integrity: sha512-0fZBq27b+D7Ar5CQMofVN8sggOVhEtzFUwOwPppQt0k+VR+7UHMZZY4y+64WJ06XOhBTKXtQB/Sv0NwQMXyNAA==} + cpu: [arm64] + os: [linux] + + '@rollup/rollup-linux-arm64-gnu@4.14.3': + resolution: {integrity: sha512-Eci2us9VTHm1eSyn5/eEpaC7eP/mp5n46gTRB3Aar3BgSvDQGJZuicyq6TsH4HngNBgVqC5sDYxOzTExSU+NjA==} + cpu: [arm64] + os: [linux] + + '@rollup/rollup-linux-arm64-musl@4.12.0': + resolution: {integrity: sha512-eTvzUS3hhhlgeAv6bfigekzWZjaEX9xP9HhxB0Dvrdbkk5w/b+1Sxct2ZuDxNJKzsRStSq1EaEkVSEe7A7ipgQ==} + cpu: [arm64] + os: [linux] + + '@rollup/rollup-linux-arm64-musl@4.14.3': + resolution: {integrity: sha512-UrBoMLCq4E92/LCqlh+blpqMz5h1tJttPIniwUgOFJyjWI1qrtrDhhpHPuFxULlUmjFHfloWdixtDhSxJt5iKw==} + cpu: [arm64] + os: [linux] + + '@rollup/rollup-linux-powerpc64le-gnu@4.14.3': + resolution: {integrity: sha512-5aRjvsS8q1nWN8AoRfrq5+9IflC3P1leMoy4r2WjXyFqf3qcqsxRCfxtZIV58tCxd+Yv7WELPcO9mY9aeQyAmw==} + cpu: [ppc64] + os: [linux] + + '@rollup/rollup-linux-riscv64-gnu@4.12.0': + resolution: {integrity: sha512-ix+qAB9qmrCRiaO71VFfY8rkiAZJL8zQRXveS27HS+pKdjwUfEhqo2+YF2oI+H/22Xsiski+qqwIBxVewLK7sw==} + cpu: [riscv64] + os: [linux] + + '@rollup/rollup-linux-riscv64-gnu@4.14.3': + resolution: {integrity: sha512-sk/Qh1j2/RJSX7FhEpJn8n0ndxy/uf0kI/9Zc4b1ELhqULVdTfN6HL31CDaTChiBAOgLcsJ1sgVZjWv8XNEsAQ==} + cpu: [riscv64] + os: [linux] + + '@rollup/rollup-linux-s390x-gnu@4.14.3': + resolution: {integrity: sha512-jOO/PEaDitOmY9TgkxF/TQIjXySQe5KVYB57H/8LRP/ux0ZoO8cSHCX17asMSv3ruwslXW/TLBcxyaUzGRHcqg==} + cpu: [s390x] + os: [linux] + + '@rollup/rollup-linux-x64-gnu@4.12.0': + resolution: {integrity: sha512-TenQhZVOtw/3qKOPa7d+QgkeM6xY0LtwzR8OplmyL5LrgTWIXpTQg2Q2ycBf8jm+SFW2Wt/DTn1gf7nFp3ssVA==} + cpu: [x64] + os: [linux] + + '@rollup/rollup-linux-x64-gnu@4.14.3': + resolution: {integrity: sha512-8ybV4Xjy59xLMyWo3GCfEGqtKV5M5gCSrZlxkPGvEPCGDLNla7v48S662HSGwRd6/2cSneMQWiv+QzcttLrrOA==} + cpu: [x64] + os: [linux] + + '@rollup/rollup-linux-x64-musl@4.12.0': + resolution: {integrity: sha512-LfFdRhNnW0zdMvdCb5FNuWlls2WbbSridJvxOvYWgSBOYZtgBfW9UGNJG//rwMqTX1xQE9BAodvMH9tAusKDUw==} + cpu: [x64] + os: [linux] + + '@rollup/rollup-linux-x64-musl@4.14.3': + resolution: {integrity: sha512-s+xf1I46trOY10OqAtZ5Rm6lzHre/UiLA1J2uOhCFXWkbZrJRkYBPO6FhvGfHmdtQ3Bx793MNa7LvoWFAm93bg==} + cpu: [x64] + os: [linux] + + '@rollup/rollup-win32-arm64-msvc@4.12.0': + resolution: {integrity: sha512-JPDxovheWNp6d7AHCgsUlkuCKvtu3RB55iNEkaQcf0ttsDU/JZF+iQnYcQJSk/7PtT4mjjVG8N1kpwnI9SLYaw==} + cpu: [arm64] + os: [win32] + + '@rollup/rollup-win32-arm64-msvc@4.14.3': + resolution: {integrity: sha512-+4h2WrGOYsOumDQ5S2sYNyhVfrue+9tc9XcLWLh+Kw3UOxAvrfOrSMFon60KspcDdytkNDh7K2Vs6eMaYImAZg==} + cpu: [arm64] + os: [win32] + + '@rollup/rollup-win32-ia32-msvc@4.12.0': + resolution: {integrity: sha512-fjtuvMWRGJn1oZacG8IPnzIV6GF2/XG+h71FKn76OYFqySXInJtseAqdprVTDTyqPxQOG9Exak5/E9Z3+EJ8ZA==} + cpu: [ia32] + os: [win32] + + '@rollup/rollup-win32-ia32-msvc@4.14.3': + resolution: {integrity: sha512-T1l7y/bCeL/kUwh9OD4PQT4aM7Bq43vX05htPJJ46RTI4r5KNt6qJRzAfNfM+OYMNEVBWQzR2Gyk+FXLZfogGw==} + cpu: [ia32] + os: [win32] + + '@rollup/rollup-win32-x64-msvc@4.12.0': + resolution: {integrity: sha512-ZYmr5mS2wd4Dew/JjT0Fqi2NPB/ZhZ2VvPp7SmvPZb4Y1CG/LRcS6tcRo2cYU7zLK5A7cdbhWnnWmUjoI4qapg==} + cpu: [x64] + os: [win32] + + '@rollup/rollup-win32-x64-msvc@4.14.3': + resolution: {integrity: sha512-/BypzV0H1y1HzgYpxqRaXGBRqfodgoBBCcsrujT6QRcakDQdfU+Lq9PENPh5jB4I44YWq+0C2eHsHya+nZY1sA==} + cpu: [x64] + os: [win32] + + '@shopify/jest-koa-mocks@5.0.0': + resolution: {integrity: sha512-keF5fgqAzWgC4O5uwUgQawp80IsDJdfyyMvWnIcsMaYw9CgURm4CW+v9NskUAn6AeaHd4Tkv+pWCFg/LRHHf4w==} + engines: {node: ^14.17.0 || >=16.0.0} + + '@sideway/address@4.1.5': + resolution: {integrity: sha512-IqO/DUQHUkPeixNQ8n0JA6102hT9CmaljNTPmQ1u8MEhBo/R4Q8eKLN/vGZxuebwOroDB4cbpjheD4+/sKFK4Q==} + + '@sideway/formula@3.0.1': + resolution: {integrity: sha512-/poHZJJVjx3L+zVD6g9KgHfYnb443oi7wLu/XKojDviHy6HOEOA6z1Trk5aR1dGcmPenJEgb2sK2I80LeS3MIg==} + + '@sideway/pinpoint@2.0.0': + resolution: {integrity: sha512-RNiOoTPkptFtSVzQevY/yWtZwf/RxyVnPy/OcA9HBM3MlGDnBEYL5B41H0MTn0Uec8Hi+2qUtTfG2WWZBmMejQ==} + + '@silverhand/eslint-config-react@6.0.2': + resolution: {integrity: sha512-4PqhypLqrX5FVXimKBz3S1c+usDns3N/XG66n2FQtO1FIa8WUVw1CsuWHT+tkqeIxDR1PRQX1e8Iwyy7vPclPA==} + engines: {node: ^20.9.0} + peerDependencies: + stylelint: ^15.0.0 || ^16.0.0 + + '@silverhand/eslint-config@6.0.1': + resolution: {integrity: sha512-v7VbAiNgVwcjwGXe4LK6qNVKgltcm4XX9dkYgyaD22vcYCtp1BSd8NVsPDISV1nAwwirCklL0KSDtcD7pxkbHw==} + engines: {node: ^20.9.0} + peerDependencies: + eslint: ^8.57.0 + prettier: ^3.0.0 + + '@silverhand/eslint-plugin-fp@2.5.0': + resolution: {integrity: sha512-/oLO2Rs9nkhOk+rmC3PsWDvrDKrOfKuRtbSAwH4Scawn5GqAjo7ZXIZXj7RWa4nxLsCGc3ULvaVs1e1m4n6G/A==} + engines: {node: '>=14.15.0'} + peerDependencies: + eslint: ^8.1.0 + + '@silverhand/essentials@2.9.0': + resolution: {integrity: sha512-n9mSO/gsLj0GRFXBRNhaQLRK6qbn6pBnKjMQdFwweKgT12ODBXpgkpXohpOBqSofnoaCQWqiDAT6xpCy/5dMIg==} + engines: {node: ^18.12.0 || ^20.9.0, pnpm: ^8.0.0} + + '@silverhand/slonik@31.0.0-beta.2': + resolution: {integrity: sha512-4IM57Er5We8+hT8IY9z5La1JAGNRFZ63tp3N0XYUYTNV9fLfUXF78yT+PoW4arnf4qc+4n498bMmKgFmt/mo9Q==} + engines: {node: ^20.9.0} + + '@silverhand/ts-config-react@6.0.0': + resolution: {integrity: sha512-eEB8TwGzw5kJTKcuHtvifpcs6p8ZDNRFWH2W7ZM4Rf7DsFBQtXkYpwQFQvZ9UVOAs4YCIeSY4OJCjtaY0fUp8g==} + engines: {node: ^20.9.0} + peerDependencies: + typescript: ^5.3.3 + + '@silverhand/ts-config@6.0.0': + resolution: {integrity: sha512-zgR9vxC/DBx+0ZhCxqGTlZfVX6Bi0/UZztt+8np5I07ahfGMVUJjWedgHNK2NrSX2Nwclr9zLlUbgxwgqi4Idw==} + engines: {node: ^20.9.0} + peerDependencies: + typescript: ^5.3.3 + + '@simplewebauthn/browser@9.0.1': + resolution: {integrity: sha512-wD2WpbkaEP4170s13/HUxPcAV5y4ZXaKo1TfNklS5zDefPinIgXOpgz1kpEvobAsaLPa2KeH7AKKX/od1mrBJw==} + + '@simplewebauthn/server@9.0.1': + resolution: {integrity: sha512-XnilMoBygy2BOZjIHPxby+7ENx5ChN2wXfhd14mOgO/XitYMqdphTo/kwgxEI4/Je3lELK1h/eLDJqM2fIKS1w==} + engines: {node: '>=16.0.0'} + + '@simplewebauthn/types@9.0.1': + resolution: {integrity: sha512-tGSRP1QvsAvsJmnOlRQyw/mvK9gnPtjEc5fg2+m8n+QUa+D7rvrKkOYyfpy42GTs90X3RDOnqJgfHt+qO67/+w==} + + '@sinclair/typebox@0.24.46': + resolution: {integrity: sha512-ng4ut1z2MCBhK/NwDVwIQp3pAUOCs/KNaW3cBxdFB2xTDrOuo1xuNmpr/9HHFhxqIvHrs1NTH3KJg6q+JSy1Kw==} + + '@sinclair/typebox@0.25.21': + resolution: {integrity: sha512-gFukHN4t8K4+wVC+ECqeqwzBDeFeTzBXroBTqE6vcWrQGbEUpHO7LYdG0f4xnvYq4VOEwITSlHlp0JBAIFMS/g==} + + '@sinclair/typebox@0.27.8': + resolution: {integrity: sha512-+Fj43pSMwJs4KRrH/938Uf+uAELIgVBmQzg/q1YG10djyfA3TnrU8N8XzqCh/okZdszqBQTZf96idMfE5lnwTA==} + + '@sindresorhus/is@5.4.0': + resolution: {integrity: sha512-Ggh6E9AnMpiNXlbXfFUcWE9qm408rL8jDi7+PMBBx7TMbwEmiqAiSmZ+zydYwxcJLqPGNDoLc9mXDuMDBZg0sA==} + engines: {node: '>=14.16'} + + '@sindresorhus/is@6.1.0': + resolution: {integrity: sha512-BuvU07zq3tQ/2SIgBsEuxKYDyDjC0n7Zir52bpHy2xnBbW81+po43aLFPLbeV3HRAheFbGud1qgcqSYfhtHMAg==} + engines: {node: '>=16'} + + '@sinonjs/commons@2.0.0': + resolution: {integrity: sha512-uLa0j859mMrg2slwQYdO/AkrOfmH+X6LTVmNTS9CqexuE2IvVORIkSpJLqePAbEnKJ77aMmCwr1NUZ57120Xcg==} + + '@sinonjs/commons@3.0.0': + resolution: {integrity: sha512-jXBtWAF4vmdNmZgD5FoKsVLv3rPgDnLgPbU84LIJ3otV44vJlDRokVng5v8NFJdCf/da9legHcKaRuZs4L7faA==} + + '@sinonjs/fake-timers@10.3.0': + resolution: {integrity: sha512-V4BG07kuYSUkTCSBHG8G8TNhM+F19jXFWnQtzj+we8DrkpSBCee9Z3Ms8yiGer/dlmhe35/Xdgyo3/0rQKg7YA==} + + '@sinonjs/fake-timers@11.2.2': + resolution: {integrity: sha512-G2piCSxQ7oWOxwGSAyFHfPIsyeJGXYtc6mFbnFA+kRXkiEnTl8c/8jul2S329iFBnDI9HGoeWWAZvuvOkZccgw==} + + '@sinonjs/samsam@8.0.0': + resolution: {integrity: sha512-Bp8KUVlLp8ibJZrnvq2foVhP0IVX2CIprMJPK0vqGqgrDa0OHVKeZyBykqskkrdxV6yKBPmGasO8LVjAKR3Gew==} + + '@sinonjs/text-encoding@0.7.2': + resolution: {integrity: sha512-sXXKG+uL9IrKqViTtao2Ws6dy0znu9sOaP1di/jKGW1M6VssO8vlpXCQcpZ+jisQ1tTFAC5Jo/EOzFbggBagFQ==} + + '@smithy/abort-controller@2.2.0': + resolution: {integrity: sha512-wRlta7GuLWpTqtFfGo+nZyOO1vEvewdNR1R4rTxpC8XU6vG/NDyrFBhwLZsqg1NUoR1noVaXJPC/7ZK47QCySw==} + engines: {node: '>=14.0.0'} + + '@smithy/chunked-blob-reader-native@2.2.0': + resolution: {integrity: sha512-VNB5+1oCgX3Fzs072yuRsUoC2N4Zg/LJ11DTxX3+Qu+Paa6AmbIF0E9sc2wthz9Psrk/zcOlTCyuposlIhPjZQ==} + + '@smithy/chunked-blob-reader@2.2.0': + resolution: {integrity: sha512-3GJNvRwXBGdkDZZOGiziVYzDpn4j6zfyULHMDKAGIUo72yHALpE9CbhfQp/XcLNVoc1byfMpn6uW5H2BqPjgaQ==} + + '@smithy/config-resolver@2.2.0': + resolution: {integrity: sha512-fsiMgd8toyUba6n1WRmr+qACzXltpdDkPTAaDqc8QqPBUzO+/JKwL6bUBseHVi8tu9l+3JOK+tSf7cay+4B3LA==} + engines: {node: '>=14.0.0'} + + '@smithy/core@1.4.2': + resolution: {integrity: sha512-2fek3I0KZHWJlRLvRTqxTEri+qV0GRHrJIoLFuBMZB4EMg4WgeBGfF0X6abnrNYpq55KJ6R4D6x4f0vLnhzinA==} + engines: {node: '>=14.0.0'} + + '@smithy/credential-provider-imds@2.3.0': + resolution: {integrity: sha512-BWB9mIukO1wjEOo1Ojgl6LrG4avcaC7T/ZP6ptmAaW4xluhSIPZhY+/PI5YKzlk+jsm+4sQZB45Bt1OfMeQa3w==} + engines: {node: '>=14.0.0'} + + '@smithy/eventstream-codec@2.2.0': + resolution: {integrity: sha512-8janZoJw85nJmQZc4L8TuePp2pk1nxLgkxIR0TUjKJ5Dkj5oelB9WtiSSGXCQvNsJl0VSTvK/2ueMXxvpa9GVw==} + + '@smithy/eventstream-serde-browser@2.2.0': + resolution: {integrity: sha512-UaPf8jKbcP71BGiO0CdeLmlg+RhWnlN8ipsMSdwvqBFigl5nil3rHOI/5GE3tfiuX8LvY5Z9N0meuU7Rab7jWw==} + engines: {node: '>=14.0.0'} + + '@smithy/eventstream-serde-config-resolver@2.2.0': + resolution: {integrity: sha512-RHhbTw/JW3+r8QQH7PrganjNCiuiEZmpi6fYUAetFfPLfZ6EkiA08uN3EFfcyKubXQxOwTeJRZSQmDDCdUshaA==} + engines: {node: '>=14.0.0'} + + '@smithy/eventstream-serde-node@2.2.0': + resolution: {integrity: sha512-zpQMtJVqCUMn+pCSFcl9K/RPNtQE0NuMh8sKpCdEHafhwRsjP50Oq/4kMmvxSRy6d8Jslqd8BLvDngrUtmN9iA==} + engines: {node: '>=14.0.0'} + + '@smithy/eventstream-serde-universal@2.2.0': + resolution: {integrity: sha512-pvoe/vvJY0mOpuF84BEtyZoYfbehiFj8KKWk1ds2AT0mTLYFVs+7sBJZmioOFdBXKd48lfrx1vumdPdmGlCLxA==} + engines: {node: '>=14.0.0'} + + '@smithy/fetch-http-handler@2.5.0': + resolution: {integrity: sha512-BOWEBeppWhLn/no/JxUL/ghTfANTjT7kg3Ww2rPqTUY9R4yHPXxJ9JhMe3Z03LN3aPwiwlpDIUcVw1xDyHqEhw==} + + '@smithy/hash-blob-browser@2.2.0': + resolution: {integrity: sha512-SGPoVH8mdXBqrkVCJ1Hd1X7vh1zDXojNN1yZyZTZsCno99hVue9+IYzWDjq/EQDDXxmITB0gBmuyPh8oAZSTcg==} + + '@smithy/hash-node@2.2.0': + resolution: {integrity: sha512-zLWaC/5aWpMrHKpoDF6nqpNtBhlAYKF/7+9yMN7GpdR8CzohnWfGtMznPybnwSS8saaXBMxIGwJqR4HmRp6b3g==} + engines: {node: '>=14.0.0'} + + '@smithy/hash-stream-node@2.2.0': + resolution: {integrity: sha512-aT+HCATOSRMGpPI7bi7NSsTNVZE/La9IaxLXWoVAYMxHT5hGO3ZOGEMZQg8A6nNL+pdFGtZQtND1eoY084HgHQ==} + engines: {node: '>=14.0.0'} + + '@smithy/invalid-dependency@2.2.0': + resolution: {integrity: sha512-nEDASdbKFKPXN2O6lOlTgrEEOO9NHIeO+HVvZnkqc8h5U9g3BIhWsvzFo+UcUbliMHvKNPD/zVxDrkP1Sbgp8Q==} + + '@smithy/is-array-buffer@2.2.0': + resolution: {integrity: sha512-GGP3O9QFD24uGeAXYUjwSTXARoqpZykHadOmA8G5vfJPK0/DC67qa//0qvqrJzL1xc8WQWX7/yc7fwudjPHPhA==} + engines: {node: '>=14.0.0'} + + '@smithy/md5-js@2.2.0': + resolution: {integrity: sha512-M26XTtt9IIusVMOWEAhIvFIr9jYj4ISPPGJROqw6vXngO3IYJCnVVSMFn4Tx1rUTG5BiKJNg9u2nxmBiZC5IlQ==} + + '@smithy/middleware-content-length@2.2.0': + resolution: {integrity: sha512-5bl2LG1Ah/7E5cMSC+q+h3IpVHMeOkG0yLRyQT1p2aMJkSrZG7RlXHPuAgb7EyaFeidKEnnd/fNaLLaKlHGzDQ==} + engines: {node: '>=14.0.0'} + + '@smithy/middleware-endpoint@2.5.1': + resolution: {integrity: sha512-1/8kFp6Fl4OsSIVTWHnNjLnTL8IqpIb/D3sTSczrKFnrE9VMNWxnrRKNvpUHOJ6zpGD5f62TPm7+17ilTJpiCQ==} + engines: {node: '>=14.0.0'} + + '@smithy/middleware-retry@2.3.1': + resolution: {integrity: sha512-P2bGufFpFdYcWvqpyqqmalRtwFUNUA8vHjJR5iGqbfR6mp65qKOLcUd6lTr4S9Gn/enynSrSf3p3FVgVAf6bXA==} + engines: {node: '>=14.0.0'} + + '@smithy/middleware-serde@2.3.0': + resolution: {integrity: sha512-sIADe7ojwqTyvEQBe1nc/GXB9wdHhi9UwyX0lTyttmUWDJLP655ZYE1WngnNyXREme8I27KCaUhyhZWRXL0q7Q==} + engines: {node: '>=14.0.0'} + + '@smithy/middleware-stack@2.2.0': + resolution: {integrity: sha512-Qntc3jrtwwrsAC+X8wms8zhrTr0sFXnyEGhZd9sLtsJ/6gGQKFzNB+wWbOcpJd7BR8ThNCoKt76BuQahfMvpeA==} + engines: {node: '>=14.0.0'} + + '@smithy/node-config-provider@2.3.0': + resolution: {integrity: sha512-0elK5/03a1JPWMDPaS726Iw6LpQg80gFut1tNpPfxFuChEEklo2yL823V94SpTZTxmKlXFtFgsP55uh3dErnIg==} + engines: {node: '>=14.0.0'} + + '@smithy/node-http-handler@2.5.0': + resolution: {integrity: sha512-mVGyPBzkkGQsPoxQUbxlEfRjrj6FPyA3u3u2VXGr9hT8wilsoQdZdvKpMBFMB8Crfhv5dNkKHIW0Yyuc7eABqA==} + engines: {node: '>=14.0.0'} + + '@smithy/property-provider@2.2.0': + resolution: {integrity: sha512-+xiil2lFhtTRzXkx8F053AV46QnIw6e7MV8od5Mi68E1ICOjCeCHw2XfLnDEUHnT9WGUIkwcqavXjfwuJbGlpg==} + engines: {node: '>=14.0.0'} + + '@smithy/protocol-http@3.3.0': + resolution: {integrity: sha512-Xy5XK1AFWW2nlY/biWZXu6/krgbaf2dg0q492D8M5qthsnU2H+UgFeZLbM76FnH7s6RO/xhQRkj+T6KBO3JzgQ==} + engines: {node: '>=14.0.0'} + + '@smithy/querystring-builder@2.2.0': + resolution: {integrity: sha512-L1kSeviUWL+emq3CUVSgdogoM/D9QMFaqxL/dd0X7PCNWmPXqt+ExtrBjqT0V7HLN03Vs9SuiLrG3zy3JGnE5A==} + engines: {node: '>=14.0.0'} + + '@smithy/querystring-parser@2.2.0': + resolution: {integrity: sha512-BvHCDrKfbG5Yhbpj4vsbuPV2GgcpHiAkLeIlcA1LtfpMz3jrqizP1+OguSNSj1MwBHEiN+jwNisXLGdajGDQJA==} + engines: {node: '>=14.0.0'} + + '@smithy/service-error-classification@2.1.5': + resolution: {integrity: sha512-uBDTIBBEdAQryvHdc5W8sS5YX7RQzF683XrHePVdFmAgKiMofU15FLSM0/HU03hKTnazdNRFa0YHS7+ArwoUSQ==} + engines: {node: '>=14.0.0'} + + '@smithy/shared-ini-file-loader@2.4.0': + resolution: {integrity: sha512-WyujUJL8e1B6Z4PBfAqC/aGY1+C7T0w20Gih3yrvJSk97gpiVfB+y7c46T4Nunk+ZngLq0rOIdeVeIklk0R3OA==} + engines: {node: '>=14.0.0'} + + '@smithy/signature-v4@2.3.0': + resolution: {integrity: sha512-ui/NlpILU+6HAQBfJX8BBsDXuKSNrjTSuOYArRblcrErwKFutjrCNb/OExfVRyj9+26F9J+ZmfWT+fKWuDrH3Q==} + engines: {node: '>=14.0.0'} + + '@smithy/smithy-client@2.5.1': + resolution: {integrity: sha512-jrbSQrYCho0yDaaf92qWgd+7nAeap5LtHTI51KXqmpIFCceKU3K9+vIVTUH72bOJngBMqa4kyu1VJhRcSrk/CQ==} + engines: {node: '>=14.0.0'} + + '@smithy/types@2.12.0': + resolution: {integrity: sha512-QwYgloJ0sVNBeBuBs65cIkTbfzV/Q6ZNPCJ99EICFEdJYG50nGIY/uYXp+TbsdJReIuPr0a0kXmCvren3MbRRw==} + engines: {node: '>=14.0.0'} + + '@smithy/url-parser@2.2.0': + resolution: {integrity: sha512-hoA4zm61q1mNTpksiSWp2nEl1dt3j726HdRhiNgVJQMj7mLp7dprtF57mOB6JvEk/x9d2bsuL5hlqZbBuHQylQ==} + + '@smithy/util-base64@2.3.0': + resolution: {integrity: sha512-s3+eVwNeJuXUwuMbusncZNViuhv2LjVJ1nMwTqSA0XAC7gjKhqqxRdJPhR8+YrkoZ9IiIbFk/yK6ACe/xlF+hw==} + engines: {node: '>=14.0.0'} + + '@smithy/util-body-length-browser@2.2.0': + resolution: {integrity: sha512-dtpw9uQP7W+n3vOtx0CfBD5EWd7EPdIdsQnWTDoFf77e3VUf05uA7R7TGipIo8e4WL2kuPdnsr3hMQn9ziYj5w==} + + '@smithy/util-body-length-node@2.3.0': + resolution: {integrity: sha512-ITWT1Wqjubf2CJthb0BuT9+bpzBfXeMokH/AAa5EJQgbv9aPMVfnM76iFIZVFf50hYXGbtiV71BHAthNWd6+dw==} + engines: {node: '>=14.0.0'} + + '@smithy/util-buffer-from@2.2.0': + resolution: {integrity: sha512-IJdWBbTcMQ6DA0gdNhh/BwrLkDR+ADW5Kr1aZmd4k3DIF6ezMV4R2NIAmT08wQJ3yUK82thHWmC/TnK/wpMMIA==} + engines: {node: '>=14.0.0'} + + '@smithy/util-config-provider@2.3.0': + resolution: {integrity: sha512-HZkzrRcuFN1k70RLqlNK4FnPXKOpkik1+4JaBoHNJn+RnJGYqaa3c5/+XtLOXhlKzlRgNvyaLieHTW2VwGN0VQ==} + engines: {node: '>=14.0.0'} + + '@smithy/util-defaults-mode-browser@2.2.1': + resolution: {integrity: sha512-RtKW+8j8skk17SYowucwRUjeh4mCtnm5odCL0Lm2NtHQBsYKrNW0od9Rhopu9wF1gHMfHeWF7i90NwBz/U22Kw==} + engines: {node: '>= 10.0.0'} + + '@smithy/util-defaults-mode-node@2.3.1': + resolution: {integrity: sha512-vkMXHQ0BcLFysBMWgSBLSk3+leMpFSyyFj8zQtv5ZyUBx8/owVh1/pPEkzmW/DR/Gy/5c8vjLDD9gZjXNKbrpA==} + engines: {node: '>= 10.0.0'} + + '@smithy/util-endpoints@1.2.0': + resolution: {integrity: sha512-BuDHv8zRjsE5zXd3PxFXFknzBG3owCpjq8G3FcsXW3CykYXuEqM3nTSsmLzw5q+T12ZYuDlVUZKBdpNbhVtlrQ==} + engines: {node: '>= 14.0.0'} + + '@smithy/util-hex-encoding@2.2.0': + resolution: {integrity: sha512-7iKXR+/4TpLK194pVjKiasIyqMtTYJsgKgM242Y9uzt5dhHnUDvMNb+3xIhRJ9QhvqGii/5cRUt4fJn3dtXNHQ==} + engines: {node: '>=14.0.0'} + + '@smithy/util-middleware@2.2.0': + resolution: {integrity: sha512-L1qpleXf9QD6LwLCJ5jddGkgWyuSvWBkJwWAZ6kFkdifdso+sk3L3O1HdmPvCdnCK3IS4qWyPxev01QMnfHSBw==} + engines: {node: '>=14.0.0'} + + '@smithy/util-retry@2.2.0': + resolution: {integrity: sha512-q9+pAFPTfftHXRytmZ7GzLFFrEGavqapFc06XxzZFcSIGERXMerXxCitjOG1prVDR9QdjqotF40SWvbqcCpf8g==} + engines: {node: '>= 14.0.0'} + + '@smithy/util-stream@2.2.0': + resolution: {integrity: sha512-17faEXbYWIRst1aU9SvPZyMdWmqIrduZjVOqCPMIsWFNxs5yQQgFrJL6b2SdiCzyW9mJoDjFtgi53xx7EH+BXA==} + engines: {node: '>=14.0.0'} + + '@smithy/util-uri-escape@2.2.0': + resolution: {integrity: sha512-jtmJMyt1xMD/d8OtbVJ2gFZOSKc+ueYJZPW20ULW1GOp/q/YIM0wNh+u8ZFao9UaIGz4WoPW8hC64qlWLIfoDA==} + engines: {node: '>=14.0.0'} + + '@smithy/util-utf8@2.3.0': + resolution: {integrity: sha512-R8Rdn8Hy72KKcebgLiv8jQcQkXoLMOGGv5uI1/k0l+snqkOzQ1R0ChUBCxWMlBsFMekWjq0wRudIweFs7sKT5A==} + engines: {node: '>=14.0.0'} + + '@smithy/util-waiter@2.2.0': + resolution: {integrity: sha512-IHk53BVw6MPMi2Gsn+hCng8rFA3ZmR3Rk7GllxDUW9qFJl/hiSvskn7XldkECapQVkIg/1dHpMAxI9xSTaLLSA==} + engines: {node: '>=14.0.0'} + + '@svgr/babel-plugin-add-jsx-attribute@6.5.1': + resolution: {integrity: sha512-9PYGcXrAxitycIjRmZB+Q0JaN07GZIWaTBIGQzfaZv+qr1n8X1XUEJ5rZ/vx6OVD9RRYlrNnXWExQXcmZeD/BQ==} + engines: {node: '>=10'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@svgr/babel-plugin-remove-jsx-attribute@6.5.0': + resolution: {integrity: sha512-8zYdkym7qNyfXpWvu4yq46k41pyNM9SOstoWhKlm+IfdCE1DdnRKeMUPsWIEO/DEkaWxJ8T9esNdG3QwQ93jBA==} + engines: {node: '>=10'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@svgr/babel-plugin-remove-jsx-empty-expression@6.5.0': + resolution: {integrity: sha512-NFdxMq3xA42Kb1UbzCVxplUc0iqSyM9X8kopImvFnB+uSDdzIHOdbs1op8ofAvVRtbg4oZiyRl3fTYeKcOe9Iw==} + engines: {node: '>=10'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@svgr/babel-plugin-replace-jsx-attribute-value@6.5.1': + resolution: {integrity: sha512-8DPaVVE3fd5JKuIC29dqyMB54sA6mfgki2H2+swh+zNJoynC8pMPzOkidqHOSc6Wj032fhl8Z0TVn1GiPpAiJg==} + engines: {node: '>=10'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@svgr/babel-plugin-svg-dynamic-title@6.5.1': + resolution: {integrity: sha512-FwOEi0Il72iAzlkaHrlemVurgSQRDFbk0OC8dSvD5fSBPHltNh7JtLsxmZUhjYBZo2PpcU/RJvvi6Q0l7O7ogw==} + engines: {node: '>=10'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@svgr/babel-plugin-svg-em-dimensions@6.5.1': + resolution: {integrity: sha512-gWGsiwjb4tw+ITOJ86ndY/DZZ6cuXMNE/SjcDRg+HLuCmwpcjOktwRF9WgAiycTqJD/QXqL2f8IzE2Rzh7aVXA==} + engines: {node: '>=10'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@svgr/babel-plugin-transform-react-native-svg@6.5.1': + resolution: {integrity: sha512-2jT3nTayyYP7kI6aGutkyfJ7UMGtuguD72OjeGLwVNyfPRBD8zQthlvL+fAbAKk5n9ZNcvFkp/b1lZ7VsYqVJg==} + engines: {node: '>=10'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@svgr/babel-plugin-transform-svg-component@6.5.1': + resolution: {integrity: sha512-a1p6LF5Jt33O3rZoVRBqdxL350oge54iZWHNI6LJB5tQ7EelvD/Mb1mfBiZNAan0dt4i3VArkFRjA4iObuNykQ==} + engines: {node: '>=12'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@svgr/babel-preset@6.5.1': + resolution: {integrity: sha512-6127fvO/FF2oi5EzSQOAjo1LE3OtNVh11R+/8FXa+mHx1ptAaS4cknIjnUA7e6j6fwGGJ17NzaTJFUwOV2zwCw==} + engines: {node: '>=10'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@svgr/core@6.5.1': + resolution: {integrity: sha512-/xdLSWxK5QkqG524ONSjvg3V/FkNyCv538OIBdQqPNaAta3AsXj/Bd2FbvR87yMbXO2hFSWiAe/Q6IkVPDw+mw==} + engines: {node: '>=10'} + + '@svgr/hast-util-to-babel-ast@6.5.1': + resolution: {integrity: sha512-1hnUxxjd83EAxbL4a0JDJoD3Dao3hmjvyvyEV8PzWmLK3B9m9NPlW7GKjFyoWE8nM7HnXzPcmmSyOW8yOddSXw==} + engines: {node: '>=10'} + + '@svgr/plugin-jsx@6.5.1': + resolution: {integrity: sha512-+UdQxI3jgtSjCykNSlEMuy1jSRQlGC7pqBCPvkG/2dATdWo082zHTTK3uhnAju2/6XpE6B5mZ3z4Z8Ns01S8Gw==} + engines: {node: '>=10'} + peerDependencies: + '@svgr/core': ^6.0.0 + + '@svgr/plugin-svgo@6.5.1': + resolution: {integrity: sha512-omvZKf8ixP9z6GWgwbtmP9qQMPX4ODXi+wzbVZgomNFsUIlHA1sf4fThdwTWSsZGgvGAG6yE+b/F5gWUkcZ/iQ==} + engines: {node: '>=10'} + peerDependencies: + '@svgr/core': '*' + + '@swc/core-darwin-arm64@1.3.52': + resolution: {integrity: sha512-Y+4YDN7mAhMgqLVMjpIOagFg93uWdQRsJXd3NAXo24CAJXLBuXsiXQdJVdhGavQkF0+NuhFSTGrzB8TknzWQkg==} + engines: {node: '>=10'} + cpu: [arm64] + os: [darwin] + + '@swc/core-darwin-x64@1.3.52': + resolution: {integrity: sha512-XbvBA+DwTedleh/smYA6E1Z1L1tVnF+ULhpszAAW4YYDzH47R73ucCdcSH/aHs4swv+uyvRquKoDtTTNZFvD4A==} + engines: {node: '>=10'} + cpu: [x64] + os: [darwin] + + '@swc/core-linux-arm-gnueabihf@1.3.52': + resolution: {integrity: sha512-YRTLjZcoGH09q0vjg5s6vxOryzAGlMx2Ly6Hq8+8ruBtG3QTsCN3y7MI8mX254xdFCJiTX5YwQheGjRXS7FF9A==} + engines: {node: '>=10'} + cpu: [arm] + os: [linux] + + '@swc/core-linux-arm64-gnu@1.3.52': + resolution: {integrity: sha512-B0HKtj0XpqpqflGKMxFlyXyORN0xshF8TVzUBD/2FgF7o8fE2RM1eqtdf1EzmZTT1hwxLpJXrEj+0gSXfWPW4A==} + engines: {node: '>=10'} + cpu: [arm64] + os: [linux] + + '@swc/core-linux-arm64-musl@1.3.52': + resolution: {integrity: sha512-GCxNjTAborAmv4VV1AMZLyejHLGgIzu13tvLUFqybtU4jFxVbE2ZK4ZnPCfDlWN+eBwyRWk1oNFR2hH+66vaUQ==} + engines: {node: '>=10'} + cpu: [arm64] + os: [linux] + + '@swc/core-linux-x64-gnu@1.3.52': + resolution: {integrity: sha512-mrvDBSkLI3Mza2qcu3uzB5JGwMBYDb1++UQ1VB0RXf2AR21/cCper4P44IpfdeqFz9XyXq18Sh3gblICUCGvig==} + engines: {node: '>=10'} + cpu: [x64] + os: [linux] + + '@swc/core-linux-x64-musl@1.3.52': + resolution: {integrity: sha512-r9RIvKUQv7yBkpXz+QxPAucdoj8ymBlgIm5rLE0b5VmU7dlKBnpAmRBYaITdH6IXhF0pwuG+FHAd5elBcrkIwA==} + engines: {node: '>=10'} + cpu: [x64] + os: [linux] + + '@swc/core-win32-arm64-msvc@1.3.52': + resolution: {integrity: sha512-YRtEr7tDo0Wes3M2ZhigF4erUjWBXeFP+O+iz6ELBBmPG7B7m/lrA21eiW9/90YGnzi0iNo46shK6PfXuPhP+Q==} + engines: {node: '>=10'} + cpu: [arm64] + os: [win32] + + '@swc/core-win32-ia32-msvc@1.3.52': + resolution: {integrity: sha512-t1x6EdYg3nnnmZBkEtmdXwGpVFTnkNCYyTILcn4367tKI6NpcNe75tz6wBUZAWAmol6Bn75je9KHDNC9uBcO2A==} + engines: {node: '>=10'} + cpu: [ia32] + os: [win32] + + '@swc/core-win32-x64-msvc@1.3.52': + resolution: {integrity: sha512-ef0KzcHxWgRii0EyUlgzNA0ycqaRRKxSb6QCO9Ev3tib4SSjbPy0MAndU7f82Ndm/pPmXT+7cciRtZ083vzjZA==} + engines: {node: '>=10'} + cpu: [x64] + os: [win32] + + '@swc/core@1.3.52': + resolution: {integrity: sha512-2LOkkl5Ebyzg1e2pu/tqz5zAAiNAtSR99KZDJz4+FTpo6lYwr+SRkeXSNFrYAReHBMb5VJoimrLDLHJ2X1E7Lg==} + engines: {node: '>=10'} + peerDependencies: + '@swc/helpers': ^0.5.0 + peerDependenciesMeta: + '@swc/helpers': + optional: true + + '@swc/helpers@0.5.1': + resolution: {integrity: sha512-sJ902EfIzn1Fa+qYmjdQqh8tPsoxyBz+8yBKC2HKUxyezKJFwPGOn7pv4WY6QuQW//ySQi5lJjA/ZT9sNWWNTg==} + + '@swc/jest@0.2.26': + resolution: {integrity: sha512-7lAi7q7ShTO3E5Gt1Xqf3pIhRbERxR1DUxvtVa9WKzIB+HGQ7wZP5sYx86zqnaEoKKGhmOoZ7gyW0IRu8Br5+A==} + engines: {npm: '>= 7.0.0'} + peerDependencies: + '@swc/core': '*' + + '@szmarczak/http-timer@5.0.1': + resolution: {integrity: sha512-+PmQX0PiAYPMeVYe237LJAYvOMYW1j2rH5YROyS3b4CTVJum34HfRvKvAzozHAQG0TnHNdUfY9nCeUyRAs//cw==} + engines: {node: '>=14.16'} + + '@testing-library/dom@10.0.0': + resolution: {integrity: sha512-PmJPnogldqoVFf+EwbHvbBJ98MmqASV8kLrBYgsDNxQcFMeIS7JFL48sfyXvuMtgmWO/wMhh25odr+8VhDmn4g==} + engines: {node: '>=18'} + + '@testing-library/react-hooks@8.0.1': + resolution: {integrity: sha512-Aqhl2IVmLt8IovEVarNDFuJDVWVvhnr9/GCU6UUnrYXwgDFF9h2L2o2P9KBni1AST5sT6riAyoukFLyjQUgD/g==} + engines: {node: '>=12'} + peerDependencies: + '@types/react': ^16.9.0 || ^17.0.0 + react: ^16.9.0 || ^17.0.0 || ^18.0.0 + react-dom: ^16.9.0 || ^17.0.0 + react-test-renderer: ^16.9.0 || ^17.0.0 + peerDependenciesMeta: + '@types/react': + optional: true + react-dom: + optional: true + react-test-renderer: + optional: true + + '@testing-library/react@15.0.2': + resolution: {integrity: sha512-5mzIpuytB1ctpyywvyaY2TAAUQVCZIGqwiqFQf6u9lvj/SJQepGUzNV18Xpk+NLCaCE2j7CWrZE0tEf9xLZYiQ==} + engines: {node: '>=18'} + peerDependencies: + react: ^18.0.0 + react-dom: ^18.0.0 + + '@tootallnate/once@2.0.0': + resolution: {integrity: sha512-XCuKFP5PS55gnMVu3dty8KPatLqUoy/ZYzDzAGCQ8JNFCkLXzmI7vNHCR+XpbZaMWQK/vQubr7PkYq8g470J/A==} + engines: {node: '>= 10'} + + '@tootallnate/quickjs-emscripten@0.23.0': + resolution: {integrity: sha512-C5Mc6rdnsaJDjO3UpGW/CQTHtCKaYlScZTly4JIu97Jxo/odCiH0ITnDXSJPTOrEKk/ycSZ0AOgTmkDtkOsvIA==} + + '@trysound/sax@0.2.0': + resolution: {integrity: sha512-L7z9BgrNEcYyUYtF+HaEfiS5ebkh9jXqbszz7pC0hRBPaatV0XjSD3+eHrpqFemQfgwiFF0QPIarnIihIDn7OA==} + engines: {node: '>=10.13.0'} + + '@tsconfig/node10@1.0.9': + resolution: {integrity: sha512-jNsYVVxU8v5g43Erja32laIDHXeoNvFEpX33OK4d6hljo3jDhCBDhx5dhCCTMWUojscpAagGiRkBKxpdl9fxqA==} + + '@tsconfig/node12@1.0.11': + resolution: {integrity: sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag==} + + '@tsconfig/node14@1.0.3': + resolution: {integrity: sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow==} + + '@tsconfig/node16@1.0.4': + resolution: {integrity: sha512-vxhUy4J8lyeyinH7Azl1pdd43GJhZH/tP2weN8TntQblOY+A0XbT8DJk1/oCPuOOyg/Ja757rG0CgHcWC8OfMA==} + + '@types/accepts@1.3.5': + resolution: {integrity: sha512-jOdnI/3qTpHABjM5cx1Hc0sKsPoYCp+DP/GJRGtDlPd7fiV9oXGGIcjW/ZOxLIvjGz8MA+uMZI9metHlgqbgwQ==} + + '@types/aria-query@5.0.1': + resolution: {integrity: sha512-XTIieEY+gvJ39ChLcB4If5zHtPxt3Syj5rgZR+e1ctpmK8NjPf0zFqsz4JpLJT0xla9GFDKjy8Cpu331nrmE1Q==} + + '@types/babel__core@7.1.19': + resolution: {integrity: sha512-WEOTgRsbYkvA/KCsDwVEGkd7WAr1e3g31VHQ8zy5gul/V1qKullU/BU5I68X5v7V3GnB9eotmom4v5a5gjxorw==} + + '@types/babel__generator@7.6.4': + resolution: {integrity: sha512-tFkciB9j2K755yrTALxD44McOrk+gfpIpvC3sxHjRawj6PfnQxrse4Clq5y/Rq+G3mrBurMax/lG8Qn2t9mSsg==} + + '@types/babel__template@7.4.1': + resolution: {integrity: sha512-azBFKemX6kMg5Io+/rdGT0dkGreboUVR0Cdm3fz9QJWpaQGJRQXl7C+6hOTCZcMll7KFyEQpgbYI2lHdsS4U7g==} + + '@types/babel__traverse@7.18.2': + resolution: {integrity: sha512-FcFaxOr2V5KZCviw1TnutEMVUVsGt4D2hP1TAfXZAMKuHYW3xQhe3jTxNPWutgCJ3/X1c5yX8ZoGVEItxKbwBg==} + + '@types/body-parser@1.19.2': + resolution: {integrity: sha512-ALYone6pm6QmwZoAgeyNksccT9Q4AWZQ6PvfwR37GT6r6FWUPguq6sUmNGSMV2Wr761oQoBxwGGa6DR5o1DC9g==} + + '@types/caseless@0.12.5': + resolution: {integrity: sha512-hWtVTC2q7hc7xZ/RLbxapMvDMgUnDvKvMOpKal4DrMyfGBUfB1oKaZlIRr6mJL+If3bAP6sV/QneGzF6tJjZDg==} + + '@types/co-body@6.1.3': + resolution: {integrity: sha512-UhuhrQ5hclX6UJctv5m4Rfp52AfG9o9+d9/HwjxhVB5NjXxr5t9oKgJxN8xRHgr35oo8meUEHUPFWiKg6y71aA==} + + '@types/color-convert@2.0.0': + resolution: {integrity: sha512-m7GG7IKKGuJUXvkZ1qqG3ChccdIM/qBBo913z+Xft0nKCX4hAU/IxKwZBU4cpRZ7GS5kV4vOblUkILtSShCPXQ==} + + '@types/color-name@1.1.1': + resolution: {integrity: sha512-rr+OQyAjxze7GgWrSaJwydHStIhHq2lvY3BOC2Mj7KnzI7XK0Uw1TOOdI9lDoajEbSWLiYgoo4f1R51erQfhPQ==} + + '@types/color@3.0.3': + resolution: {integrity: sha512-X//qzJ3d3Zj82J9sC/C18ZY5f43utPbAJ6PhYt/M7uG6etcF6MRpKdN880KBy43B0BMzSfeT96MzrsNjFI3GbA==} + + '@types/connect@3.4.35': + resolution: {integrity: sha512-cdeYyv4KWoEgpBISTxWvqYsVy444DOqehiF3fM3ne10AmJ62RSyNkUnxMJXHQWRQQX2eR94m5y1IZyDwBjV9FQ==} + + '@types/content-disposition@0.5.4': + resolution: {integrity: sha512-0mPF08jn9zYI0n0Q/Pnz7C4kThdSt+6LD4amsrYDDpgBfrVWa3TcCOxKX1zkGgYniGagRv8heN2cbh+CAn+uuQ==} + + '@types/conventional-commits-parser@5.0.0': + resolution: {integrity: sha512-loB369iXNmAZglwWATL+WRe+CRMmmBPtpolYzIebFaX4YA3x+BEfLqhUAV9WanycKI3TG1IMr5bMJDajDKLlUQ==} + + '@types/cookiejar@2.1.5': + resolution: {integrity: sha512-he+DHOWReW0nghN24E1WUqM0efK4kI9oTqDm6XmK8ZPe2djZ90BSNdGnIyCLzCPw7/pogPlGbzI2wHGGmi4O/Q==} + + '@types/cookies@0.7.7': + resolution: {integrity: sha512-h7BcvPUogWbKCzBR2lY4oqaZbO3jXZksexYJVFvkrFeLgbZjQkU4x8pRq6eg2MHXQhY0McQdqmmsxRWlVAHooA==} + + '@types/debug@4.1.7': + resolution: {integrity: sha512-9AonUzyTjXXhEOa0DnqpzZi6VHlqKMswga9EXjpXnnqxwLtdvPPtlO8evrI5D9S6asFRCQ6v+wpiUKbw+vKqyg==} + + '@types/estree@1.0.5': + resolution: {integrity: sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw==} + + '@types/etag@1.8.1': + resolution: {integrity: sha512-bsKkeSqN7HYyYntFRAmzcwx/dKW4Wa+KVMTInANlI72PWLQmOpZu96j0OqHZGArW4VQwCmJPteQlXaUDeOB0WQ==} + + '@types/express-serve-static-core@4.17.26': + resolution: {integrity: sha512-zeu3tpouA043RHxW0gzRxwCHchMgftE8GArRsvYT0ByDMbn19olQHx5jLue0LxWY6iYtXb7rXmuVtSkhy9YZvQ==} + + '@types/express@4.17.13': + resolution: {integrity: sha512-6bSZTPaTIACxn48l50SR+axgrqm6qXFIxrdAKaG6PaJk3+zuUr35hBlgT7vOmJcum+OEaIBLtHV/qloEAFITeA==} + + '@types/formidable@2.0.6': + resolution: {integrity: sha512-L4HcrA05IgQyNYJj6kItuIkXrInJvsXTPC5B1i64FggWKKqSL+4hgt7asiSNva75AoLQjq29oPxFfU4GAQ6Z2w==} + + '@types/graceful-fs@4.1.5': + resolution: {integrity: sha512-anKkLmZZ+xm4p8JWBf4hElkM4XR+EZeA2M9BAkkTldmcyDY4mbdIJnRghDJH3Ov5ooY7/UAoENtmdMSkaAd7Cw==} + + '@types/hast@2.3.4': + resolution: {integrity: sha512-wLEm0QvaoawEDoTRwzTXp4b4jpwiJDvR5KMnFnVodm3scufTlBOWRD6N1OBf9TZMhjlNsSfcO5V+7AF4+Vy+9g==} + + '@types/hast@3.0.1': + resolution: {integrity: sha512-hs/iBJx2aydugBQx5ETV3ZgeSS0oIreQrFJ4bjBl0XvM4wAmDjFEALY7p0rTSLt2eL+ibjRAAs9dTPiCLtmbqQ==} + + '@types/history@4.7.11': + resolution: {integrity: sha512-qjDJRrmvBMiTx+jyLxvLfJU7UznFuokDv4f3WRuriHKERccVpFU+8XMQUAbDzoiJCsmexxRExQeMwwCdamSKDA==} + + '@types/http-assert@1.5.3': + resolution: {integrity: sha512-FyAOrDuQmBi8/or3ns4rwPno7/9tJTijVW6aQQjK02+kOQ8zmoNg2XJtAuQhvQcy1ASJq38wirX5//9J1EqoUA==} + + '@types/http-cache-semantics@4.0.4': + resolution: {integrity: sha512-1m0bIFVc7eJWyve9S0RnuRgcQqF/Xd5QsUZAZeQFr1Q3/p9JWoQQEqmVy+DPTNpGXwhgIetAoYF8JSc33q29QA==} + + '@types/http-errors@1.8.2': + resolution: {integrity: sha512-EqX+YQxINb+MeXaIqYDASb6U6FCHbWjkj4a1CKDBks3d/QiB2+PqBLyO72vLDgAO1wUI4O+9gweRcQK11bTL/w==} + + '@types/inquirer@9.0.3': + resolution: {integrity: sha512-CzNkWqQftcmk2jaCWdBTf9Sm7xSw4rkI1zpU/Udw3HX5//adEZUIm9STtoRP1qgWj0CWQtJ9UTvqmO2NNjhMJw==} + + '@types/is-ci@3.0.0': + resolution: {integrity: sha512-Q0Op0hdWbYd1iahB+IFNQcWXFq4O0Q5MwQP7uN0souuQ4rPg1vEYcnIOfr1gY+M+6rc8FGoRaBO1mOOvL29sEQ==} + + '@types/istanbul-lib-coverage@2.0.4': + resolution: {integrity: sha512-z/QT1XN4K4KYuslS23k62yDIDLwLFkzxOuMplDtObz0+y7VqJCaO2o+SPwHCvLFZh7xazvvoor2tA/hPz9ee7g==} + + '@types/istanbul-lib-report@3.0.0': + resolution: {integrity: sha512-plGgXAPfVKFoYfa9NpYDAkseG+g6Jr294RqeqcqDixSbU34MZVJRi/P+7Y8GDpzkEwLaGZZOpKIEmeVZNtKsrg==} + + '@types/istanbul-reports@3.0.1': + resolution: {integrity: sha512-c3mAZEuK0lvBp8tmuL74XRKn1+y2dcwOUpH7x4WrF6gk1GIgiluDRgMYQtw2OFcBvAJWlt6ASU3tSqxp0Uu0Aw==} + + '@types/jest@29.4.0': + resolution: {integrity: sha512-VaywcGQ9tPorCX/Jkkni7RWGFfI11whqzs8dvxF41P17Z+z872thvEvlIbznjPJ02kl1HMX3LmLOonsj2n7HeQ==} + + '@types/jsdom@20.0.0': + resolution: {integrity: sha512-YfAchFs0yM1QPDrLm2VHe+WHGtqms3NXnXAMolrgrVP6fgBHHXy1ozAbo/dFtPNtZC/m66bPiCTWYmqp1F14gA==} + + '@types/json-schema@7.0.15': + resolution: {integrity: sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==} + + '@types/json5@0.0.29': + resolution: {integrity: sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ==} + + '@types/keygrip@1.0.2': + resolution: {integrity: sha512-GJhpTepz2udxGexqos8wgaBx4I/zWIDPh/KOGEwAqtuGDkOUJu5eFvwmdBX4AmB8Odsr+9pHCQqiAqDL/yKMKw==} + + '@types/koa-compose@3.2.5': + resolution: {integrity: sha512-B8nG/OoE1ORZqCkBVsup/AKcvjdgoHnfi4pZMn5UwAPCbhk/96xyv284eBYW8JlQbQ7zDmnpFr68I/40mFoIBQ==} + + '@types/koa-compress@4.0.3': + resolution: {integrity: sha512-nJSII/tOSvYCwk3yDEBJLHd8ctkt5CQFZ0j8ZBnHZ2x0hg24z9H1i38lWXA/5z0Ix0uitMW1jov+kVbQI1aNPQ==} + + '@types/koa-logger@3.1.2': + resolution: {integrity: sha512-sioTA1xlKYiIgryANWPRHBkG3XGbWftw9slWADUPC+qvPIY/yRLSrhvX7zkJwMrntub5dPO0GuAoyGGf0yitfQ==} + + '@types/koa-mount@4.0.1': + resolution: {integrity: sha512-HNeg80CVS9Dfq8dGYqCZZCAUm7g6jPCNJ1ydqVLEJxLrjmeburpvq+lOZkE4rxBZ6O38dr3tj9IA3IfbdoI05w==} + + '@types/koa-send@4.1.3': + resolution: {integrity: sha512-daaTqPZlgjIJycSTNjKpHYuKhXYP30atFc1pBcy6HHqB9+vcymDgYTguPdx9tO4HMOqNyz6bz/zqpxt5eLR+VA==} + + '@types/koa@2.13.4': + resolution: {integrity: sha512-dfHYMfU+z/vKtQB7NUrthdAEiSvnLebvBjwHtfFmpZmB7em2N3WVQdHgnFq+xvyVgxW5jKDmjWfLD3lw4g4uTw==} + + '@types/koa@2.15.0': + resolution: {integrity: sha512-7QFsywoE5URbuVnG3loe03QXuGajrnotr3gQkXcEBShORai23MePfFYdhz90FEtBBpkyIYQbVD+evKtloCgX3g==} + + '@types/koa__cors@5.0.0': + resolution: {integrity: sha512-LCk/n25Obq5qlernGOK/2LUwa/2YJb2lxHUkkvYFDOpLXlVI6tKcdfCHRBQnOY4LwH6el5WOLs6PD/a8Uzau6g==} + + '@types/mdast@3.0.10': + resolution: {integrity: sha512-W864tg/Osz1+9f4lrGTZpCSO5/z4608eUp19tbozkq2HJK6i3z1kT0H9tlADXuYIb1YYOBByU4Jsqkk75q48qA==} + + '@types/mdast@4.0.1': + resolution: {integrity: sha512-IlKct1rUTJ1T81d8OHzyop15kGv9A/ff7Gz7IJgrk6jDb4Udw77pCJ+vq8oxZf4Ghpm+616+i1s/LNg/Vh7d+g==} + + '@types/mdx-js__react@1.5.5': + resolution: {integrity: sha512-k8pnaP6JXVlQh18HgL5X6sYFNC/qZnzO7R2+HsmwrwUd+JnnsU0d9lyyT0RQrHg1anxDU36S98TI/fsGtmYqqg==} + + '@types/mdx@2.0.1': + resolution: {integrity: sha512-JPEv4iAl0I+o7g8yVWDwk30es8mfVrjkvh5UeVR2sYPpZCK44vrAPsbJpIS+rJAUxLgaSAMKTEH5Vn5qd9XsrQ==} + + '@types/methods@1.1.4': + resolution: {integrity: sha512-ymXWVrDiCxTBE3+RIrrP533E70eA+9qu7zdWoHuOmGujkYtzf4HQF96b8nwHLqhuf4ykX61IGRIB38CC6/sImQ==} + + '@types/mime@1.3.2': + resolution: {integrity: sha512-YATxVxgRqNH6nHEIsvg6k2Boc1JHI9ZbH5iWFFv/MTkchz3b1ieGDa5T0a9RznNdI0KhVbdbWSN+KWWrQZRxTw==} + + '@types/minimist@1.2.2': + resolution: {integrity: sha512-jhuKLIRrhvCPLqwPcx6INqmKeiA5EWrsCOPhrlFSrbrmU4ZMPjj5Ul/oLCMDO98XRUIwVm78xICz4EPCektzeQ==} + + '@types/ms@0.7.31': + resolution: {integrity: sha512-iiUgKzV9AuaEkZqkOLDIvlQiL6ltuZd9tGcW3gwpnX8JbuiuhFlEGmmFXEXkN50Cvq7Os88IY2v0dkDqXYWVgA==} + + '@types/node-fetch@2.6.2': + resolution: {integrity: sha512-DHqhlq5jeESLy19TYhLakJ07kNumXWjcDdxXsLUMJZ6ue8VZJj4kLPQVE/2mdHh3xZziNF1xppu5lwmS53HR+A==} + + '@types/node@12.20.55': + resolution: {integrity: sha512-J8xLz7q2OFulZ2cyGTLE1TbbZcjpno7FaN6zdJNrgAdrJ+DZzh/uFR6YrTb4C+nXakvud8Q4+rbhoIWlYQbUFQ==} + + '@types/node@20.10.4': + resolution: {integrity: sha512-D08YG6rr8X90YB56tSIuBaddy/UXAA9RKJoFvrsnogAum/0pmjkgi4+2nx96A330FmioegBWmEYQ+syqCFaveg==} + + '@types/node@20.11.20': + resolution: {integrity: sha512-7/rR21OS+fq8IyHTgtLkDK949uzsa6n8BkziAKtPVpugIkO6D+/ooXMvzXxDnZrmtXVfjb1bKQafYpb8s89LOg==} + + '@types/node@20.12.7': + resolution: {integrity: sha512-wq0cICSkRLVaf3UGLMGItu/PtdY7oaXaI/RVU+xliKVOtRna3PRY57ZDfztpDL0n11vfymMUnXv8QwYCO7L1wg==} + + '@types/nodemailer@6.4.7': + resolution: {integrity: sha512-f5qCBGAn/f0qtRcd4SEn88c8Fp3Swct1731X4ryPKqS61/A3LmmzN8zaEz7hneJvpjFbUUgY7lru/B/7ODTazg==} + + '@types/normalize-package-data@2.4.1': + resolution: {integrity: sha512-Gj7cI7z+98M282Tqmp2K5EIsoouUEzbBJhQQzDE3jSIRk6r9gsz0oUokqIUR4u1R3dMHo0pDHM7sNOHyhulypw==} + + '@types/oidc-provider@8.4.4': + resolution: {integrity: sha512-+SlmKc4qlCJLjpw6Du/8cXw18JsPEYyQwoy+xheLkiuNsCz1mPEYI/lRXLQHvfJD9TH6+2/WDTLZQ2UUJ5G4bw==} + + '@types/parse-json@4.0.0': + resolution: {integrity: sha512-//oorEZjL6sbPcKUaCdIGlIUeH26mgzimjBB77G6XRgnDl/L5wOnpyBGRe/Mmf5CVW3PwEBE1NjiMZ/ssFh4wA==} + + '@types/parse5@5.0.3': + resolution: {integrity: sha512-kUNnecmtkunAoQ3CnjmMkzNU/gtxG8guhi+Fk2U/kOpIKjIMKnXGp4IJCgQJrXSgMsWYimYG4TGjz/UzbGEBTw==} + + '@types/pg@8.11.2': + resolution: {integrity: sha512-G2Mjygf2jFMU/9hCaTYxJrwdObdcnuQde1gndooZSOHsNSaCehAuwc7EIuSA34Do8Jx2yZ19KtvW8P0j4EuUXw==} + + '@types/pg@8.6.6': + resolution: {integrity: sha512-O2xNmXebtwVekJDD+02udOncjVcMZQuTEQEMpKJ0ZRf5E7/9JJX3izhKUcUifBkyKpljyUM6BTgy2trmviKlpw==} + + '@types/pluralize@0.0.33': + resolution: {integrity: sha512-JOqsl+ZoCpP4e8TDke9W79FDcSgPAR0l6pixx2JHkhnRjvShyYiAYw2LVsnA7K08Y6DeOnaU6ujmENO4os/cYg==} + + '@types/prop-types@15.7.4': + resolution: {integrity: sha512-rZ5drC/jWjrArrS8BR6SIr4cWpW09RNTYt9AMZo3Jwwif+iacXAqgVjm0B0Bv/S1jhDXKHqRVNCbACkJ89RAnQ==} + + '@types/qrcode@1.5.2': + resolution: {integrity: sha512-W4KDz75m7rJjFbyCctzCtRzZUj+PrUHV+YjqDp50sSRezTbrtEAIq2iTzC6lISARl3qw+8IlcCyljdcVJE0Wug==} + + '@types/qs@6.9.7': + resolution: {integrity: sha512-FGa1F62FT09qcrueBA6qYTrJPVDzah9a+493+o2PCXsesWHIn27G98TsSMs3WPNbZIEj4+VJf6saSFpvD+3Zsw==} + + '@types/range-parser@1.2.4': + resolution: {integrity: sha512-EEhsLsD6UsDM1yFhAvy0Cjr6VwmpMWqFBCb9w07wVugF7w9nfajxLuVmngTIpgS6svCnm6Vaw+MZhoDCKnOfsw==} + + '@types/react-color@3.0.6': + resolution: {integrity: sha512-OzPIO5AyRmLA7PlOyISlgabpYUa3En74LP8mTMa0veCA719SvYQov4WLMsHvCgXP+L+KI9yGhYnqZafVGG0P4w==} + + '@types/react-dom@18.0.6': + resolution: {integrity: sha512-/5OFZgfIPSwy+YuIBP/FgJnQnsxhZhjjrnxudMddeblOouIodEQ75X14Rr4wGSG/bknL+Omy9iWlLo1u/9GzAA==} + + '@types/react-helmet@6.1.6': + resolution: {integrity: sha512-ZKcoOdW/Tg+kiUbkFCBtvDw0k3nD4HJ/h/B9yWxN4uDO8OkRksWTO+EL+z/Qu3aHTeTll3Ro0Cc/8UhwBCMG5A==} + + '@types/react-modal@3.13.1': + resolution: {integrity: sha512-iY/gPvTDIy6Z+37l+ibmrY+GTV4KQTHcCyR5FIytm182RQS69G5ps4PH2FxtC7bAQ2QRHXMevsBgck7IQruHNg==} + + '@types/react-router-dom@5.3.2': + resolution: {integrity: sha512-ELEYRUie2czuJzaZ5+ziIp9Hhw+juEw8b7C11YNA4QdLCVbQ3qLi2l4aq8XnlqM7V31LZX8dxUuFUCrzHm6sqQ==} + + '@types/react-router@5.1.17': + resolution: {integrity: sha512-RNSXOyb3VyRs/EOGmjBhhGKTbnN6fHWvy5FNLzWfOWOGjgVUKqJZXfpKzLmgoU8h6Hj8mpALj/mbXQASOb92wQ==} + + '@types/react-syntax-highlighter@15.5.1': + resolution: {integrity: sha512-+yD6D8y21JqLf89cRFEyRfptVMqo2ROHyAlysRvFwT28gT5gDo3KOiXHwGilHcq9y/OKTjlWK0f/hZUicrBFPQ==} + + '@types/react@18.0.31': + resolution: {integrity: sha512-EEG67of7DsvRDU6BLLI0p+k1GojDLz9+lZsnCpCRTa/lOokvyPBvp8S5x+A24hME3yyQuIipcP70KJ6H7Qupww==} + + '@types/reactcss@1.2.6': + resolution: {integrity: sha512-qaIzpCuXNWomGR1Xq8SCFTtF4v8V27Y6f+b9+bzHiv087MylI/nTCqqdChNeWS7tslgROmYB7yeiruWX7WnqNg==} + + '@types/request@2.48.12': + resolution: {integrity: sha512-G3sY+NpsA9jnwm0ixhAFQSJ3Q9JkpLZpJbI3GMv0mIAT0y3mRabYeINzal5WOChIiaTEGQYlHOKgkaM9EisWHw==} + + '@types/resolve@1.20.2': + resolution: {integrity: sha512-60BCwRFOZCQhDncwQdxxeOEEkbc5dIMccYLwbxsS4TUNeVECQ/pBJ0j09mrHOl/JJvpRPGwO9SvE4nR2Nb/a4Q==} + + '@types/retry@0.12.2': + resolution: {integrity: sha512-XISRgDJ2Tc5q4TRqvgJtzsRkFYNJzZrhTdtMoGVBttwzzQJkPnS3WWTFc7kuDRoPtPakl+T+OfdEUjYJj7Jbow==} + + '@types/scheduler@0.16.2': + resolution: {integrity: sha512-hppQEBDmlwhFAXKJX2KnWLYu5yMfi91yazPb2l+lbJiwW+wdo1gNeRA+3RgNSO39WYX2euey41KEwnqesU2Jew==} + + '@types/semver@7.3.12': + resolution: {integrity: sha512-WwA1MW0++RfXmCr12xeYOOC5baSC9mSb0ZqCquFzKhcoF4TvHu5MKOuXsncgZcpVFhB1pXd5hZmM0ryAoCp12A==} + + '@types/semver@7.5.0': + resolution: {integrity: sha512-G8hZ6XJiHnuhQKR7ZmysCeJWE08o8T0AXtk5darsCaTVsYZhhgUrq53jizaR2FvsoeCwJhlmwTjkXBY5Pn/ZHw==} + + '@types/semver@7.5.8': + resolution: {integrity: sha512-I8EUhyrgfLrcTkzV3TSsGyl1tSuPrEDzr0yd5m90UgNxQkyDXULk3b6MlQqTCpZpNtWe1K0hzclnZkTcLBe2UQ==} + + '@types/serve-static@1.13.10': + resolution: {integrity: sha512-nCkHGI4w7ZgAdNkrEu0bv+4xNV/XDqW+DydknebMOQwkpDGx8G+HTlj7R7ABI8i8nKxVw0wtKPi1D+lPOkh4YQ==} + + '@types/shimmer@1.0.2': + resolution: {integrity: sha512-dKkr1bTxbEsFlh2ARpKzcaAmsYixqt9UyCdoEZk8rHyE4iQYcDCyvSjDSf7JUWJHlJiTtbIoQjxKh6ViywqDAg==} + + '@types/sinon@17.0.2': + resolution: {integrity: sha512-Zt6heIGsdqERkxctIpvN5Pv3edgBrhoeb3yHyxffd4InN0AX2SVNKSrhdDZKGQICVOxWP/q4DyhpfPNMSrpIiA==} + + '@types/sinonjs__fake-timers@8.1.2': + resolution: {integrity: sha512-9GcLXF0/v3t80caGs5p2rRfkB+a8VBGLJZVih6CNFkx8IZ994wiKKLSRs9nuFwk1HevWs/1mnUmkApGrSGsShA==} + + '@types/stack-utils@2.0.1': + resolution: {integrity: sha512-Hl219/BT5fLAaz6NDkSuhzasy49dwQS/DSdu4MdggFB8zcXv7vflBI3xp7FEmkmdDkBUI2bPUNeMttp2knYdxw==} + + '@types/superagent@8.1.1': + resolution: {integrity: sha512-YQyEXA4PgCl7EVOoSAS3o0fyPFU6erv5mMixztQYe1bqbWmmn8c+IrqoxjQeZe4MgwXikgcaZPiI/DsbmOVlzA==} + + '@types/supertest@6.0.2': + resolution: {integrity: sha512-137ypx2lk/wTQbW6An6safu9hXmajAifU/s7szAHLN/FeIm5w7yR0Wkl9fdJMRSHwOn4HLAI0DaB2TOORuhPDg==} + + '@types/tar@6.1.12': + resolution: {integrity: sha512-FwbJPi9YuovB6ilnHrz8Y4pb0Fh6N7guFkbnlCl39ua893Qi5gkXui7LSDpTQMJCmA4z5f6SeSrTPQEWLdtFVw==} + + '@types/through@0.0.30': + resolution: {integrity: sha512-FvnCJljyxhPM3gkRgWmxmDZyAQSiBQQWLI0A0VFL0K7W1oRUrPJSqNO0NvTnLkBcotdlp3lKvaT0JrnyRDkzOg==} + + '@types/tough-cookie@4.0.2': + resolution: {integrity: sha512-Q5vtl1W5ue16D+nIaW8JWebSSraJVlK+EthKn7e7UcD4KWsaSJ8BqGPXNaPghgtcn/fhvrN17Tv8ksUsQpiplw==} + + '@types/tunnel@0.0.3': + resolution: {integrity: sha512-sOUTGn6h1SfQ+gbgqC364jLFBw2lnFqkgF3q0WovEHRLMrVD1sd5aufqi/aJObLekJO+Aq5z646U4Oxy6shXMA==} + + '@types/unist@2.0.6': + resolution: {integrity: sha512-PBjIUxZHOuj0R15/xuwJYjFi+KZdNFrehocChv4g5hu6aFroHue8m0lBP0POdK2nKzbw0cgV1mws8+V/JAcEkQ==} + + '@types/unist@3.0.0': + resolution: {integrity: sha512-MFETx3tbTjE7Uk6vvnWINA/1iJ7LuMdO4fcq8UfF0pRbj01aGLduVvQcRyswuACJdpnHgg8E3rQLhaRdNEJS0w==} + + '@types/yargs-parser@21.0.0': + resolution: {integrity: sha512-iO9ZQHkZxHn4mSakYV0vFHAVDyEOIJQrV2uZ06HxEPcx+mt8swXoZHIbaaJ2crJYFfErySgktuTZ3BeLz+XmFA==} + + '@types/yargs@16.0.4': + resolution: {integrity: sha512-T8Yc9wt/5LbJyCaLiHPReJa0kApcIgJ7Bn735GjItUfh08Z1pJvu8QZqb9s+mMvKV6WUQRV7K2R46YbjMXTTJw==} + + '@types/yargs@17.0.13': + resolution: {integrity: sha512-9sWaruZk2JGxIQU+IhI1fhPYRcQ0UuTNuKuCW9bR5fp7qi2Llf7WDzNa17Cy7TKnh3cdxDOiyTu6gaLS0eDatg==} + + '@types/yauzl@2.10.3': + resolution: {integrity: sha512-oJoftv0LSuaDZE3Le4DbKX+KS9G36NzOeSap90UIK0yMA/NhKJhqlSGtNDORNRaIbQfzjXDrQa0ytJ6mNRGz/Q==} + + '@typescript-eslint/eslint-plugin@7.7.0': + resolution: {integrity: sha512-GJWR0YnfrKnsRoluVO3PRb9r5aMZriiMMM/RHj5nnTrBy1/wIgk76XCtCKcnXGjpZQJQRFtGV9/0JJ6n30uwpQ==} + engines: {node: ^18.18.0 || >=20.0.0} + peerDependencies: + '@typescript-eslint/parser': ^7.0.0 + eslint: ^8.56.0 + typescript: '*' + peerDependenciesMeta: + typescript: + optional: true + + '@typescript-eslint/parser@7.7.0': + resolution: {integrity: sha512-fNcDm3wSwVM8QYL4HKVBggdIPAy9Q41vcvC/GtDobw3c4ndVT3K6cqudUmjHPw8EAp4ufax0o58/xvWaP2FmTg==} + engines: {node: ^18.18.0 || >=20.0.0} + peerDependencies: + eslint: ^8.56.0 + typescript: '*' + peerDependenciesMeta: + typescript: + optional: true + + '@typescript-eslint/scope-manager@7.7.0': + resolution: {integrity: sha512-/8INDn0YLInbe9Wt7dK4cXLDYp0fNHP5xKLHvZl3mOT5X17rK/YShXaiNmorl+/U4VKCVIjJnx4Ri5b0y+HClw==} + engines: {node: ^18.18.0 || >=20.0.0} + + '@typescript-eslint/type-utils@7.7.0': + resolution: {integrity: sha512-bOp3ejoRYrhAlnT/bozNQi3nio9tIgv3U5C0mVDdZC7cpcQEDZXvq8inrHYghLVwuNABRqrMW5tzAv88Vy77Sg==} + engines: {node: ^18.18.0 || >=20.0.0} + peerDependencies: + eslint: ^8.56.0 + typescript: '*' + peerDependenciesMeta: + typescript: + optional: true + + '@typescript-eslint/types@7.7.0': + resolution: {integrity: sha512-G01YPZ1Bd2hn+KPpIbrAhEWOn5lQBrjxkzHkWvP6NucMXFtfXoevK82hzQdpfuQYuhkvFDeQYbzXCjR1z9Z03w==} + engines: {node: ^18.18.0 || >=20.0.0} + + '@typescript-eslint/typescript-estree@7.7.0': + resolution: {integrity: sha512-8p71HQPE6CbxIBy2kWHqM1KGrC07pk6RJn40n0DSc6bMOBBREZxSDJ+BmRzc8B5OdaMh1ty3mkuWRg4sCFiDQQ==} + engines: {node: ^18.18.0 || >=20.0.0} + peerDependencies: + typescript: '*' + peerDependenciesMeta: + typescript: + optional: true + + '@typescript-eslint/utils@7.7.0': + resolution: {integrity: sha512-LKGAXMPQs8U/zMRFXDZOzmMKgFv3COlxUQ+2NMPhbqgVm6R1w+nU1i4836Pmxu9jZAuIeyySNrN/6Rc657ggig==} + engines: {node: ^18.18.0 || >=20.0.0} + peerDependencies: + eslint: ^8.56.0 + + '@typescript-eslint/visitor-keys@7.7.0': + resolution: {integrity: sha512-h0WHOj8MhdhY8YWkzIF30R379y0NqyOHExI9N9KCzvmu05EgG4FumeYa3ccfKUSphyWkWQE1ybVrgz/Pbam6YA==} + engines: {node: ^18.18.0 || >=20.0.0} + + '@ungap/structured-clone@1.2.0': + resolution: {integrity: sha512-zuVdFrMJiuCDQUMCzQaD6KL28MjnqqN8XnAqiEq9PNm/hCPTSGfrXCOfwj1ow4LFb/tNymJPwsNbVePc1xFqrQ==} + + '@vitest/coverage-v8@1.4.0': + resolution: {integrity: sha512-4hDGyH1SvKpgZnIByr9LhGgCEuF9DKM34IBLCC/fVfy24Z3+PZ+Ii9hsVBsHvY1umM1aGPEjceRkzxCfcQ10wg==} + peerDependencies: + vitest: 1.4.0 + + '@vitest/expect@1.4.0': + resolution: {integrity: sha512-Jths0sWCJZ8BxjKe+p+eKsoqev1/T8lYcrjavEaz8auEJ4jAVY0GwW3JKmdVU4mmNPLPHixh4GNXP7GFtAiDHA==} + + '@vitest/runner@1.4.0': + resolution: {integrity: sha512-EDYVSmesqlQ4RD2VvWo3hQgTJ7ZrFQ2VSJdfiJiArkCerDAGeyF1i6dHkmySqk573jLp6d/cfqCN+7wUB5tLgg==} + + '@vitest/snapshot@1.4.0': + resolution: {integrity: sha512-saAFnt5pPIA5qDGxOHxJ/XxhMFKkUSBJmVt5VgDsAqPTX6JP326r5C/c9UuCMPoXNzuudTPsYDZCoJ5ilpqG2A==} + + '@vitest/spy@1.4.0': + resolution: {integrity: sha512-Ywau/Qs1DzM/8Uc+yA77CwSegizMlcgTJuYGAi0jujOteJOUf1ujunHThYo243KG9nAyWT3L9ifPYZ5+As/+6Q==} + + '@vitest/utils@1.4.0': + resolution: {integrity: sha512-mx3Yd1/6e2Vt/PUC98DcqTirtfxUyAZ32uK82r8rZzbtBeBo+nqgnjx/LvqQdWsrvNtm14VmurNgcf4nqY5gJg==} + + '@withtyped/client@0.8.7': + resolution: {integrity: sha512-qK+Tsczvko8mBRACtHGYj0CdMZFaBmosMGUahTAr544Jb183INPZPn/NpUFtTEpl5g3e4lUjMc5jPH0V78D0+g==} + + '@withtyped/server@0.13.6': + resolution: {integrity: sha512-l+jaZ6Gy/S3oF9q91JuHtWlRqB+bK8ycniAK2atK05/ZfhS/qBPV/JPA18fM+JzSQA+tr3CYXnul5SshmYsRoA==} + peerDependencies: + zod: ^3.19.1 + + '@withtyped/shared@0.2.2': + resolution: {integrity: sha512-Vpcj12NqaoZ8M5Z/1kffheI9FBZEm9goed0THmgTcMKXLHjXSRbMZMp0olVxovEgaTIAydshqJOQUXKZMctIZw==} + + '@xmldom/xmldom@0.8.7': + resolution: {integrity: sha512-sI1Ly2cODlWStkINzqGrZ8K6n+MTSbAeQnAipGyL+KZCXuHaRlj2gyyy8B/9MvsFFqN7XHryQnB2QwhzvJXovg==} + engines: {node: '>=10.0.0'} + + JSONStream@1.3.5: + resolution: {integrity: sha512-E+iruNOY8VV9s4JEbe1aNEm6MiszPRr/UfcHMz0TQh1BXSxHK+ASV1R6W4HpjBhSeS+54PIsAMCBmwD06LLsqQ==} + hasBin: true + + abab@2.0.6: + resolution: {integrity: sha512-j2afSsaIENvHZN2B8GOpF566vZ5WVk5opAiMTvWgaQT8DkbOqsTfvNAvHoRGU2zzP8cPoqys+xHTRDWW8L+/BA==} + + abbrev@1.1.1: + resolution: {integrity: sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==} + + abort-controller@3.0.0: + resolution: {integrity: sha512-h8lQ8tacZYnR3vNQTgibj+tODHI5/+l06Au2Pcriv/Gmet0eaj4TwWH41sO9wnHDiQsEj19q0drzdWdeAHtweg==} + engines: {node: '>=6.5'} + + abortcontroller-polyfill@1.7.5: + resolution: {integrity: sha512-JMJ5soJWP18htbbxJjG7bG6yuI6pRhgJ0scHHTfkUjf6wjP912xZWvM+A4sJK3gqd9E8fcPbDnOefbA9Th/FIQ==} + + accepts@1.3.7: + resolution: {integrity: sha512-Il80Qs2WjYlJIBNzNkK6KYqlVMTbZLXgHx2oT0pU/fjRHyEp+PEfEPY0R3WCwAGVOtauxh1hOxNgIf5bv7dQpA==} + engines: {node: '>= 0.6'} + + accepts@1.3.8: + resolution: {integrity: sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==} + engines: {node: '>= 0.6'} + + acorn-globals@7.0.1: + resolution: {integrity: sha512-umOSDSDrfHbTNPuNpC2NSnnA3LUrqpevPb4T9jRx4MagXNS0rs+gwiTcAvqCRmsD6utzsrzNt+ebm00SNWiC3Q==} + + acorn-import-assertions@1.9.0: + resolution: {integrity: sha512-cmMwop9x+8KFhxvKrKfPYmN6/pKTYYHBqLa0DfvVZcKMJWNyWLnaqND7dx/qn66R7ewM1UX5XMaDVP5wlVTaVA==} + peerDependencies: + acorn: ^8 + + acorn-jsx@5.3.2: + resolution: {integrity: sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==} + peerDependencies: + acorn: ^6.0.0 || ^7.0.0 || ^8.0.0 + + acorn-walk@8.2.0: + resolution: {integrity: sha512-k+iyHEuPgSw6SbuDpGQM+06HQUa04DZ3o+F6CSzXMvvI5KMvnaEqXe+YVe555R9nn6GPt404fos4wcgpw12SDA==} + engines: {node: '>=0.4.0'} + + acorn-walk@8.3.2: + resolution: {integrity: sha512-cjkyv4OtNCIeqhHrfS81QWXoCBPExR/J62oyEqepVw8WaQeSqpW2uhuLPh1m9eWhDuOo/jUXVTlifvesOWp/4A==} + engines: {node: '>=0.4.0'} + + acorn@8.10.0: + resolution: {integrity: sha512-F0SAmZ8iUtS//m8DmCTA0jlh6TDKkHQyK6xc6V4KDTyZKA9dnvX9/3sRTVQrWm79glUAZbnmmNcdYwUIHWVybw==} + engines: {node: '>=0.4.0'} + hasBin: true + + acorn@8.11.3: + resolution: {integrity: sha512-Y9rRfJG5jcKOE0CLisYbojUjIrIEE7AGMzA/Sm4BslANhbS+cDMpgBdcPT91oJ7OuJ9hYJBx59RjbhxVnrF8Xg==} + engines: {node: '>=0.4.0'} + hasBin: true + + agent-base@6.0.2: + resolution: {integrity: sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==} + engines: {node: '>= 6.0.0'} + + agent-base@7.1.0: + resolution: {integrity: sha512-o/zjMZRhJxny7OyEF+Op8X+efiELC7k7yOjMzgfzVqOzXqkBkWI79YoTdOtsuWd5BWhAGAuOY/Xa6xpiaWXiNg==} + engines: {node: '>= 14'} + + ajv-draft-04@1.0.0: + resolution: {integrity: sha512-mv00Te6nmYbRp5DCwclxtt7yV/joXJPGS7nM+97GdxvuttCOfgI3K4U25zboyeX0O+myI8ERluxQe5wljMmVIw==} + peerDependencies: + ajv: ^8.5.0 + peerDependenciesMeta: + ajv: + optional: true + + ajv-formats@2.1.1: + resolution: {integrity: sha512-Wx0Kx52hxE7C18hkMEggYlEifqWZtYaRgouJor+WMdPnQyEK13vgEWyVNup7SoeeoLMsr4kf5h6dOW11I15MUA==} + peerDependencies: + ajv: ^8.0.0 + peerDependenciesMeta: + ajv: + optional: true + + ajv@6.12.6: + resolution: {integrity: sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==} + + ajv@8.12.0: + resolution: {integrity: sha512-sRu1kpcO9yLtYxBKvqfTeh9KzZEwO3STyX1HT+4CaDzC6HpTGYhIhPIzj9XuKU7KYDwnaeh5hcOwjy1QuJzBPA==} + + ansi-colors@4.1.3: + resolution: {integrity: sha512-/6w/C21Pm1A7aZitlI5Ni/2J6FFQN8i1Cvz3kHABAAbw93v/NlvKdVOqz7CCWz/3iv/JplRSEEZ83XION15ovw==} + engines: {node: '>=6'} + + ansi-escapes@4.3.2: + resolution: {integrity: sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==} + engines: {node: '>=8'} + + ansi-escapes@5.0.0: + resolution: {integrity: sha512-5GFMVX8HqE/TB+FuBJGuO5XG0WrsA6ptUqoODaT/n9mmUaZFkqnBueB4leqGBCmrUHnCnC4PCZTCd0E7QQ83bA==} + engines: {node: '>=12'} + + ansi-escapes@6.0.0: + resolution: {integrity: sha512-IG23inYII3dWlU2EyiAiGj6Bwal5GzsgPMwjYGvc1HPE2dgbj4ZB5ToWBKSquKw74nB3TIuOwaI6/jSULzfgrw==} + engines: {node: '>=14.16'} + + ansi-regex@5.0.1: + resolution: {integrity: sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==} + engines: {node: '>=8'} + + ansi-regex@6.0.1: + resolution: {integrity: sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==} + engines: {node: '>=12'} + + ansi-styles@3.2.1: + resolution: {integrity: sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==} + engines: {node: '>=4'} + + ansi-styles@4.3.0: + resolution: {integrity: sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==} + engines: {node: '>=8'} + + ansi-styles@5.2.0: + resolution: {integrity: sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==} + engines: {node: '>=10'} + + ansi-styles@6.2.1: + resolution: {integrity: sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==} + engines: {node: '>=12'} + + anymatch@3.1.3: + resolution: {integrity: sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==} + engines: {node: '>= 8'} + + applicationinsights@2.9.5: + resolution: {integrity: sha512-APQ8IWyYDHFvKbitFKpsmZXxkzQh0yYTFacQqoVW7HwlPo3eeLprwnq5RFNmmG6iqLmvQ+xRJSDLEQCgqPh+bw==} + engines: {node: '>=8.0.0'} + peerDependencies: + applicationinsights-native-metrics: '*' + peerDependenciesMeta: + applicationinsights-native-metrics: + optional: true + + arg@4.1.3: + resolution: {integrity: sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==} + + argparse@1.0.10: + resolution: {integrity: sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==} + + argparse@2.0.1: + resolution: {integrity: sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==} + + aria-query@5.3.0: + resolution: {integrity: sha512-b0P0sZPKtyu8HkeRAfCq0IfURZK+SuwMjY1UXGBU27wpAiTwQAIlq56IbIO+ytk/JjS1fMR14ee5WBBfKi5J6A==} + + array-buffer-byte-length@1.0.1: + resolution: {integrity: sha512-ahC5W1xgou+KTXix4sAO8Ki12Q+jf4i0+tmk3sC+zgcynshkHxzpXdImBehiUYKKKDwvfFiJl1tZt6ewscS1Mg==} + engines: {node: '>= 0.4'} + + array-ify@1.0.0: + resolution: {integrity: sha512-c5AMf34bKdvPhQ7tBGhqkgKNUzMr4WUs+WDtC2ZUGOUncbxKMTvqxYctiseW3+L4bA8ec+GcZ6/A/FW4m8ukng==} + + array-includes@3.1.8: + resolution: {integrity: sha512-itaWrbYbqpGXkGhZPGUulwnhVf5Hpy1xiCFsGqyIGglbBxmG5vSjxQen3/WGOjPpNEv1RtBLKxbmVXm8HpJStQ==} + engines: {node: '>= 0.4'} + + array-union@2.1.0: + resolution: {integrity: sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==} + engines: {node: '>=8'} + + array.prototype.findlast@1.2.5: + resolution: {integrity: sha512-CVvd6FHg1Z3POpBLxO6E6zr+rSKEQ9L6rZHAaY7lLfhKsWYUBBOuMs0e9o24oopj6H+geRCX0YJ+TJLBK2eHyQ==} + engines: {node: '>= 0.4'} + + array.prototype.findlastindex@1.2.5: + resolution: {integrity: sha512-zfETvRFA8o7EiNn++N5f/kaCw221hrpGsDmcpndVupkPzEc1Wuf3VgC0qby1BbHs7f5DVYjgtEU2LLh5bqeGfQ==} + engines: {node: '>= 0.4'} + + array.prototype.flat@1.3.1: + resolution: {integrity: sha512-roTU0KWIOmJ4DRLmwKd19Otg0/mT3qPNt0Qb3GWW8iObuZXxrjB/pzn0R3hqpRSWg4HCwqx+0vwOnWnvlOyeIA==} + engines: {node: '>= 0.4'} + + array.prototype.flat@1.3.2: + resolution: {integrity: sha512-djYB+Zx2vLewY8RWlNCUdHjDXs2XOgm602S9E7P/UpHgfeHL00cRiIF+IN/G/aUJ7kGPb6yO/ErDI5V2s8iycA==} + engines: {node: '>= 0.4'} + + array.prototype.flatmap@1.3.2: + resolution: {integrity: sha512-Ewyx0c9PmpcsByhSW4r+9zDU7sGjFc86qf/kKtuSCRdhfbk0SNLLkaT5qvcHnRGgc5NP/ly/y+qkXkqONX54CQ==} + engines: {node: '>= 0.4'} + + array.prototype.toreversed@1.1.2: + resolution: {integrity: sha512-wwDCoT4Ck4Cz7sLtgUmzR5UV3YF5mFHUlbChCzZBQZ+0m2cl/DH3tKgvphv1nKgFsJ48oCSg6p91q2Vm0I/ZMA==} + + array.prototype.tosorted@1.1.3: + resolution: {integrity: sha512-/DdH4TiTmOKzyQbp/eadcCVexiCb36xJg7HshYOYJnNZFDj33GEv0P7GxsynpShhq4OLYJzbGcBDkLsDt7MnNg==} + + arraybuffer.prototype.slice@1.0.3: + resolution: {integrity: sha512-bMxMKAjg13EBSVscxTaYA4mRc5t1UAXa2kXiGTNfZ079HIWXEkKmkgFrh/nJqamaLSrXO5H4WFFkPEaLJWbs3A==} + engines: {node: '>= 0.4'} + + arrify@1.0.1: + resolution: {integrity: sha512-3CYzex9M9FGQjCGMGyi6/31c8GJbgb0qGyrx5HWxPd0aCwh4cB2YjMb2Xf9UuoogrMrlO9cTqnB5rI5GHZTcUA==} + engines: {node: '>=0.10.0'} + + arrify@2.0.1: + resolution: {integrity: sha512-3duEwti880xqi4eAMN8AyR4a0ByT90zoYdLlevfrvU43vb0YZwZVfxOgxWrLXXXpyugL0hNZc9G6BiB5B3nUug==} + engines: {node: '>=8'} + + asap@2.0.6: + resolution: {integrity: sha512-BSHWgDSAiKs50o2Re8ppvp3seVHXSRM44cdSsT9FfNEUUZLOGWVCsiWaRPWM1Znn+mqZ1OfVZ3z3DWEzSp7hRA==} + + asn1@0.2.6: + resolution: {integrity: sha512-ix/FxPn0MDjeyJ7i/yoHGFt/EX6LyNbxSEhPPXODPL+KB0VPk86UYfL0lMdy+KCnv+fmvIzySwaK5COwqVbWTQ==} + + asn1js@3.0.5: + resolution: {integrity: sha512-FVnvrKJwpt9LP2lAMl8qZswRNm3T4q9CON+bxldk2iwk3FFpuwhx2FfinyitizWHsVYyaY+y5JzDR0rCMV5yTQ==} + engines: {node: '>=12.0.0'} + + assertion-error@1.1.0: + resolution: {integrity: sha512-jgsaNduz+ndvGyFt3uSuWqvy4lCnIJiovtouQN5JZHOKCS2QuhEdbcQHFhVksz2N2U9hXJo8odG7ETyWlEeuDw==} + + ast-types-flow@0.0.8: + resolution: {integrity: sha512-OH/2E5Fg20h2aPrbe+QL8JZQFko0YZaF+j4mnQ7BGhfavO7OpSLa8a0y9sBwomHdSbkhTS8TQNayBfnW5DwbvQ==} + + ast-types@0.13.4: + resolution: {integrity: sha512-x1FCFnFifvYDDzTaLII71vG5uvDwgtmDTEVWAxrgeiR8VjMONcCXJx7E+USjDtHlwFmt9MysbqgF9b9Vjr6w+w==} + engines: {node: '>=4'} + + astral-regex@2.0.0: + resolution: {integrity: sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ==} + engines: {node: '>=8'} + + astring@1.8.3: + resolution: {integrity: sha512-sRpyiNrx2dEYIMmUXprS8nlpRg2Drs8m9ElX9vVEXaCB4XEAJhKfs7IcX0IwShjuOAjLR6wzIrgoptz1n19i1A==} + hasBin: true + + async-hook-jl@1.7.6: + resolution: {integrity: sha512-gFaHkFfSxTjvoxDMYqDuGHlcRyUuamF8s+ZTtJdDzqjws4mCt7v0vuV79/E2Wr2/riMQgtG4/yUtXWs1gZ7JMg==} + engines: {node: ^4.7 || >=6.9 || >=7.3} + + async-listener@0.6.10: + resolution: {integrity: sha512-gpuo6xOyF4D5DE5WvyqZdPA3NGhiT6Qf07l7DCB0wwDEsLvDIbCr6j9S5aj5Ch96dLace5tXVzWBZkxU/c5ohw==} + engines: {node: <=0.11.8 || >0.11.10} + + async-retry@1.3.3: + resolution: {integrity: sha512-wfr/jstw9xNi/0teMHrRW7dsz3Lt5ARhYNZ2ewpadnhaIp5mbALhOAP+EAdsC7t4Z6wqsDVv9+W6gm1Dk9mEyw==} + + asynckit@0.4.0: + resolution: {integrity: sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==} + + attr-accept@2.2.2: + resolution: {integrity: sha512-7prDjvt9HmqiZ0cl5CRjtS84sEyhsHP2coDkaZKRKVfCDo9s7iw7ChVmar78Gu9pC4SoR/28wFu/G5JJhTnqEg==} + engines: {node: '>=4'} + + available-typed-arrays@1.0.7: + resolution: {integrity: sha512-wvUjBtSGN7+7SjNpq/9M2Tg350UZD3q62IFZLbRAR1bSMlCo1ZaeW+BJ+D090e4hIIZLBcTDWe4Mh4jvUDajzQ==} + engines: {node: '>= 0.4'} + + axe-core@4.7.0: + resolution: {integrity: sha512-M0JtH+hlOL5pLQwHOLNYZaXuhqmvS8oExsqB1SBYgA4Dk7u/xx+YdGHXaK5pyUfed5mYXdlYiphWq3G8cRi5JQ==} + engines: {node: '>=4'} + + axios@1.6.7: + resolution: {integrity: sha512-/hDJGff6/c7u0hDkvkGxR/oy6CbCs8ziCsC7SqmhjfozqiJGc8Z11wrv9z9lYfY4K8l+H9TpjcMDX0xOZmx+RA==} + + axobject-query@3.2.1: + resolution: {integrity: sha512-jsyHu61e6N4Vbz/v18DHwWYKK0bSWLqn47eeDSKPB7m8tqMHF9YJ+mhIk2lVteyZrY8tnSj/jHOv4YiTCuCJgg==} + + b4a@1.6.4: + resolution: {integrity: sha512-fpWrvyVHEKyeEvbKZTVOeZF3VSKKWtJxFIxX/jaVPf+cLbGUSitjb49pHLqPV2BUNNZ0LcoeEGfE/YCpyDYHIw==} + + babel-jest@29.7.0: + resolution: {integrity: sha512-BrvGY3xZSwEcCzKvKsCi2GgHqDqsYkOP4/by5xCgIwGXQxIEh+8ew3gmrE1y7XRR6LHZIj6yLYnUi/mm2KXKBg==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + peerDependencies: + '@babel/core': ^7.8.0 + + babel-plugin-apply-mdx-type-prop@1.6.22: + resolution: {integrity: sha512-VefL+8o+F/DfK24lPZMtJctrCVOfgbqLAGZSkxwhazQv4VxPg3Za/i40fu22KR2m8eEda+IfSOlPLUSIiLcnCQ==} + peerDependencies: + '@babel/core': ^7.11.6 + + babel-plugin-extract-import-names@1.6.22: + resolution: {integrity: sha512-yJ9BsJaISua7d8zNT7oRG1ZLBJCIdZ4PZqmH8qa9N5AK01ifk3fnkc98AXhtzE7UkfCsEumvoQWgoYLhOnJ7jQ==} + + babel-plugin-istanbul@6.1.1: + resolution: {integrity: sha512-Y1IQok9821cC9onCx5otgFfRm7Lm+I+wwxOx738M/WLPZ9Q42m4IG5W0FNX8WLL2gYMZo3JkuXIH2DOpWM+qwA==} + engines: {node: '>=8'} + + babel-plugin-jest-hoist@29.6.3: + resolution: {integrity: sha512-ESAc/RJvGTFEzRwOTT4+lNDk/GNHMkKbNzsvT0qKRfDyyYTskxB5rnU2njIDYVxXCBHHEI1c0YwHob3WaYujOg==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + babel-preset-current-node-syntax@1.0.1: + resolution: {integrity: sha512-M7LQ0bxarkxQoN+vz5aJPsLBn77n8QgTFmo8WK0/44auK2xlCXrYcUxHFxgU7qW5Yzw/CjmLRK2uJzaCd7LvqQ==} + peerDependencies: + '@babel/core': ^7.0.0 + + babel-preset-jest@29.6.3: + resolution: {integrity: sha512-0B3bhxR6snWXJZtR/RliHTDPRgn1sNHOR0yVtq/IiQFyuOVjFS+wuio/R4gSNkyYmKmJB4wGZv2NZanmKmTnNA==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + peerDependencies: + '@babel/core': ^7.0.0 + + bail@1.0.5: + resolution: {integrity: sha512-xFbRxM1tahm08yHBP16MMjVUAvDaBMD38zsM9EMAUN61omwLmKlOpB/Zku5QkjZ8TZ4vn53pj+t518cH0S03RQ==} + + bail@2.0.2: + resolution: {integrity: sha512-0xO6mYd7JB2YesxDKplafRpsiOzPt9V02ddPCLbY1xYGPOX24NTyN50qnUxgCPcSoYMhKpAuBTjQoRZCAkUDRw==} + + balanced-match@1.0.2: + resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==} + + balanced-match@2.0.0: + resolution: {integrity: sha512-1ugUSr8BHXRnK23KfuYS+gVMC3LB8QGH9W1iGtDPsNWoQbgtXSExkBu2aDR4epiGWZOjZsj6lDl/N/AqqTC3UA==} + + bare-events@2.2.2: + resolution: {integrity: sha512-h7z00dWdG0PYOQEvChhOSWvOfkIKsdZGkWr083FgN/HyoQuebSew/cgirYqh9SCuy/hRvxc5Vy6Fw8xAmYHLkQ==} + + bare-fs@2.2.3: + resolution: {integrity: sha512-amG72llr9pstfXOBOHve1WjiuKKAMnebcmMbPWDZ7BCevAoJLpugjuAPRsDINEyjT0a6tbaVx3DctkXIRbLuJw==} + + bare-os@2.2.1: + resolution: {integrity: sha512-OwPyHgBBMkhC29Hl3O4/YfxW9n7mdTr2+SsO29XBWKKJsbgj3mnorDB80r5TiCQgQstgE5ga1qNYrpes6NvX2w==} + + bare-path@2.1.1: + resolution: {integrity: sha512-OHM+iwRDRMDBsSW7kl3dO62JyHdBKO3B25FB9vNQBPcGHMo4+eA8Yj41Lfbk3pS/seDY+siNge0LdRTulAau/A==} + + base-x@3.0.9: + resolution: {integrity: sha512-H7JU6iBHTal1gp56aKoaa//YUxEaAOUiydvrV/pILqIHXTtqxSkATOnDA2u+jZ/61sD+L/412+7kzXRtWukhpQ==} + + base64-js@1.5.1: + resolution: {integrity: sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==} + + basic-ftp@5.0.3: + resolution: {integrity: sha512-QHX8HLlncOLpy54mh+k/sWIFd0ThmRqwe9ZjELybGZK+tZ8rUb9VO0saKJUROTbE+KhzDUT7xziGpGrW8Kmd+g==} + engines: {node: '>=10.0.0'} + + better-path-resolve@1.0.0: + resolution: {integrity: sha512-pbnl5XzGBdrFU/wT4jqmJVPn2B6UHPBOhzMQkY/SPUPB6QtUXtmBHBIwCbXJol93mOpGMnQyP/+BB19q04xj7g==} + engines: {node: '>=4'} + + bignumber.js@9.1.2: + resolution: {integrity: sha512-2/mKyZH9K85bzOEfhXDBFZTGd1CTs+5IHpeFQo9luiBG7hghdC851Pj2WAhb6E3R6b9tZj/XKhbg4fum+Kepug==} + + binary-extensions@2.2.0: + resolution: {integrity: sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==} + engines: {node: '>=8'} + + bl@5.1.0: + resolution: {integrity: sha512-tv1ZJHLfTDnXE6tMHv73YgSJaWR2AFuPwMntBe7XL/GBFHnT0CLnsHMogfk5+GzCDC5ZWarSCYaIGATZt9dNsQ==} + + bluebird@3.7.2: + resolution: {integrity: sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==} + + boolbase@1.0.0: + resolution: {integrity: sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww==} + + boolean@3.1.4: + resolution: {integrity: sha512-3hx0kwU3uzG6ReQ3pnaFQPSktpBw6RHN3/ivDKEuU8g1XSfafowyvDnadjv1xp8IZqhtSukxlwv9bF6FhX8m0w==} + + bowser@2.11.0: + resolution: {integrity: sha512-AlcaJBi/pqqJBIQ8U9Mcpc9i8Aqxn88Skv5d+xBX006BY5u8N3mGLHa5Lgppa7L/HfwgwLgZ6NYs+Ag6uUmJRA==} + + brace-expansion@1.1.11: + resolution: {integrity: sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==} + + brace-expansion@2.0.1: + resolution: {integrity: sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==} + + braces@3.0.2: + resolution: {integrity: sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==} + engines: {node: '>=8'} + + breakword@1.0.5: + resolution: {integrity: sha512-ex5W9DoOQ/LUEU3PMdLs9ua/CYZl1678NUkKOdUSi8Aw5F1idieaiRURCBFJCwVcrD1J8Iy3vfWSloaMwO2qFg==} + + browserslist@4.21.4: + resolution: {integrity: sha512-CBHJJdDmgjl3daYjN5Cp5kbTf1mUhZoS+beLklHIvkOWscs83YAhLlF3Wsh/lciQYAcbBJgTOD44VtG31ZM4Hw==} + engines: {node: ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7} + hasBin: true + + browserslist@4.23.0: + resolution: {integrity: sha512-QW8HiM1shhT2GuzkvklfjcKDiWFXHOeFCIA/huJPwHsslwcydgk7X+z2zXpEijP98UCY7HbubZt5J2Zgvf0CaQ==} + engines: {node: ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7} + hasBin: true + + bser@2.1.1: + resolution: {integrity: sha512-gQxTNE/GAfIIrmHLUE3oJyp5FO6HRBfhjnw4/wMmA63ZGDJnWBmgY/lyQBpnDUkGmAhbSe39tx2d/iTOAfglwQ==} + + buffer-crc32@0.2.13: + resolution: {integrity: sha512-VO9Ht/+p3SN7SKWqcrgEzjGbRSJYTx+Q1pTQC0wrWqHx0vpJraQ6GtHx8tvcg1rlK1byhU5gccxgOgj7B0TDkQ==} + + buffer-equal-constant-time@1.0.1: + resolution: {integrity: sha512-zRpUiDwd/xk6ADqPMATG8vc9VPrkck7T07OIx0gnjmJAnHnTVXNQG3vfvWNuiZIkwu9KrKdA1iJKfsfTVxE6NA==} + + buffer-from@1.1.2: + resolution: {integrity: sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==} + + buffer-writer@2.0.0: + resolution: {integrity: sha512-a7ZpuTZU1TRtnwyCNW3I5dc0wWNC3VR9S++Ewyk2HHZdrO3CQJqSpd+95Us590V6AL7JqUAH2IwZ/398PmNFgw==} + engines: {node: '>=4'} + + buffer@5.7.1: + resolution: {integrity: sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==} + + buffer@6.0.3: + resolution: {integrity: sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==} + + builtin-modules@3.3.0: + resolution: {integrity: sha512-zhaCDicdLuWN5UbN5IMnFqNMhNfo919sH85y2/ea+5Yg9TsTkeZxpL+JLbp6cgYFS4sRLp3YV4S6yDuqVWHYOw==} + engines: {node: '>=6'} + + bytes@3.1.1: + resolution: {integrity: sha512-dWe4nWO/ruEOY7HkUJ5gFt1DCFV9zPRoJr8pV0/ASQermOZjtq8jMjOprC0Kd10GLN+l7xaUPvxzJFWtxGu8Fg==} + engines: {node: '>= 0.8'} + + bytes@3.1.2: + resolution: {integrity: sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==} + engines: {node: '>= 0.8'} + + cac@6.7.14: + resolution: {integrity: sha512-b6Ilus+c3RrdDk+JhLKUAQfzzgLEPy6wcXqS7f/xe1EETvsDP6GORG7SFuOs6cID5YkqchW/LXZbX5bc8j7ZcQ==} + engines: {node: '>=8'} + + cache-content-type@1.0.1: + resolution: {integrity: sha512-IKufZ1o4Ut42YUrZSo8+qnMTrFuKkvyoLXUywKz9GJ5BrhOFGhLdkx9sG4KAnVvbY6kEcSFjLQul+DVmBm2bgA==} + engines: {node: '>= 6.0.0'} + + cacheable-lookup@7.0.0: + resolution: {integrity: sha512-+qJyx4xiKra8mZrcwhjMRMUhD5NR1R8esPkzIYxX96JiecFoxAXFuz/GpR3+ev4PE1WamHip78wV0vcmPQtp8w==} + engines: {node: '>=14.16'} + + cacheable-request@10.2.14: + resolution: {integrity: sha512-zkDT5WAF4hSSoUgyfg5tFIxz8XQK+25W/TLVojJTMKBaxevLBBtLxgqguAuVQB8PVW79FVjHcU+GJ9tVbDZ9mQ==} + engines: {node: '>=14.16'} + + call-bind@1.0.7: + resolution: {integrity: sha512-GHTSNSYICQ7scH7sZ+M2rFopRoLh8t2bLSW6BbgrtLsahOIB5iyAVJf9GjWK3cYTDaMj4XdBpM1cA6pIS0Kv2w==} + engines: {node: '>= 0.4'} + + call-me-maybe@1.0.2: + resolution: {integrity: sha512-HpX65o1Hnr9HH25ojC1YGs7HCQLq0GCOibSaWER0eNpgJ/Z1MZv2mTc7+xh6WOPxbRVcmgbv4hGU+uSQ/2xFZQ==} + + callsites@3.1.0: + resolution: {integrity: sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==} + engines: {node: '>=6'} + + camelcase-css@2.0.1: + resolution: {integrity: sha512-QOSvevhslijgYwRx6Rv7zKdMF8lbRmx+uQGx2+vDc+KI/eBnsy9kit5aj23AgGu3pa4t9AgwbnXWqS+iOY+2aA==} + engines: {node: '>= 6'} + + camelcase-keys@6.2.2: + resolution: {integrity: sha512-YrwaA0vEKazPBkn0ipTiMpSajYDSe+KjQfrjhcBMxJt/znbvlHd8Pw/Vamaz5EB4Wfhs3SUR3Z9mwRu/P3s3Yg==} + engines: {node: '>=8'} + + camelcase-keys@7.0.2: + resolution: {integrity: sha512-Rjs1H+A9R+Ig+4E/9oyB66UC5Mj9Xq3N//vcLf2WzgdTi/3gUu3Z9KoqmlrEG4VuuLK8wJHofxzdQXz/knhiYg==} + engines: {node: '>=12'} + + camelcase-keys@9.0.0: + resolution: {integrity: sha512-GdZ92DNXdcfFB/5Kq4O82EL6UW5neiRBhfNP5M3mGw7CX2sPDbVA04ZPLsqbp7oMi2l3m2I0AZ/kFP5Nk5kopA==} + engines: {node: '>=16'} + + camelcase@5.3.1: + resolution: {integrity: sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==} + engines: {node: '>=6'} + + camelcase@6.3.0: + resolution: {integrity: sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==} + engines: {node: '>=10'} + + camelcase@8.0.0: + resolution: {integrity: sha512-8WB3Jcas3swSvjIeA2yvCJ+Miyz5l1ZmB6HFb9R1317dt9LCQoswg/BGrmAmkWVEszSrrg4RwmO46qIm2OEnSA==} + engines: {node: '>=16'} + + caniuse-lite@1.0.30001561: + resolution: {integrity: sha512-NTt0DNoKe958Q0BE0j0c1V9jbUzhBxHIEJy7asmGrpE0yG63KTV7PLHPnK2E1O9RsQrQ081I3NLuXGS6zht3cw==} + + caniuse-lite@1.0.30001610: + resolution: {integrity: sha512-QFutAY4NgaelojVMjY63o6XlZyORPaLfyMnsl3HgnWdJUcX6K0oaJymHjH8PT5Gk7sTm8rvC/c5COUQKXqmOMA==} + + cbor-extract@2.2.0: + resolution: {integrity: sha512-Ig1zM66BjLfTXpNgKpvBePq271BPOvu8MR0Jl080yG7Jsl+wAZunfrwiwA+9ruzm/WEdIV5QF/bjDZTqyAIVHA==} + hasBin: true + + cbor-x@1.5.4: + resolution: {integrity: sha512-PVKILDn+Rf6MRhhcyzGXi5eizn1i0i3F8Fe6UMMxXBnWkalq9+C5+VTmlIjAYM4iF2IYF2N+zToqAfYOp+3rfw==} + + ccount@1.1.0: + resolution: {integrity: sha512-vlNK021QdI7PNeiUh/lKkC/mNHHfV0m/Ad5JoI0TYtlBnJAslM/JIkm/tGC88bkLIwO6OQ5uV6ztS6kVAtCDlg==} + + ccount@2.0.1: + resolution: {integrity: sha512-eyrF0jiFpY+3drT6383f1qhkbGsLSifNAjA61IUjZjmLCWjItY6LB9ft9YhoDgwfmclB2zhu51Lc7+95b8NRAg==} + + chai@4.4.1: + resolution: {integrity: sha512-13sOfMv2+DWduEU+/xbun3LScLoqN17nBeTLUsmDfKdoiC1fr0n9PU4guu4AhRcOVFk/sW8LyZWHuhWtQZiF+g==} + engines: {node: '>=4'} + + chalk@2.4.2: + resolution: {integrity: sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==} + engines: {node: '>=4'} + + chalk@4.1.2: + resolution: {integrity: sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==} + engines: {node: '>=10'} + + chalk@5.1.2: + resolution: {integrity: sha512-E5CkT4jWURs1Vy5qGJye+XwCkNj7Od3Af7CP6SujMetSMkLs8Do2RWJK5yx1wamHV/op8Rz+9rltjaTQWDnEFQ==} + engines: {node: ^12.17.0 || ^14.13 || >=16.0.0} + + chalk@5.3.0: + resolution: {integrity: sha512-dLitG79d+GV1Nb/VYcCDFivJeK1hiukt9QjRNVOsUtTy1rR1YJsmpGGTZ3qJos+uw7WmWF4wUwBd9jxjocFC2w==} + engines: {node: ^12.17.0 || ^14.13 || >=16.0.0} + + char-regex@1.0.2: + resolution: {integrity: sha512-kWWXztvZ5SBQV+eRgKFeh8q5sLuZY2+8WUIzlxWVTg+oGwY14qylx1KbKzHd8P6ZYkAg0xyIDU9JMHhyJMZ1jw==} + engines: {node: '>=10'} + + character-entities-legacy@1.1.4: + resolution: {integrity: sha512-3Xnr+7ZFS1uxeiUDvV02wQ+QDbc55o97tIV5zHScSPJpcLm/r0DFPcoY3tYRp+VZukxuMeKgXYmsXQHO05zQeA==} + + character-entities@1.2.4: + resolution: {integrity: sha512-iBMyeEHxfVnIakwOuDXpVkc54HijNgCyQB2w0VfGQThle6NXn50zU6V/u+LDhxHcDUPojn6Kpga3PTAD8W1bQw==} + + character-entities@2.0.1: + resolution: {integrity: sha512-OzmutCf2Kmc+6DrFrrPS8/tDh2+DpnrfzdICHWhcVC9eOd0N1PXmQEE1a8iM4IziIAG+8tmTq3K+oo0ubH6RRQ==} + + character-reference-invalid@1.1.4: + resolution: {integrity: sha512-mKKUkUbhPpQlCOfIuZkvSEgktjPFIsZKRRbC6KWVEMvlzblj3i3asQv5ODsrwt0N3pHAEvjP8KTQPHkp0+6jOg==} + + chardet@0.7.0: + resolution: {integrity: sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA==} + + check-error@1.0.3: + resolution: {integrity: sha512-iKEoDYaRmd1mxM90a2OEfWhjsjPpYPuQ+lMYsoxB126+t8fw7ySEO48nmDg5COTjxDI65/Y2OWpeEHk3ZOe8zg==} + + chokidar@3.5.3: + resolution: {integrity: sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==} + engines: {node: '>= 8.10.0'} + + chownr@3.0.0: + resolution: {integrity: sha512-+IxzY9BZOQd/XuYPRmrvEVjF/nqj5kgT4kEq7VofrDoM1MxoRjEWkrCC3EtLi59TVawxTAn+orJwFQcrqEN1+g==} + engines: {node: '>=18'} + + chrome-trace-event@1.0.3: + resolution: {integrity: sha512-p3KULyQg4S7NIHixdwbGX+nFHkoBiA4YQmyWtjb8XngSKV124nJmRysgAeujbUVb15vh+RvFUfCPqU7rXk+hZg==} + engines: {node: '>=6.0'} + + chromium-bidi@0.5.17: + resolution: {integrity: sha512-BqOuIWUgTPj8ayuBFJUYCCuwIcwjBsb3/614P7tt1bEPJ4i1M0kCdIl0Wi9xhtswBXnfO2bTpTMkHD71H8rJMg==} + peerDependencies: + devtools-protocol: '*' + + ci-info@3.8.0: + resolution: {integrity: sha512-eXTggHWSooYhq49F2opQhuHWgzucfF2YgODK4e1566GQs5BIfP30B0oenwBJHfWxAs2fyPB1s7Mg949zLf61Yw==} + engines: {node: '>=8'} + + ci-info@4.0.0: + resolution: {integrity: sha512-TdHqgGf9odd8SXNuxtUBVx8Nv+qZOejE6qyqiy5NtbYYQOeFa6zmHkxlPzmaLxWWHsU6nJmB7AETdVPi+2NBUg==} + engines: {node: '>=8'} + + cjs-module-lexer@1.2.2: + resolution: {integrity: sha512-cOU9usZw8/dXIXKtwa8pM0OTJQuJkxMN6w30csNRUerHfeQ5R6U3kkU/FtJeIf3M202OHfY2U8ccInBG7/xogA==} + + classnames@2.3.1: + resolution: {integrity: sha512-OlQdbZ7gLfGarSqxesMesDa5uz7KFbID8Kpq/SxIoNGDqY8lSYs0D+hhtBXhcdB3rcbXArFr7vlHheLk1voeNA==} + + clean-deep@3.4.0: + resolution: {integrity: sha512-Lo78NV5ItJL/jl+B5w0BycAisaieJGXK1qYi/9m4SjR8zbqmrUtO7Yhro40wEShGmmxs/aJLI/A+jNhdkXK8mw==} + engines: {node: '>=4'} + + clean-regexp@1.0.0: + resolution: {integrity: sha512-GfisEZEJvzKrmGWkvfhgzcz/BllN1USeqD2V6tg14OAOgaCD2Z/PUEuxnAZ/nPvmaHRG7a8y77p1T/IRQ4D1Hw==} + engines: {node: '>=4'} + + cli-cursor@4.0.0: + resolution: {integrity: sha512-VGtlMu3x/4DOtIUwEkRezxUZ2lBacNJCHash0N0WeZDBS+7Ux1dm3XWAgWYxLJFMMdOeXMHXorshEFhbMSGelg==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + + cli-spinners@2.7.0: + resolution: {integrity: sha512-qu3pN8Y3qHNgE2AFweciB1IfMnmZ/fsNTEE+NOFjmGB2F/7rLhnhzppvpCnN4FovtP26k8lHyy9ptEbNwWFLzw==} + engines: {node: '>=6'} + + cli-spinners@2.9.2: + resolution: {integrity: sha512-ywqV+5MmyL4E7ybXgKys4DugZbX0FC6LnwrhjuykIjnK9k8OQacQ7axGKnjDXWNhns0xot3bZI5h55H8yo9cJg==} + engines: {node: '>=6'} + + cli-truncate@3.1.0: + resolution: {integrity: sha512-wfOBkjXteqSnI59oPcJkcPl/ZmwvMMOj340qUIY1SKZCv0B9Cf4D4fAucRkIKQmsIuYK3x1rrgU7MeGRruiuiA==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + + cli-width@4.0.0: + resolution: {integrity: sha512-ZksGS2xpa/bYkNzN3BAw1wEjsLV/ZKOf/CCrJ/QOBsxx6fOARIkwTutxp1XIOIohi6HKmOFjMoK/XaqDVUpEEw==} + engines: {node: '>= 12'} + + cliui@6.0.0: + resolution: {integrity: sha512-t6wbgtoCXvAzst7QgXxJYqPt0usEfbgQdftEPbLL/cvv6HPE5VgvqCuAIDR0NgU52ds6rFwqrgakNLrHEjCbrQ==} + + cliui@8.0.1: + resolution: {integrity: sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==} + engines: {node: '>=12'} + + clone@1.0.4: + resolution: {integrity: sha512-JQHZ2QMW6l3aH/j6xCqQThY/9OH4D/9ls34cgkUBiEeocRTU04tHfKPBsUK1PqZCUQM7GiA0IIXJSuXHI64Kbg==} + engines: {node: '>=0.8'} + + clone@2.1.2: + resolution: {integrity: sha512-3Pe/CF1Nn94hyhIYpjtiLhdCoEoz0DqQ+988E9gmeEdQZlojxnOb74wctFyuwWQHzqyf9X7C7MG8juUpqBJT8w==} + engines: {node: '>=0.8'} + + cls-hooked@4.2.2: + resolution: {integrity: sha512-J4Xj5f5wq/4jAvcdgoGsL3G103BtWpZrMo8NEinRltN+xpTZdI+M38pyQqhuFU/P792xkMFvnKSf+Lm81U1bxw==} + engines: {node: ^4.7 || >=6.9 || >=7.3 || >=8.2.1} + + cluster-key-slot@1.1.2: + resolution: {integrity: sha512-RMr0FhtfXemyinomL4hrWcYJxmX6deFdCxpJzhDttxgO1+bcCnkk+9drydLVDmAMG7NE6aN/fl4F7ucU/90gAA==} + engines: {node: '>=0.10.0'} + + co-body@6.1.0: + resolution: {integrity: sha512-m7pOT6CdLN7FuXUcpuz/8lfQ/L77x8SchHCF4G0RBTJO20Wzmhn5Sp4/5WsKy8OSpifBSUrmg83qEqaDHdyFuQ==} + + co@4.6.0: + resolution: {integrity: sha512-QVb0dM5HvG+uaxitm8wONl7jltx8dqhfU33DcqtOZcLSVIKSDDLDi7+0LbAKiyI8hD9u42m2YxXSkMGWThaecQ==} + engines: {iojs: '>= 1.0.0', node: '>= 0.12.0'} + + collapse-white-space@1.0.6: + resolution: {integrity: sha512-jEovNnrhMuqyCcjfEJA56v0Xq8SkIoPKDyaHahwo3POf4qcSXqMYuwNcOTzp74vTsR9Tn08z4MxWqAhcekogkQ==} + + collect-v8-coverage@1.0.1: + resolution: {integrity: sha512-iBPtljfCNcTKNAto0KEtDfZ3qzjJvqE3aTGZsbhjSBlorqpXJlaWWtPO35D+ZImoC3KWejX64o+yPGxhWSTzfg==} + + color-convert@1.9.3: + resolution: {integrity: sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==} + + color-convert@2.0.1: + resolution: {integrity: sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==} + engines: {node: '>=7.0.0'} + + color-name@1.1.3: + resolution: {integrity: sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==} + + color-name@1.1.4: + resolution: {integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==} + + color-string@1.9.1: + resolution: {integrity: sha512-shrVawQFojnZv6xM40anx4CkoDP+fZsw/ZerEMsW/pyzsRbElpsL/DBVW7q3ExxwusdNXI3lXpuhEZkzs8p5Eg==} + + color@4.2.3: + resolution: {integrity: sha512-1rXeuUUiGGrykh+CeBdu5Ie7OJwinCgQY0bc7GCRxy5xVHy+moaqkpL/jqQq0MtQOeYcrqEz4abc5f0KtU7W4A==} + engines: {node: '>=12.5.0'} + + colord@2.9.3: + resolution: {integrity: sha512-jeC1axXpnb0/2nn/Y1LPuLdgXBLH7aDcHu4KEKfqw3CUhX7ZpfBSlPKyqXE6btIgEzfWtrX3/tyBCaCvXvMkOw==} + + colorette@2.0.20: + resolution: {integrity: sha512-IfEDxwoWIjkeXL1eXcDiow4UbKjhLdq6/EuSVR9GMN7KVH3r9gQ83e73hsz1Nd1T3ijd5xv1wcWRYO+D6kCI2w==} + + combined-stream@1.0.8: + resolution: {integrity: sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==} + engines: {node: '>= 0.8'} + + comma-separated-tokens@1.0.8: + resolution: {integrity: sha512-GHuDRO12Sypu2cV70d1dkA2EUmXHgntrzbpvOB+Qy+49ypNfGgFQIC2fhhXbnyrJRynDCAARsT7Ou0M6hirpfw==} + + comma-separated-tokens@2.0.2: + resolution: {integrity: sha512-G5yTt3KQN4Yn7Yk4ed73hlZ1evrFKXeUW3086p3PRFNp7m2vIjI6Pg+Kgb+oyzhd9F2qdcoj67+y3SdxL5XWsg==} + + commander@11.1.0: + resolution: {integrity: sha512-yPVavfyCcRhmorC7rWlkHn15b4wDVgVmBA7kV4QVBsF7kv/9TKJAbAXVTxvTnwP8HHKjRCJDClKbciiYS7p0DQ==} + engines: {node: '>=16'} + + commander@5.1.0: + resolution: {integrity: sha512-P0CysNDQ7rtVw4QIQtm+MRxV66vKFSvlsQvGYXZWR3qFU0jlMKHZZZgw8e+8DSah4UDKMqnknRDQz+xuQXQ/Zg==} + engines: {node: '>= 6'} + + commander@7.2.0: + resolution: {integrity: sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw==} + engines: {node: '>= 10'} + + commondir@1.0.1: + resolution: {integrity: sha512-W9pAhw0ja1Edb5GVdIF1mjZw/ASI0AlShXM83UUGe2DVr5TdAPEA1OA8m/g8zWp9x6On7gqufY+FatDbC3MDQg==} + + compare-func@2.0.0: + resolution: {integrity: sha512-zHig5N+tPWARooBnb0Zx1MFcdfpyJrfTJ3Y5L+IFvUm8rM74hHz66z0gw0x4tijh5CorKkKUCnW82R2vmpeCRA==} + + component-emitter@1.3.0: + resolution: {integrity: sha512-Rd3se6QB+sO1TwqZjscQrurpEPIfO0/yYnSin6Q/rD3mOutHvUrCAhJub3r90uNb+SESBuE0QYoB90YdfatsRg==} + + compressible@2.0.18: + resolution: {integrity: sha512-AF3r7P5dWxL8MxyITRMlORQNaOA2IkAFaTr4k7BUumjPtRpGDTZpl0Pb1XCO6JeDCBdp126Cgs9sMxqSjgYyRg==} + engines: {node: '>= 0.6'} + + concat-map@0.0.1: + resolution: {integrity: sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==} + + confusing-browser-globals@1.0.11: + resolution: {integrity: sha512-JsPKdmh8ZkmnHxDk55FZ1TqVLvEQTvoByJZRN9jzI0UjxK/QgAmsphz7PGtqgPieQZ/CQcHWXCR7ATDNhGe+YA==} + + content-disposition@0.5.4: + resolution: {integrity: sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ==} + engines: {node: '>= 0.6'} + + content-type@1.0.4: + resolution: {integrity: sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA==} + engines: {node: '>= 0.6'} + + content-type@1.0.5: + resolution: {integrity: sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==} + engines: {node: '>= 0.6'} + + continuation-local-storage@3.2.1: + resolution: {integrity: sha512-jx44cconVqkCEEyLSKWwkvUXwO561jXMa3LPjTPsm5QR22PA0/mhe33FT4Xb5y74JDvt/Cq+5lm8S8rskLv9ZA==} + + conventional-changelog-angular@7.0.0: + resolution: {integrity: sha512-ROjNchA9LgfNMTTFSIWPzebCwOGFdgkEq45EnvvrmSLvCtAw0HSmrCs7/ty+wAeYUZyNay0YMUNYFTRL72PkBQ==} + engines: {node: '>=16'} + + conventional-changelog-conventionalcommits@7.0.2: + resolution: {integrity: sha512-NKXYmMR/Hr1DevQegFB4MwfM5Vv0m4UIxKZTTYuD98lpTknaZlSRrDOG4X7wIXpGkfsYxZTghUN+Qq+T0YQI7w==} + engines: {node: '>=16'} + + conventional-commits-parser@5.0.0: + resolution: {integrity: sha512-ZPMl0ZJbw74iS9LuX9YIAiW8pfM5p3yh2o/NbXHbkFuZzY5jvdi5jFycEOkmBW5H5I7nA+D6f3UcsCLP2vvSEA==} + engines: {node: '>=16'} + hasBin: true + + convert-source-map@1.9.0: + resolution: {integrity: sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A==} + + convert-source-map@2.0.0: + resolution: {integrity: sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==} + + cookiejar@2.1.4: + resolution: {integrity: sha512-LDx6oHrK+PhzLKJU9j5S7/Y3jM/mUHvD/DeI1WQmJn652iPC5Y4TBzC9l+5OMOXlyTTA+SmVUPm0HQUwpD5Jqw==} + + cookies@0.8.0: + resolution: {integrity: sha512-8aPsApQfebXnuI+537McwYsDtjVxGm8gTIzQI3FDW6t5t/DAhERxtnbEPN/8RX+uZthoz4eCOgloXaE5cYyNow==} + engines: {node: '>= 0.8'} + + cookies@0.9.1: + resolution: {integrity: sha512-TG2hpqe4ELx54QER/S3HQ9SRVnQnGBtKUz5bLQWtYAQ+o6GpgMs6sYUvaiJjVxb+UXwhRhAEP3m7LbsIZ77Hmw==} + engines: {node: '>= 0.8'} + + core-js-compat@3.37.0: + resolution: {integrity: sha512-vYq4L+T8aS5UuFg4UwDhc7YNRWVeVZwltad9C/jV3R2LgVOpS9BDr7l/WL6BN0dbV3k1XejPTHqqEzJgsa0frA==} + + core-js@3.34.0: + resolution: {integrity: sha512-aDdvlDder8QmY91H88GzNi9EtQi2TjvQhpCX6B1v/dAZHU1AuLgHvRh54RiOerpEhEW46Tkf+vgAViB/CWC0ag==} + + cosmiconfig-typescript-loader@5.0.0: + resolution: {integrity: sha512-+8cK7jRAReYkMwMiG+bxhcNKiHJDM6bR9FD/nGBXOWdMLuYawjF5cGrtLilJ+LGd3ZjCXnJjR5DkfWPoIVlqJA==} + engines: {node: '>=v16'} + peerDependencies: + '@types/node': '*' + cosmiconfig: '>=8.2' + typescript: '>=4' + + cosmiconfig@7.1.0: + resolution: {integrity: sha512-AdmX6xUzdNASswsFtmwSt7Vj8po9IuqXm0UXz7QKPuEUmPB4XyjGfaAr2PSuELMwkRMVH1EpIkX5bTZGRB3eCA==} + engines: {node: '>=10'} + + cosmiconfig@8.3.6: + resolution: {integrity: sha512-kcZ6+W5QzcJ3P1Mt+83OUv/oHFqZHIx8DuxG6eZ5RGMERoLqp4BuGjhHLYGK+Kf5XVkQvqBSmAy/nGWN3qDgEA==} + engines: {node: '>=14'} + peerDependencies: + typescript: '>=4.9.5' + peerDependenciesMeta: + typescript: + optional: true + + cosmiconfig@9.0.0: + resolution: {integrity: sha512-itvL5h8RETACmOTFc4UfIyB2RfEHi71Ax6E/PivVxq9NseKbOWpeyHEOIbmAw1rs8Ak0VursQNww7lf7YtUwzg==} + engines: {node: '>=14'} + peerDependencies: + typescript: '>=4.9.5' + peerDependenciesMeta: + typescript: + optional: true + + create-eslint-index@1.0.0: + resolution: {integrity: sha512-nXvJjnfDytOOaPOonX0h0a1ggMoqrhdekGeZkD6hkcWYvlCWhU719tKFVh8eU04CnMwu3uwe1JjwuUF2C3k2qg==} + engines: {node: '>=4.0.0'} + + create-jest@29.7.0: + resolution: {integrity: sha512-Adz2bdH0Vq3F53KEMJOoftQFutWCukm6J24wbPWRO4k1kMY7gS7ds/uoJkNuV8wDCtWWnuwGcJwpWcih+zEW1Q==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + hasBin: true + + create-require@1.1.1: + resolution: {integrity: sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==} + + cross-env@7.0.3: + resolution: {integrity: sha512-+/HKd6EgcQCJGh2PSjZuUitQBQynKor4wrFbRg4DtAgS1aWO+gU52xpH7M9ScGgXSYmAVS9bIJ8EzuaGw0oNAw==} + engines: {node: '>=10.14', npm: '>=6', yarn: '>=1'} + hasBin: true + + cross-fetch@4.0.0: + resolution: {integrity: sha512-e4a5N8lVvuLgAWgnCrLr2PP0YyDOTHa9H/Rj54dirp61qXnNq46m82bRhNqIA5VccJtWBvPTFRV3TtvHUKPB1g==} + + cross-spawn@5.1.0: + resolution: {integrity: sha512-pTgQJ5KC0d2hcY8eyL1IzlBPYjTkyH72XRZPnLyKus2mBfNjQs3klqbJU2VILqZryAZUt9JOb3h/mWMy23/f5A==} + + cross-spawn@7.0.3: + resolution: {integrity: sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==} + engines: {node: '>= 8'} + + css-functions-list@3.2.1: + resolution: {integrity: sha512-Nj5YcaGgBtuUmn1D7oHqPW0c9iui7xsTsj5lIX8ZgevdfhmjFfKB3r8moHJtNJnctnYXJyYX5I1pp90HM4TPgQ==} + engines: {node: '>=12 || >=16'} + + css-select@4.3.0: + resolution: {integrity: sha512-wPpOYtnsVontu2mODhA19JrqWxNsfdatRKd64kmpRbQgh1KtItko5sTnEpPdpSaJszTOhEMlF/RPz28qj4HqhQ==} + + css-tree@1.1.3: + resolution: {integrity: sha512-tRpdppF7TRazZrjJ6v3stzv93qxRcSsFmW6cX0Zm2NVKpxE1WV1HblnghVv9TreireHkqI/VDEsfolRF1p6y7Q==} + engines: {node: '>=8.0.0'} + + css-tree@2.3.1: + resolution: {integrity: sha512-6Fv1DV/TYw//QF5IzQdqsNDjx/wc8TrMBZsqjL9eW01tWb7R7k/mq+/VXfJCl7SoD5emsJop9cOByJZfs8hYIw==} + engines: {node: ^10 || ^12.20.0 || ^14.13.0 || >=15.0.0} + + css-unit-converter@1.1.2: + resolution: {integrity: sha512-IiJwMC8rdZE0+xiEZHeru6YoONC4rfPMqGm2W85jMIbkFvv5nFTwJVFHam2eFrN6txmoUYFAFXiv8ICVeTO0MA==} + + css-what@6.1.0: + resolution: {integrity: sha512-HTUrgRJ7r4dsZKU6GjmpfRK1O76h97Z8MfS1G0FozR+oF2kG6Vfe8JE6zwrkbxigziPHinCJ+gCPjA9EaBDtRw==} + engines: {node: '>= 6'} + + cssesc@3.0.0: + resolution: {integrity: sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==} + engines: {node: '>=4'} + hasBin: true + + csso@4.2.0: + resolution: {integrity: sha512-wvlcdIbf6pwKEk7vHj8/Bkc0B4ylXZruLvOgs9doS5eOsOpuodOV2zJChSpkp+pRpYQLQMeF04nr3Z68Sta9jA==} + engines: {node: '>=8.0.0'} + + cssom@0.3.8: + resolution: {integrity: sha512-b0tGHbfegbhPJpxpiBPU2sCkigAqtM9O121le6bbOlgyV+NyGyCmVfJ6QW9eRjz8CpNfWEOYBIMIGRYkLwsIYg==} + + cssom@0.5.0: + resolution: {integrity: sha512-iKuQcq+NdHqlAcwUY0o/HL69XQrUaQdMjmStJ8JFmUaiiQErlhrmuigkg/CU4E2J0IyUKUrMAgl36TvN67MqTw==} + + cssstyle@2.3.0: + resolution: {integrity: sha512-AZL67abkUzIuvcHqk7c09cezpGNcxUxU4Ioi/05xHk4DQeTkWmGYftIE6ctU6AEt+Gn4n1lDStOtj7FKycP71A==} + engines: {node: '>=8'} + + csstype@3.0.11: + resolution: {integrity: sha512-sa6P2wJ+CAbgyy4KFssIb/JNMLxFvKF1pCYCSXS8ZMuqZnMsrxqI2E5sPyoTpxoPU/gVZMzr2zjOfg8GIZOMsw==} + + csv-generate@3.4.3: + resolution: {integrity: sha512-w/T+rqR0vwvHqWs/1ZyMDWtHHSJaN06klRqJXBEpDJaM/+dZkso0OKh1VcuuYvK3XM53KysVNq8Ko/epCK8wOw==} + + csv-parse@4.16.3: + resolution: {integrity: sha512-cO1I/zmz4w2dcKHVvpCr7JVRu8/FymG5OEpmvsZYlccYolPBLoVGKUHgNoc4ZGkFeFlWGEDmMyBM+TTqRdW/wg==} + + csv-stringify@5.6.5: + resolution: {integrity: sha512-PjiQ659aQ+fUTQqSrd1XEDnOr52jh30RBurfzkscaE2tPaFsDH5wOAHJiw8XAHphRknCwMUE9KRayc4K/NbO8A==} + + csv@5.5.3: + resolution: {integrity: sha512-QTaY0XjjhTQOdguARF0lGKm5/mEq9PD9/VhZZegHDIBq2tQwgNpHc3dneD4mGo2iJs+fTKv5Bp0fZ+BRuY3Z0g==} + engines: {node: '>= 0.1.90'} + + cwd@0.10.0: + resolution: {integrity: sha512-YGZxdTTL9lmLkCUTpg4j0zQ7IhRB5ZmqNBbGCl3Tg6MP/d5/6sY7L5mmTjzbc6JKgVZYiqTQTNhPFsbXNGlRaA==} + engines: {node: '>=0.8'} + + d3-array@2.12.1: + resolution: {integrity: sha512-B0ErZK/66mHtEsR1TkPEEkwdy+WDesimkM5gpZr5Dsg54BiTA5RXtYW5qTLIAcekaS9xfZrzBLF/OAkB3Qn1YQ==} + + d3-color@2.0.0: + resolution: {integrity: sha512-SPXi0TSKPD4g9tw0NMZFnR95XVgUZiBH+uUTqQuDu1OsE2zomHU7ho0FISciaPvosimixwHFl3WHLGabv6dDgQ==} + + d3-format@2.0.0: + resolution: {integrity: sha512-Ab3S6XuE/Q+flY96HXT0jOXcM4EAClYFnRGY5zsjRGNy6qCYrQsMffs7cV5Q9xejb35zxW5hf/guKw34kvIKsA==} + + d3-interpolate@3.0.1: + resolution: {integrity: sha512-3bYs1rOD33uo8aqJfKP3JWPAibgw8Zm2+L9vBKEHJ2Rg+viTR7o5Mmv5mZcieN+FRYaAOWX5SJATX6k1PWz72g==} + engines: {node: '>=12'} + + d3-path@2.0.0: + resolution: {integrity: sha512-ZwZQxKhBnv9yHaiWd6ZU4x5BtCQ7pXszEV9CU6kRgwIQVQGLMv1oiL4M+MK/n79sYzsj+gcgpPQSctJUsLN7fA==} + + d3-scale@4.0.2: + resolution: {integrity: sha512-GZW464g1SH7ag3Y7hXjf8RoUuAFIqklOAq3MRl4OaWabTFJY9PN/E1YklhXLh+OQ3fM9yS2nOkCoS+WLZ6kvxQ==} + engines: {node: '>=12'} + + d3-shape@3.1.0: + resolution: {integrity: sha512-tGDh1Muf8kWjEDT/LswZJ8WF85yDZLvVJpYU9Nq+8+yW1Z5enxrmXOhTArlkaElU+CTn0OTVNli+/i+HP45QEQ==} + engines: {node: '>=12'} + + d3-time-format@3.0.0: + resolution: {integrity: sha512-UXJh6EKsHBTjopVqZBhFysQcoXSv/5yLONZvkQ5Kk3qbwiUYkdX17Xa1PT6U1ZWXGGfB1ey5L8dKMlFq2DO0Ag==} + + d3-time@2.1.1: + resolution: {integrity: sha512-/eIQe/eR4kCQwq7yxi7z4c6qEXf2IYGcjoWB5OOQy4Tq9Uv39/947qlDcN2TLkiTzQWzvnsuYPB9TrWaNfipKQ==} + + damerau-levenshtein@1.0.8: + resolution: {integrity: sha512-sdQSFB7+llfUcQHUQO3+B8ERRj0Oa4w9POWMI/puGtuf7gFywGmkaLCElnudfTiKZV+NvHqL0ifzdrI8Ro7ESA==} + + dargs@8.1.0: + resolution: {integrity: sha512-wAV9QHOsNbwnWdNW2FYvE1P56wtgSbM+3SZcdGiWQILwVjACCXDCI3Ai8QlCjMDB8YK5zySiXZYBiwGmNY3lnw==} + engines: {node: '>=12'} + + data-uri-to-buffer@5.0.1: + resolution: {integrity: sha512-a9l6T1qqDogvvnw0nKlfZzqsyikEBZBClF39V3TFoKhDtGBqHu2HkuomJc02j5zft8zrUaXEuoicLeW54RkzPg==} + engines: {node: '>= 14'} + + data-urls@3.0.2: + resolution: {integrity: sha512-Jy/tj3ldjZJo63sVAvg6LHt2mHvl4V6AgRAmNDtLdm7faqtsx+aJG42rsyCo9JCoRVKwPFzKlIPx3DIibwSIaQ==} + engines: {node: '>=12'} + + data-view-buffer@1.0.1: + resolution: {integrity: sha512-0lht7OugA5x3iJLOWFhWK/5ehONdprk0ISXqVFn/NFrDu+cuc8iADFrGQz5BnRK7LLU3JmkbXSxaqX+/mXYtUA==} + engines: {node: '>= 0.4'} + + data-view-byte-length@1.0.1: + resolution: {integrity: sha512-4J7wRJD3ABAzr8wP+OcIcqq2dlUKp4DVflx++hs5h5ZKydWMI6/D/fAot+yh6g2tHh8fLFTvNOaVN357NvSrOQ==} + engines: {node: '>= 0.4'} + + data-view-byte-offset@1.0.0: + resolution: {integrity: sha512-t/Ygsytq+R995EJ5PZlD4Cu56sWa8InXySaViRzw9apusqsOO2bQP+SbYzAhR0pFKoB+43lYy8rWban9JSuXnA==} + engines: {node: '>= 0.4'} + + date-fns@2.29.3: + resolution: {integrity: sha512-dDCnyH2WnnKusqvZZ6+jA1O51Ibt8ZMRNkDZdyAyK4YfbDwa/cEmuztzG5pk6hqlp9aSBPYcjOlktquahGwGeA==} + engines: {node: '>=0.11'} + + dayjs@1.11.6: + resolution: {integrity: sha512-zZbY5giJAinCG+7AGaw0wIhNZ6J8AhWuSXKvuc1KAyMiRsvGQWqh4L+MomvhdAYjN+lqvVCMq1I41e3YHvXkyQ==} + + debug@3.2.7: + resolution: {integrity: sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==} + peerDependencies: + supports-color: '*' + peerDependenciesMeta: + supports-color: + optional: true + + debug@4.3.4: + resolution: {integrity: sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==} + engines: {node: '>=6.0'} + peerDependencies: + supports-color: '*' + peerDependenciesMeta: + supports-color: + optional: true + + decamelize-keys@1.1.1: + resolution: {integrity: sha512-WiPxgEirIV0/eIOMcnFBA3/IJZAZqKnwAwWyvvdi4lsr1WCN22nhdf/3db3DoZcUjTV2SqfzIwNyp6y2xs3nmg==} + engines: {node: '>=0.10.0'} + + decamelize@1.2.0: + resolution: {integrity: sha512-z2S+W9X73hAUUki+N+9Za2lBlun89zigOyGrsax+KUQ6wKW4ZoWpEYBkGhQjwAjjDCkWxhY0VKEhk8wzY7F5cA==} + engines: {node: '>=0.10.0'} + + decamelize@5.0.1: + resolution: {integrity: sha512-VfxadyCECXgQlkoEAjeghAr5gY3Hf+IKjKb+X8tGVDtveCjN+USwprd2q3QXBR9T1+x2DG0XZF5/w+7HAtSaXA==} + engines: {node: '>=10'} + + decamelize@6.0.0: + resolution: {integrity: sha512-Fv96DCsdOgB6mdGl67MT5JaTNKRzrzill5OH5s8bjYJXVlcXyPYGyPsUkWyGV5p1TXI5esYIYMMeDJL0hEIwaA==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + + decimal.js-light@2.5.1: + resolution: {integrity: sha512-qIMFpTMZmny+MMIitAB6D7iVPEorVw6YQRWkvarTkT4tBeSLLiHzcwj6q0MmYSFCiVpiqPJTJEYIrpcPzVEIvg==} + + decimal.js@10.4.2: + resolution: {integrity: sha512-ic1yEvwT6GuvaYwBLLY6/aFFgjZdySKTE8en/fkU3QICTmRtgtSlFn0u0BXN06InZwtfCelR7j8LRiDI/02iGA==} + + decode-named-character-reference@1.0.1: + resolution: {integrity: sha512-YV/0HQHreRwKb7uBopyIkLG17jG6Sv2qUchk9qSoVJ2f+flwRsPNBO0hAnjt6mTNYUT+vw9Gy2ihXg4sUWPi2w==} + + decode-uri-component@0.4.1: + resolution: {integrity: sha512-+8VxcR21HhTy8nOt6jf20w0c9CADrw1O8d+VZ/YzzCt4bJ3uBjw+D1q2osAB8RnpwwaeYBxy0HyKQxD5JBMuuQ==} + engines: {node: '>=14.16'} + + decompress-response@6.0.0: + resolution: {integrity: sha512-aW35yZM6Bb/4oJlZncMH2LCoZtJXTRxES17vE3hoRiowU2kWHaJKFkSBDnDR+cm9J+9QhXmREyIfv0pji9ejCQ==} + engines: {node: '>=10'} + + dedent@1.5.1: + resolution: {integrity: sha512-+LxW+KLWxu3HW3M2w2ympwtqPrqYRzU8fqi6Fhd18fBALe15blJPI/I4+UHveMVG6lJqB4JNd4UG0S5cnVHwIg==} + peerDependencies: + babel-plugin-macros: ^3.1.0 + peerDependenciesMeta: + babel-plugin-macros: + optional: true + + deep-eql@4.1.3: + resolution: {integrity: sha512-WaEtAOpRA1MQ0eohqZjpGD8zdI0Ovsm8mmFhaDN8dvDZzyoUMcYDnf5Y6iu7HTXxf8JDS23qWa4a+hKCDyOPzw==} + engines: {node: '>=6'} + + deep-equal@1.0.1: + resolution: {integrity: sha1-9dJgKStmDghO/0zbyfCK0yR0SLU=} + + deep-is@0.1.4: + resolution: {integrity: sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==} + + deep-object-diff@1.1.9: + resolution: {integrity: sha512-Rn+RuwkmkDwCi2/oXOFS9Gsr5lJZu/yTGpK7wAaAIE75CC+LCGEZHpY6VQJa/RoJcrmaA/docWJZvYohlNkWPA==} + + deepmerge@4.2.2: + resolution: {integrity: sha512-FJ3UgI4gIl+PHZm53knsuSFpE+nESMr7M4v9QcgB7S63Kj/6WqMiFQJpBBYz1Pt+66bZpP3Q7Lye0Oo9MPKEdg==} + engines: {node: '>=0.10.0'} + + deepmerge@4.3.1: + resolution: {integrity: sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==} + engines: {node: '>=0.10.0'} + + defaults@1.0.4: + resolution: {integrity: sha512-eFuaLoy/Rxalv2kr+lqMlUnrDWV+3j4pljOIJgLIhI058IQfWJ7vXhyEIHu+HtC738klGALYxOKDO0bQP3tg8A==} + + defer-to-connect@2.0.1: + resolution: {integrity: sha512-4tvttepXG1VaYGrRibk5EwJd1t4udunSOVMdLSAL6mId1ix438oPwPZMALY41FCijukO1L0twNcGsdzS7dHgDg==} + engines: {node: '>=10'} + + define-data-property@1.1.4: + resolution: {integrity: sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==} + engines: {node: '>= 0.4'} + + define-properties@1.1.4: + resolution: {integrity: sha512-uckOqKcfaVvtBdsVkdPv3XjveQJsNQqmhXgRi8uhvWWuPYZCNlzT8qAyblUgNoXdHdjMTzAqeGjAoli8f+bzPA==} + engines: {node: '>= 0.4'} + + define-properties@1.2.1: + resolution: {integrity: sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg==} + engines: {node: '>= 0.4'} + + degenerator@5.0.1: + resolution: {integrity: sha512-TllpMR/t0M5sqCXfj85i4XaAzxmS5tVA16dqvdkMwGmzI+dXLXnw3J+3Vdv7VKw+ThlTMboK6i9rnZ6Nntj5CQ==} + engines: {node: '>= 14'} + + delayed-stream@1.0.0: + resolution: {integrity: sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==} + engines: {node: '>=0.4.0'} + + delegates@1.0.0: + resolution: {integrity: sha1-hMbhWbgZBP3KWaDvRM2HDTElD5o=} + + depd@1.1.2: + resolution: {integrity: sha512-7emPTl6Dpo6JRXOXjLRxck+FlLRX5847cLKEn00PLAgc3g2hTZZgr+e4c2v6QpSmLeFP3n5yUo7ft6avBK/5jQ==} + engines: {node: '>= 0.6'} + + depd@2.0.0: + resolution: {integrity: sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==} + engines: {node: '>= 0.8'} + + dequal@2.0.3: + resolution: {integrity: sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA==} + engines: {node: '>=6'} + + destroy@1.0.4: + resolution: {integrity: sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA=} + + destroy@1.2.0: + resolution: {integrity: sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==} + engines: {node: '>= 0.8', npm: 1.2.8000 || >= 1.4.16} + + detab@2.0.4: + resolution: {integrity: sha512-8zdsQA5bIkoRECvCrNKPla84lyoR7DSAyf7p0YgXzBO9PDJx8KntPUay7NS6yp+KdxdVtiE5SpHKtbp2ZQyA9g==} + + detect-indent@6.1.0: + resolution: {integrity: sha512-reYkTUJAZb9gUuZ2RvVCNhVHdg62RHnJ7WJl8ftMi4diZ6NWlciOzQN88pUhSELEwflJht4oQDv0F0BMlwaYtA==} + engines: {node: '>=8'} + + detect-libc@1.0.3: + resolution: {integrity: sha512-pGjwhsmsp4kL2RTz08wcOlGN83otlqHeD/Z5T8GXZB+/YcpQ/dgo+lbU8ZsGxV0HIvqqxo9l7mqYwyYMD9bKDg==} + engines: {node: '>=0.10'} + hasBin: true + + detect-libc@2.0.2: + resolution: {integrity: sha512-UX6sGumvvqSaXgdKGUsgZWqcUyIXZ/vZTrlRT/iobiKhGL0zL4d3osHj3uqllWJK+i+sixDS/3COVEOFbupFyw==} + engines: {node: '>=8'} + + detect-newline@3.1.0: + resolution: {integrity: sha512-TLz+x/vEXm/Y7P7wn1EJFNLxYpUD4TgMosxY6fAVJUnJMbupHBOncxyWUG9OpTaH9EBD7uFI5LfEgmMOc54DsA==} + engines: {node: '>=8'} + + devlop@1.1.0: + resolution: {integrity: sha512-RWmIqhcFf1lRYBvNmr7qTNuyCt/7/ns2jbpp1+PalgE/rDQcBT0fioSMUpJ93irlUhC5hrg4cYqe6U+0ImW0rA==} + + devtools-protocol@0.0.1262051: + resolution: {integrity: sha512-YJe4CT5SA8on3Spa+UDtNhEqtuV6Epwz3OZ4HQVLhlRccpZ9/PAYk0/cy/oKxFKRrZPBUPyxympQci4yWNWZ9g==} + + dezalgo@1.0.4: + resolution: {integrity: sha512-rXSP0bf+5n0Qonsb+SVVfNfIsimO4HEtmnIpPHY8Q1UCzKlQrDMfdobr8nJOOsRgWCyMRqeSBQzmWUMq7zvVig==} + + diagnostic-channel-publishers@1.0.8: + resolution: {integrity: sha512-HmSm9hXxSPxA9BaLGY98QU1zsdjeCk113KjAYGPCen1ZP6mhVaTPzHd6UYv5r21DnWANi+f+NyPOHruGT9jpqQ==} + peerDependencies: + diagnostic-channel: '*' + + diagnostic-channel@1.1.1: + resolution: {integrity: sha512-r2HV5qFkUICyoaKlBEpLKHjxMXATUf/l+h8UZPGBHGLy4DDiY2sOLcIctax4eRnTw5wH2jTMExLntGPJ8eOJxw==} + + diff-sequences@29.6.3: + resolution: {integrity: sha512-EjePK1srD3P08o2j4f0ExnylqRs5B9tJjcp9t1krH2qRi8CCdsYfwe9JgSLurFBWwq4uOlipzfk5fHNvwFKr8Q==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + diff@4.0.2: + resolution: {integrity: sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==} + engines: {node: '>=0.3.1'} + + diff@5.1.0: + resolution: {integrity: sha512-D+mk+qE8VC/PAUrlAU34N+VfXev0ghe5ywmpqrawphmVZc1bEfn56uo9qpyGp1p4xpzOHkSW4ztBd6L7Xx4ACw==} + engines: {node: '>=0.3.1'} + + dijkstrajs@1.0.3: + resolution: {integrity: sha512-qiSlmBq9+BCdCA/L46dw8Uy93mloxsPSbwnm5yrKn2vMPiy8KyAskTF6zuV/j5BMsmOGZDPs7KjU+mjb670kfA==} + + dir-glob@3.0.1: + resolution: {integrity: sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==} + engines: {node: '>=8'} + + dnd-core@16.0.0: + resolution: {integrity: sha512-8cGtybb5LBjG2euYgVv3amk49F+9dH3l5TuuGQf0mhFr+KWIPE1qPxB8VpPDov74ZevUAxVDxadL2zN7I0oQ1Q==} + + doctrine@2.1.0: + resolution: {integrity: sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==} + engines: {node: '>=0.10.0'} + + doctrine@3.0.0: + resolution: {integrity: sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==} + engines: {node: '>=6.0.0'} + + dom-accessibility-api@0.5.10: + resolution: {integrity: sha512-Xu9mD0UjrJisTmv7lmVSDMagQcU9R5hwAbxsaAE/35XPnPLJobbuREfV/rraiSaEj/UOvgrzQs66zyTWTlyd+g==} + + dom-helpers@3.4.0: + resolution: {integrity: sha512-LnuPJ+dwqKDIyotW1VzmOZ5TONUN7CwkCR5hrgawTUbkBGYdeoNLZo6nNfGkCrjtE1nXXaj7iMMpDa8/d9WoIA==} + + dom-serializer@1.4.1: + resolution: {integrity: sha512-VHwB3KfrcOOkelEG2ZOfxqLZdfkil8PtJi4P8N2MMXucZq2yLp75ClViUlOVwyoHEDjYU433Aq+5zWP61+RGag==} + + domelementtype@2.3.0: + resolution: {integrity: sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw==} + + domexception@4.0.0: + resolution: {integrity: sha512-A2is4PLG+eeSfoTMA95/s4pvAoSo2mKtiM5jlHkAVewmiO8ISFTFKZjH7UAM1Atli/OT/7JHOrJRJiMKUZKYBw==} + engines: {node: '>=12'} + + domhandler@4.3.1: + resolution: {integrity: sha512-GrwoxYN+uWlzO8uhUXRl0P+kHE4GtVPfYzVLcUxPL7KNdHKj66vvlhiweIHqYYXWlw+T8iLMp42Lm67ghw4WMQ==} + engines: {node: '>= 4'} + + domutils@2.8.0: + resolution: {integrity: sha512-w96Cjofp72M5IIhpjgobBimYEfoPjx1Vx0BSX9P30WBdZW2WIKU0T1Bd0kz2eNZ9ikjKgHbEyKx8BB6H1L3h3A==} + + dot-case@3.0.4: + resolution: {integrity: sha512-Kv5nKlh6yRrdrGvxeJ2e5y2eRUpkUosIW4A2AS38zwSz27zu7ufDwQPi5Jhs3XAlGNetl3bmnGhQsMtkKJnj3w==} + + dot-prop@5.3.0: + resolution: {integrity: sha512-QM8q3zDe58hqUqjraQOmzZ1LIH9SWQJTlEKCH4kJ2oQvLZk7RbQXvtDM2XEq3fwkV9CCvvH4LA0AV+ogFsBM2Q==} + engines: {node: '>=8'} + + dotenv-expand@5.1.0: + resolution: {integrity: sha512-YXQl1DSa4/PQyRfgrv6aoNjhasp/p4qs9FjJ4q4cQk+8m4r6k4ZSiEyytKG8f8W9gi8WsQtIObNmKd+tMzNTmA==} + + dotenv@16.0.0: + resolution: {integrity: sha512-qD9WU0MPM4SWLPJy/r2Be+2WgQj8plChsyrCNQzW/0WjvcJQiKQJ9mH3ZgB3fxbUUxgc/11ZJ0Fi5KiimWGz2Q==} + engines: {node: '>=12'} + + dotenv@7.0.0: + resolution: {integrity: sha512-M3NhsLbV1i6HuGzBUH8vXrtxOk+tWmzWKDMbAVSUp3Zsjm7ywFeuwrUXhmhQyRK1q5B5GGy7hcXPbj3bnfZg2g==} + engines: {node: '>=6'} + + duplexer@0.1.2: + resolution: {integrity: sha512-jtD6YG370ZCIi/9GTaJKQxWTZD045+4R4hTk/x1UyoqadyJ9x9CgSi1RlVDQF8U2sxLLSnFkCaMihqljHIWgMg==} + + duplexify@4.1.3: + resolution: {integrity: sha512-M3BmBhwJRZsSx38lZyhE53Csddgzl5R7xGJNk7CVddZD6CcmwMCH8J+7AprIrQKH7TonKxaCjcv27Qmf+sQ+oA==} + + eastasianwidth@0.2.0: + resolution: {integrity: sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==} + + ecdsa-sig-formatter@1.0.11: + resolution: {integrity: sha512-nagl3RYrbNv6kQkeJIpt6NJZy8twLB/2vtz6yN9Z4vRKHN4/QZJIEbqohALSgwKdnksuY3k5Addp5lg8sVoVcQ==} + + ee-first@1.1.1: + resolution: {integrity: sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0=} + + electron-to-chromium@1.4.281: + resolution: {integrity: sha512-yer0w5wCYdFoZytfmbNhwiGI/3cW06+RV7E23ln4490DVMxs7PvYpbsrSmAiBn/V6gode8wvJlST2YfWgvzWIg==} + + electron-to-chromium@1.4.738: + resolution: {integrity: sha512-lwKft2CLFztD+vEIpesrOtCrko/TFnEJlHFdRhazU7Y/jx5qc4cqsocfVrBg4So4gGe9lvxnbLIoev47WMpg+A==} + + emitter-listener@1.1.2: + resolution: {integrity: sha512-Bt1sBAGFHY9DKY+4/2cV6izcKJUf5T7/gkdmkxzX/qv9CcGH8xSwVRW5mtX03SWJtRTWSOpzCuWN9rBFYZepZQ==} + + emittery@0.13.1: + resolution: {integrity: sha512-DeWwawk6r5yR9jFgnDKYt4sLS0LmHJJi3ZOnb5/JdbYwj3nW+FxQnHIjhBKz8YLC7oRNPVM9NQ47I3CVx34eqQ==} + engines: {node: '>=12'} + + emoji-regex@10.3.0: + resolution: {integrity: sha512-QpLs9D9v9kArv4lfDEgg1X/gN5XLnf/A6l9cs8SPZLRZR3ZkY9+kwIQTxm+fsSej5UMYGE8fdoaZVIBlqG0XTw==} + + emoji-regex@8.0.0: + resolution: {integrity: sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==} + + emoji-regex@9.2.2: + resolution: {integrity: sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==} + + encode-utf8@1.0.3: + resolution: {integrity: sha512-ucAnuBEhUK4boH2HjVYG5Q2mQyPorvv0u/ocS+zhdw0S8AlHYY+GOFhP1Gio5z4icpP2ivFSvhtFjQi8+T9ppw==} + + encodeurl@1.0.2: + resolution: {integrity: sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k=} + engines: {node: '>= 0.8'} + + end-of-stream@1.4.4: + resolution: {integrity: sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==} + + enhanced-resolve@5.16.0: + resolution: {integrity: sha512-O+QWCviPNSSLAD9Ucn8Awv+poAkqn3T1XY5/N7kR7rQO9yfSGWkYZDwpJ+iKF7B8rxaQKWngSqACpgzeapSyoA==} + engines: {node: '>=10.13.0'} + + enquirer@2.3.6: + resolution: {integrity: sha512-yjNnPr315/FjS4zIsUxYguYUPP2e1NK4d7E7ZOLiyYCcbFBiTMyID+2wvm2w6+pZ/odMA7cRkjhsPbltwBOrLg==} + engines: {node: '>=8.6'} + + ent@2.2.0: + resolution: {integrity: sha512-GHrMyVZQWvTIdDtpiEXdHZnFQKzeO09apj8Cbl4pKWy4i0Oprcq17usfDt5aO63swf0JOeMWjWQE/LzgSRuWpA==} + + entities@2.2.0: + resolution: {integrity: sha512-p92if5Nz619I0w+akJrLZH0MX0Pb5DX39XOwQTtXSdQQOaYH03S1uIQp4mhOZtAXrxq4ViO67YTiLBo2638o9A==} + + entities@3.0.1: + resolution: {integrity: sha512-WiyBqoomrwMdFG1e0kqvASYfnlb0lp8M5o5Fw2OFq1hNZxxcNk8Ik0Xm7LxzBhuidnZB/UtBqVCgUz3kBOP51Q==} + engines: {node: '>=0.12'} + + entities@4.4.0: + resolution: {integrity: sha512-oYp7156SP8LkeGD0GF85ad1X9Ai79WtRsZ2gxJqtBuzH+98YUV6jkHEKlZkMbcrjJjIVJNIDP/3WL9wQkoPbWA==} + engines: {node: '>=0.12'} + + env-paths@2.2.1: + resolution: {integrity: sha512-+h1lkLKhZMTYjog1VEpJNG7NZJWcuc2DDk/qsqSTRRCOXiLjeQ1d1/udrUGhqMxUgAlwKNZ0cf2uqan5GLuS2A==} + engines: {node: '>=6'} + + error-ex@1.3.2: + resolution: {integrity: sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==} + + es-abstract@1.20.4: + resolution: {integrity: sha512-0UtvRN79eMe2L+UNEF1BwRe364sj/DXhQ/k5FmivgoSdpM90b8Jc0mDzKMGo7QS0BVbOP/bTwBKNnDc9rNzaPA==} + engines: {node: '>= 0.4'} + + es-abstract@1.23.3: + resolution: {integrity: sha512-e+HfNH61Bj1X9/jLc5v1owaLYuHdeHHSQlkhCBiTK8rBvKaULl/beGMxwrMXjpYrv4pz22BlY570vVePA2ho4A==} + engines: {node: '>= 0.4'} + + es-define-property@1.0.0: + resolution: {integrity: sha512-jxayLKShrEqqzJ0eumQbVhTYQM27CfT1T35+gCgDFoL82JLsXqTJ76zv6A0YLOgEnLUMvLzsDsGIrl8NFpT2gQ==} + engines: {node: '>= 0.4'} + + es-errors@1.3.0: + resolution: {integrity: sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==} + engines: {node: '>= 0.4'} + + es-iterator-helpers@1.0.18: + resolution: {integrity: sha512-scxAJaewsahbqTYrGKJihhViaM6DDZDDoucfvzNbK0pOren1g/daDQ3IAhzn+1G14rBG7w+i5N+qul60++zlKA==} + engines: {node: '>= 0.4'} + + es-object-atoms@1.0.0: + resolution: {integrity: sha512-MZ4iQ6JwHOBQjahnjwaC1ZtIBH+2ohjamzAO3oaHcXYup7qxjF2fixyH+Q71voWHeOkI2q/TnJao/KfXYIZWbw==} + engines: {node: '>= 0.4'} + + es-set-tostringtag@2.0.3: + resolution: {integrity: sha512-3T8uNMC3OQTHkFUsFq8r/BwAXLHvU/9O9mE0fBc/MY5iq/8H7ncvO947LmYA6ldWw9Uh8Yhf25zu6n7nML5QWQ==} + engines: {node: '>= 0.4'} + + es-shim-unscopables@1.0.0: + resolution: {integrity: sha512-Jm6GPcCdC30eMLbZ2x8z2WuRwAws3zTBBKuusffYVUrNj/GVSUAZ+xKMaUpfNDR5IbyNA5LJbaecoUVbmUcB1w==} + + es-shim-unscopables@1.0.2: + resolution: {integrity: sha512-J3yBRXCzDu4ULnQwxyToo/OjdMx6akgVC7K6few0a7F/0wLtmKKN7I73AH5T2836UuXRqN7Qg+IIUw/+YJksRw==} + + es-to-primitive@1.2.1: + resolution: {integrity: sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==} + engines: {node: '>= 0.4'} + + esbuild@0.20.2: + resolution: {integrity: sha512-WdOOppmUNU+IbZ0PaDiTst80zjnrOkyJNHoKupIcVyU8Lvla3Ugx94VzkQ32Ijqd7UhHJy75gNWDMUekcrSJ6g==} + engines: {node: '>=12'} + hasBin: true + + escalade@3.1.1: + resolution: {integrity: sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==} + engines: {node: '>=6'} + + escape-html@1.0.3: + resolution: {integrity: sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg=} + + escape-string-regexp@1.0.5: + resolution: {integrity: sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==} + engines: {node: '>=0.8.0'} + + escape-string-regexp@2.0.0: + resolution: {integrity: sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==} + engines: {node: '>=8'} + + escape-string-regexp@4.0.0: + resolution: {integrity: sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==} + engines: {node: '>=10'} + + escape-string-regexp@5.0.0: + resolution: {integrity: sha512-/veY75JbMK4j1yjvuUxuVsiS/hr/4iHs9FTT6cgTexxdE0Ly/glccBAkloH/DofkjRbZU3bnoj38mOmhkZ0lHw==} + engines: {node: '>=12'} + + escodegen@2.0.0: + resolution: {integrity: sha512-mmHKys/C8BFUGI+MAWNcSYoORYLMdPzjrknd2Vc+bUsjN5bXcr8EhrNB+UTqfL1y3I9c4fw2ihgtMPQLBRiQxw==} + engines: {node: '>=6.0'} + hasBin: true + + escodegen@2.1.0: + resolution: {integrity: sha512-2NlIDTwUWJN0mRPQOdtQBzbUHvdGY2P1VXSyU83Q3xKxM7WHX2Ql8dKq782Q9TgQUNOLEzEYu9bzLNj1q88I5w==} + engines: {node: '>=6.0'} + hasBin: true + + eslint-ast-utils@1.1.0: + resolution: {integrity: sha512-otzzTim2/1+lVrlH19EfQQJEhVJSu0zOb9ygb3iapN6UlyaDtyRq4b5U1FuW0v1lRa9Fp/GJyHkSwm6NqABgCA==} + engines: {node: '>=4'} + + eslint-compat-utils@0.5.0: + resolution: {integrity: sha512-dc6Y8tzEcSYZMHa+CMPLi/hyo1FzNeonbhJL7Ol0ccuKQkwopJcJBA9YL/xmMTLU1eKigXo9vj9nALElWYSowg==} + engines: {node: '>=12'} + peerDependencies: + eslint: '>=6.0.0' + + eslint-config-prettier@9.1.0: + resolution: {integrity: sha512-NSWl5BFQWEPi1j4TjVNItzYV7dZXZ+wP6I6ZhrBGpChQhZRUaElihE9uRRkcbRnNb76UMKDF3r+WTmNcGPKsqw==} + hasBin: true + peerDependencies: + eslint: '>=7.0.0' + + eslint-config-xo-react@0.27.0: + resolution: {integrity: sha512-wiV215xQIn71XZyyVfaOXHaFpR1B14IJttwOjMi/eqUK1s+ojJdHr7eHqTLaGUfh6FKgWha1QNwePlIXx7mBUg==} + engines: {node: '>=12'} + peerDependencies: + eslint: '>=8.6.0' + eslint-plugin-react: '>=7.29.0' + eslint-plugin-react-hooks: '>=4.3.0' + + eslint-config-xo-typescript@4.0.0: + resolution: {integrity: sha512-pmSWzVpvzEjZHG7S/rN34cFXAoe6YbvWFBQSitEXD5CcT2SULfykYl8hcYXss37r5N3SmJYAiO6VlcfkPiDRxg==} + engines: {node: '>=18'} + peerDependencies: + '@typescript-eslint/eslint-plugin': '>=7.0.2' + '@typescript-eslint/parser': '>=7.0.2' + eslint: '>=8.56.0' + typescript: '>=5.0.0' + + eslint-config-xo@0.44.0: + resolution: {integrity: sha512-YG4gdaor0mJJi8UBeRJqDPO42MedTWYMaUyucF5bhm2pi/HS98JIxfFQmTLuyj6hGpQlAazNfyVnn7JuDn+Sew==} + engines: {node: '>=18'} + peerDependencies: + eslint: '>=8.56.0' + + eslint-import-resolver-node@0.3.9: + resolution: {integrity: sha512-WFj2isz22JahUv+B788TlO3N6zL3nNJGU8CcZbPZvVEkBPaJdCV4vy5wyghty5ROFbCRnm132v8BScu5/1BQ8g==} + + eslint-import-resolver-typescript@3.6.1: + resolution: {integrity: sha512-xgdptdoi5W3niYeuQxKmzVDTATvLYqhpwmykwsh7f6HIOStGWEIL9iqZgQDF9u9OEzrRwR8no5q2VT+bjAujTg==} + engines: {node: ^14.18.0 || >=16.0.0} + peerDependencies: + eslint: '*' + eslint-plugin-import: '*' + + eslint-module-utils@2.8.1: + resolution: {integrity: sha512-rXDXR3h7cs7dy9RNpUlQf80nX31XWJEyGq1tRMo+6GsO5VmTe4UTwtmonAD4ZkAsrfMVDA2wlGJ3790Ys+D49Q==} + engines: {node: '>=4'} + peerDependencies: + '@typescript-eslint/parser': '*' + eslint: '*' + eslint-import-resolver-node: '*' + eslint-import-resolver-typescript: '*' + eslint-import-resolver-webpack: '*' + peerDependenciesMeta: + '@typescript-eslint/parser': + optional: true + eslint: + optional: true + eslint-import-resolver-node: + optional: true + eslint-import-resolver-typescript: + optional: true + eslint-import-resolver-webpack: + optional: true + + eslint-plugin-consistent-default-export-name@0.0.15: + resolution: {integrity: sha512-gqW7dnJbWMxI5H6/Pyz6Sl/vBMwOktePMI2iuuKPb4N82uvemUkfaWhsRZCKndSzpIVaCZ9wdspCVO1tm0wXJQ==} + engines: {node: '>=0.10.0'} + + eslint-plugin-es-x@7.6.0: + resolution: {integrity: sha512-I0AmeNgevgaTR7y2lrVCJmGYF0rjoznpDvqV/kIkZSZbZ8Rw3eu4cGlvBBULScfkSOCzqKbff5LR4CNrV7mZHA==} + engines: {node: ^14.18.0 || >=16.0.0} + peerDependencies: + eslint: '>=8' + + eslint-plugin-eslint-comments@3.2.0: + resolution: {integrity: sha512-0jkOl0hfojIHHmEHgmNdqv4fmh7300NdpA9FFpF7zaoLvB/QeXOGNLIo86oAveJFrfB1p05kC8hpEMHM8DwWVQ==} + engines: {node: '>=6.5.0'} + peerDependencies: + eslint: '>=4.19.1' + + eslint-plugin-import@2.29.1: + resolution: {integrity: sha512-BbPC0cuExzhiMo4Ff1BTVwHpjjv28C5R+btTOGaCRC7UEz801up0JadwkeSk5Ued6TG34uaczuVuH6qyy5YUxw==} + engines: {node: '>=4'} + peerDependencies: + '@typescript-eslint/parser': '*' + eslint: ^2 || ^3 || ^4 || ^5 || ^6 || ^7.2.0 || ^8 + peerDependenciesMeta: + '@typescript-eslint/parser': + optional: true + + eslint-plugin-jsx-a11y@6.8.0: + resolution: {integrity: sha512-Hdh937BS3KdwwbBaKd5+PLCOmYY6U4f2h9Z2ktwtNKvIdIEu137rjYbcb9ApSbVJfWxANNuiKTD/9tOKjK9qOA==} + engines: {node: '>=4.0'} + peerDependencies: + eslint: ^3 || ^4 || ^5 || ^6 || ^7 || ^8 + + eslint-plugin-n@17.2.1: + resolution: {integrity: sha512-uW1+df2bo06kR7ix6nB614RUlvjRPrYxlaX832O6e1MCJp4V7YozEdvMgCYuvn4ltnjPu1FVYhQ2KRrmTNoJfg==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + peerDependencies: + eslint: '>=8.23.0' + + eslint-plugin-no-use-extend-native@0.5.0: + resolution: {integrity: sha512-dBNjs8hor8rJgeXLH4HTut5eD3RGWf9JUsadIfuL7UosVQ/dnvOKwxEcRrXrFxrMZ8llUVWT+hOimxJABsAUzQ==} + engines: {node: '>=6.0.0'} + + eslint-plugin-prettier@5.1.3: + resolution: {integrity: sha512-C9GCVAs4Eq7ZC/XFQHITLiHJxQngdtraXaM+LoUFoFp/lHNl2Zn8f3WQbe9HvTBBQ9YnKFB0/2Ajdqwo5D1EAw==} + engines: {node: ^14.18.0 || >=16.0.0} + peerDependencies: + '@types/eslint': '>=8.0.0' + eslint: '>=8.0.0' + eslint-config-prettier: '*' + prettier: '>=3.0.0' + peerDependenciesMeta: + '@types/eslint': + optional: true + eslint-config-prettier: + optional: true + + eslint-plugin-promise@6.1.1: + resolution: {integrity: sha512-tjqWDwVZQo7UIPMeDReOpUgHCmCiH+ePnVT+5zVapL0uuHnegBUs2smM13CzOs2Xb5+MHMRFTs9v24yjba4Oig==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + peerDependencies: + eslint: ^7.0.0 || ^8.0.0 + + eslint-plugin-react-hooks@4.6.0: + resolution: {integrity: sha512-oFc7Itz9Qxh2x4gNHStv3BqJq54ExXmfC+a1NjAta66IAN87Wu0R/QArgIS9qKzX3dXKPI9H5crl9QchNMY9+g==} + engines: {node: '>=10'} + peerDependencies: + eslint: ^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0-0 + + eslint-plugin-react@7.34.1: + resolution: {integrity: sha512-N97CxlouPT1AHt8Jn0mhhN2RrADlUAsk1/atcT2KyA/l9Q/E6ll7OIGwNumFmWfZ9skV3XXccYS19h80rHtgkw==} + engines: {node: '>=4'} + peerDependencies: + eslint: ^3 || ^4 || ^5 || ^6 || ^7 || ^8 + + eslint-plugin-sql@2.1.0: + resolution: {integrity: sha512-UPapPPhK1ADgQDTogpApiSAh6bYjrt2daYkKCdApHm5KPbq9qR4ca4TPyYod06bAnLgswbri6Z9gEPAy0R+B1A==} + engines: {node: '>=12'} + peerDependencies: + eslint: '>=8.1.0' + + eslint-plugin-unicorn@52.0.0: + resolution: {integrity: sha512-1Yzm7/m+0R4djH0tjDjfVei/ju2w3AzUGjG6q8JnuNIL5xIwsflyCooW5sfBvQp2pMYQFSWWCFONsjCax1EHng==} + engines: {node: '>=16'} + peerDependencies: + eslint: '>=8.56.0' + + eslint-plugin-unused-imports@3.1.0: + resolution: {integrity: sha512-9l1YFCzXKkw1qtAru1RWUtG2EVDZY0a0eChKXcL+EZ5jitG7qxdctu4RnvhOJHv4xfmUf7h+JJPINlVpGhZMrw==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + peerDependencies: + '@typescript-eslint/eslint-plugin': 6 - 7 + eslint: '8' + peerDependenciesMeta: + '@typescript-eslint/eslint-plugin': + optional: true + + eslint-rule-composer@0.3.0: + resolution: {integrity: sha512-bt+Sh8CtDmn2OajxvNO+BX7Wn4CIWMpTRm3MaiKPCQcnnlm0CS2mhui6QaoeQugs+3Kj2ESKEEGJUdVafwhiCg==} + engines: {node: '>=4.0.0'} + + eslint-scope@7.2.2: + resolution: {integrity: sha512-dOt21O7lTMhDM+X9mB4GX+DZrZtCUJPL/wlcTqxyrx5IvO0IYtILdtrQGQp+8n5S0gwSVmOf9NQrjMOgfQZlIg==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + + eslint-visitor-keys@3.4.1: + resolution: {integrity: sha512-pZnmmLwYzf+kWaM/Qgrvpen51upAktaaiI01nsJD/Yr3lMOdNtq0cxkrrg16w64VtisN6okbs7Q8AfGqj4c9fA==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + + eslint-visitor-keys@3.4.3: + resolution: {integrity: sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + + eslint@8.57.0: + resolution: {integrity: sha512-dZ6+mexnaTIbSBZWgou51U6OmzIhYM2VcNdtiTtI7qPNZm35Akpr0f6vtw3w1Kmn5PYo+tZVfh13WrhpS6oLqQ==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + hasBin: true + + espree@9.6.0: + resolution: {integrity: sha512-1FH/IiruXZ84tpUlm0aCUEwMl2Ho5ilqVh0VvQXw+byAz/4SAciyHLlfmL5WYqsvD38oymdUwBss0LtK8m4s/A==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + + espree@9.6.1: + resolution: {integrity: sha512-oruZaFkjorTpF32kDSI5/75ViwGeZginGGy2NoOSg3Q9bnwlnmDm4HLnkl0RE3n+njDXR037aY1+x58Z/zFdwQ==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + + esprima@4.0.1: + resolution: {integrity: sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==} + engines: {node: '>=4'} + hasBin: true + + esquery@1.5.0: + resolution: {integrity: sha512-YQLXUplAwJgCydQ78IMJywZCceoqk1oH01OERdSAJc/7U2AylwjhSCLDEtqwg811idIS/9fIU5GjG73IgjKMVg==} + engines: {node: '>=0.10'} + + esrecurse@4.3.0: + resolution: {integrity: sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==} + engines: {node: '>=4.0'} + + estraverse@5.3.0: + resolution: {integrity: sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==} + engines: {node: '>=4.0'} + + estree-walker@2.0.2: + resolution: {integrity: sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==} + + estree-walker@3.0.3: + resolution: {integrity: sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g==} + + esutils@2.0.3: + resolution: {integrity: sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==} + engines: {node: '>=0.10.0'} + + eta@3.4.0: + resolution: {integrity: sha512-tCsc7WXTjrTx4ZjYLplcqrI3o4mYJ+Z6YspeuGL8tbt/hHoMchwBwtKfwM09svEY86iRapY93vUqQttcNuIO5Q==} + engines: {node: '>=6.0.0'} + + etag@1.8.1: + resolution: {integrity: sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==} + engines: {node: '>= 0.6'} + + event-target-shim@5.0.1: + resolution: {integrity: sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ==} + engines: {node: '>=6'} + + eventemitter3@4.0.7: + resolution: {integrity: sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw==} + + eventemitter3@5.0.1: + resolution: {integrity: sha512-GWkBvjiSZK87ELrYOSESUYeVIc9mvLLf/nXalMOS5dYrgZq9o5OVkbZAVM06CVxYsCwH9BDZFPlQTlPA1j4ahA==} + + events@3.3.0: + resolution: {integrity: sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==} + engines: {node: '>=0.8.x'} + + execa@5.1.1: + resolution: {integrity: sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==} + engines: {node: '>=10'} + + execa@8.0.1: + resolution: {integrity: sha512-VyhnebXciFV2DESc+p6B+y0LjSm0krU4OgJN44qFAhBY0TJ+1V61tYD2+wHusZ6F9n5K+vl8k0sTy7PEfV4qpg==} + engines: {node: '>=16.17'} + + exenv@1.2.2: + resolution: {integrity: sha512-Z+ktTxTwv9ILfgKCk32OX3n/doe+OcLTRtqK9pcL+JsP3J1/VW8Uvl4ZjLlKqeW4rzK4oesDOGMEMRIZqtP4Iw==} + + exit@0.1.2: + resolution: {integrity: sha512-Zk/eNKV2zbjpKzrsQ+n1G6poVbErQxJ0LBOJXaKZ1EViLzH+hrLu9cdXI4zw9dBQJslwBEpbQ2P1oS7nDxs6jQ==} + engines: {node: '>= 0.8.0'} + + expand-tilde@1.2.2: + resolution: {integrity: sha512-rtmc+cjLZqnu9dSYosX9EWmSJhTwpACgJQTfj4hgg2JjOD/6SIQalZrt4a3aQeh++oNxkazcaxrhPUj6+g5G/Q==} + engines: {node: '>=0.10.0'} + + expect-puppeteer@10.0.0: + resolution: {integrity: sha512-E7sE6nVdEbrnpDOBMmcLgyqLJKt876AlBg1A+gsu5R8cWx+SLafreOgJAgzXg5Qko7Tk0cW5oZdRbHQLU738dg==} + engines: {node: '>=16'} + + expect@29.7.0: + resolution: {integrity: sha512-2Zks0hf1VLFYI1kbh0I5jP3KHHyCHpkfyHBzsSXRFgl/Bg9mWYfMW8oD+PdMPlEwy5HNsR9JutYy6pMeOh61nw==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + extend@3.0.2: + resolution: {integrity: sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==} + + extendable-error@0.1.7: + resolution: {integrity: sha512-UOiS2in6/Q0FK0R0q6UY9vYpQ21mr/Qn1KOnte7vsACuNJf514WvCCUHSRCPcgjPT2bAhNIJdlE6bVap1GKmeg==} + + external-editor@3.1.0: + resolution: {integrity: sha512-hMQ4CX1p1izmuLYyZqLMO/qGNw10wSv9QDCPfzXfyFrOaCSSoRfqE1Kf1s5an66J5JZC62NewG+mK49jOCtQew==} + engines: {node: '>=4'} + + extract-zip@2.0.1: + resolution: {integrity: sha512-GDhU9ntwuKyGXdZBUgTIe+vXnWj0fppUEtMDL0+idd5Sta8TGpHssn/eusA9mrPr9qNDym6SxAYZjNvCn/9RBg==} + engines: {node: '>= 10.17.0'} + hasBin: true + + fast-deep-equal@3.1.3: + resolution: {integrity: sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==} + + fast-diff@1.2.0: + resolution: {integrity: sha512-xJuoT5+L99XlZ8twedaRf6Ax2TgQVxvgZOYoPKqZufmJib0tL2tegPBOZb1pVNgIhlqDlA0eO0c3wBvQcmzx4w==} + + fast-equals@2.0.4: + resolution: {integrity: sha512-caj/ZmjHljPrZtbzJ3kfH5ia/k4mTJe/qSiXAGzxZWRZgsgDV0cvNaQULqUX8t0/JVlzzEdYOwCN5DmzTxoD4w==} + + fast-fifo@1.3.2: + resolution: {integrity: sha512-/d9sfos4yxzpwkDkuN7k2SqFKtYNmCTzgfEpz82x34IM9/zc8KGxQoXg1liNC/izpRM/MBdt44Nmx41ZWqk+FQ==} + + fast-glob@3.3.2: + resolution: {integrity: sha512-oX2ruAFQwf/Orj8m737Y5adxDQO0LAB7/S5MnxCdTNDd4p6BsyIVsv9JQsATbTSq8KHRpLwIHbVlUNatxd+1Ow==} + engines: {node: '>=8.6.0'} + + fast-json-stable-stringify@2.1.0: + resolution: {integrity: sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==} + + fast-json-stringify@2.7.12: + resolution: {integrity: sha512-4hjwZDPmgj/ZUKXhEWovGPciE/5mWtAIQQxN+2VBDFun7DRTk2oOItbu9ZZp6kqj+eZ/u7z+dgBgM74cfGRnBQ==} + engines: {node: '>= 10.0.0'} + + fast-levenshtein@2.0.6: + resolution: {integrity: sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==} + + fast-printf@1.6.9: + resolution: {integrity: sha512-FChq8hbz65WMj4rstcQsFB0O7Cy++nmbNfLYnD9cYv2cRn8EG6k/MGn9kO/tjO66t09DLDugj3yL+V2o6Qftrg==} + engines: {node: '>=10.0'} + + fast-safe-stringify@2.1.1: + resolution: {integrity: sha512-W+KJc2dmILlPplD/H4K9l9LcAHAfPtP6BY84uVLXQ6Evcz9Lcg33Y2z1IVblT6xdY54PXYVHEv+0Wpq8Io6zkA==} + + fast-xml-parser@4.2.5: + resolution: {integrity: sha512-B9/wizE4WngqQftFPmdaMYlXoJlJOYxGQOanC77fq9k8+Z0v5dDSVh+3glErdIROP//s/jgb7ZuxKfB8nVyo0g==} + hasBin: true + + fast-xml-parser@4.3.6: + resolution: {integrity: sha512-M2SovcRxD4+vC493Uc2GZVcZaj66CCJhWurC4viynVSTvrpErCShNcDz1lAho6n9REQKvL/ll4A4/fw6Y9z8nw==} + hasBin: true + + fastest-levenshtein@1.0.16: + resolution: {integrity: sha512-eRnCtTTtGZFpQCwhJiUOuxPQWRXVKYDn0b2PeHfXL6/Zi53SLAzAHfVhVWK2AryC/WH05kGfxhFIPvTF0SXQzg==} + engines: {node: '>= 4.9.1'} + + fastq@1.13.0: + resolution: {integrity: sha512-YpkpUnK8od0o1hmeSc7UUs/eB/vIPWJYjKck2QKIzAf71Vm1AAQ3EbuZB3g2JIy+pg+ERD0vqI79KyZiB2e2Nw==} + + fault@1.0.4: + resolution: {integrity: sha512-CJ0HCB5tL5fYTEA7ToAq5+kTwd++Borf1/bifxd9iT70QcXr4MRrO3Llf8Ifs70q+SJcGHFtnIE/Nw6giCtECA==} + + fb-watchman@2.0.2: + resolution: {integrity: sha512-p5161BqbuCaSnB8jIbzQHOlpgsPmK5rJVDfDKO91Axs5NC1uu3HRQm6wt9cd9/+GtQQIO53JdGXXoyDpTAsgYA==} + + fd-slicer@1.1.0: + resolution: {integrity: sha512-cE1qsB/VwyQozZ+q1dGxR8LBYNZeofhEdUNGSMbQD3Gw2lAzX9Zb3uIU6Ebc/Fmyjo9AWWfnn0AUCHqtevs/8g==} + + figures@5.0.0: + resolution: {integrity: sha512-ej8ksPF4x6e5wvK9yevct0UCXh8TTFlWGVLlgjZuoBH1HwjIfKE/IdL5mq89sFA7zELi1VhKpmtDnrs7zWyeyg==} + engines: {node: '>=14'} + + file-entry-cache@6.0.1: + resolution: {integrity: sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==} + engines: {node: ^10.12.0 || >=12.0.0} + + file-entry-cache@7.0.2: + resolution: {integrity: sha512-TfW7/1iI4Cy7Y8L6iqNdZQVvdXn0f8B4QcIXmkIbtTIe/Okm/nSlHb4IwGzRVOd3WfSieCgvf5cMzEfySAIl0g==} + engines: {node: '>=12.0.0'} + + file-selector@0.6.0: + resolution: {integrity: sha512-QlZ5yJC0VxHxQQsQhXvBaC7VRJ2uaxTf+Tfpu4Z/OcVQJVpZO+DGU0rkoVW5ce2SccxugvpBJoMvUs59iILYdw==} + engines: {node: '>= 12'} + + fill-range@7.0.1: + resolution: {integrity: sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==} + engines: {node: '>=8'} + + filter-obj@5.1.0: + resolution: {integrity: sha512-qWeTREPoT7I0bifpPUXtxkZJ1XJzxWtfoWWkdVGqa+eCr3SHW/Ocp89o8vLvbUuQnadybJpjOKu4V+RwO6sGng==} + engines: {node: '>=14.16'} + + find-file-up@0.1.3: + resolution: {integrity: sha512-mBxmNbVyjg1LQIIpgO8hN+ybWBgDQK8qjht+EbrTCGmmPV/sc7RF1i9stPTD6bpvXZywBdrwRYxhSdJv867L6A==} + engines: {node: '>=0.10.0'} + + find-pkg@0.1.2: + resolution: {integrity: sha512-0rnQWcFwZr7eO0513HahrWafsc3CTFioEB7DRiEYCUM/70QXSY8f3mCST17HXLcPvEhzH/Ty/Bxd72ZZsr/yvw==} + engines: {node: '>=0.10.0'} + + find-process@1.4.7: + resolution: {integrity: sha512-/U4CYp1214Xrp3u3Fqr9yNynUrr5Le4y0SsJh2lMDDSbpwYSz3M2SMWQC+wqcx79cN8PQtHQIL8KnuY9M66fdg==} + hasBin: true + + find-up@4.1.0: + resolution: {integrity: sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==} + engines: {node: '>=8'} + + find-up@5.0.0: + resolution: {integrity: sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==} + engines: {node: '>=10'} + + find-up@7.0.0: + resolution: {integrity: sha512-YyZM99iHrqLKjmt4LJDj58KI+fYyufRLBSYcqycxf//KpBk9FoewoGX0450m9nB44qrZnovzC2oeP5hUibxc/g==} + engines: {node: '>=18'} + + find-yarn-workspace-root2@1.2.16: + resolution: {integrity: sha512-hr6hb1w8ePMpPVUK39S4RlwJzi+xPLuVuG8XlwXU3KD5Yn3qgBWVfy3AzNlDhWvE1EORCE65/Qm26rFQt3VLVA==} + + flat-cache@3.0.4: + resolution: {integrity: sha512-dm9s5Pw7Jc0GvMYbshN6zchCA9RgQlzzEZX3vylR9IqFfS8XciblUXOKfW6SiuJ0e13eDYZoZV5wdrev7P3Nwg==} + engines: {node: ^10.12.0 || >=12.0.0} + + flat-cache@3.2.0: + resolution: {integrity: sha512-CYcENa+FtcUKLmhhqyctpclsq7QF38pKjZHsGNiSQF5r4FtoKDWabFDl3hzaEQMvT1LHEysw5twgLvpYYb4vbw==} + engines: {node: ^10.12.0 || >=12.0.0} + + flatted@3.2.7: + resolution: {integrity: sha512-5nqDSxl8nn5BSNxyR3n4I6eDmbolI6WT+QqR547RwxQapgjQBmtktdP+HTBb/a/zLsbzERTONyUB5pefh5TtjQ==} + + flatted@3.3.1: + resolution: {integrity: sha512-X8cqMLLie7KsNUDSdzeN8FYK9rEt4Dt67OsG/DNGnYTSDBG4uFAJFBnUeiV+zCVAvwFy56IjM9sH51jVaEhNxw==} + + follow-redirects@1.15.6: + resolution: {integrity: sha512-wWN62YITEaOpSK584EZXJafH1AGpO8RVgElfkuXbTOrPX4fIfOyEpW/CsiNd8JdYrAoOvafRTOEnvsO++qCqFA==} + engines: {node: '>=4.0'} + peerDependencies: + debug: '*' + peerDependenciesMeta: + debug: + optional: true + + for-each@0.3.3: + resolution: {integrity: sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw==} + + foreground-child@3.1.1: + resolution: {integrity: sha512-TMKDUnIte6bfb5nWv7V/caI169OHgvwjb7V4WkeUvbQQdjr5rWKqHFiKWb/fcOwB+CzBT+qbWjvj+DVwRskpIg==} + engines: {node: '>=14'} + + form-data-encoder@2.1.4: + resolution: {integrity: sha512-yDYSgNMraqvnxiEXO4hi88+YZxaHC6QKzb5N84iRCTDeRO7ZALpir/lVmf/uXUhnwUr2O4HU8s/n6x+yNjQkHw==} + engines: {node: '>= 14.17'} + + form-data-encoder@4.0.2: + resolution: {integrity: sha512-KQVhvhK8ZkWzxKxOr56CPulAhH3dobtuQ4+hNQ+HekH/Wp5gSOafqRAeTphQUJAIk0GBvHZgJ2ZGRWd5kphMuw==} + engines: {node: '>= 18'} + + form-data@2.5.1: + resolution: {integrity: sha512-m21N3WOmEEURgk6B9GLOE4RuWOFf28Lhh9qGYeNlGq4VDXUlJy2th2slBNU8Gp8EzloYZOibZJ7t5ecIrFSjVA==} + engines: {node: '>= 0.12'} + + form-data@3.0.1: + resolution: {integrity: sha512-RHkBKtLWUVwd7SqRIvCZMEvAMoGUp0XU+seQiZejj0COz3RI3hWP4sCv3gZWWLjJTd7rGwcsF5eKZGii0r/hbg==} + engines: {node: '>= 6'} + + form-data@4.0.0: + resolution: {integrity: sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==} + engines: {node: '>= 6'} + + format@0.2.2: + resolution: {integrity: sha1-1hcBB+nv3E7TDJ3DkBbflCtctYs=} + engines: {node: '>=0.4.x'} + + formidable@3.5.1: + resolution: {integrity: sha512-WJWKelbRHN41m5dumb0/k8TeAx7Id/y3a+Z7QfhxP/htI9Js5zYaEDtG8uMgG0vM0lOlqnmjE99/kfpOYi/0Og==} + + fresh@0.5.2: + resolution: {integrity: sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac=} + engines: {node: '>= 0.6'} + + fs-exists-sync@0.1.0: + resolution: {integrity: sha512-cR/vflFyPZtrN6b38ZyWxpWdhlXrzZEBawlpBQMq7033xVY7/kg0GDMBK5jg8lDYQckdJ5x/YC88lM3C7VMsLg==} + engines: {node: '>=0.10.0'} + + fs-extra@7.0.1: + resolution: {integrity: sha512-YJDaCJZEnBmcbw13fvdAM9AwNOJwOzrE4pqMqBq5nFiEqXUqHwlK4B+3pUw6JNvfSPtX05xFHtYy/1ni01eGCw==} + engines: {node: '>=6 <7 || >=8'} + + fs-extra@8.1.0: + resolution: {integrity: sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==} + engines: {node: '>=6 <7 || >=8'} + + fs.realpath@1.0.0: + resolution: {integrity: sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==} + + fsevents@2.3.3: + resolution: {integrity: sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==} + engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0} + os: [darwin] + + function-bind@1.1.1: + resolution: {integrity: sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==} + + function-bind@1.1.2: + resolution: {integrity: sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==} + + function.prototype.name@1.1.5: + resolution: {integrity: sha512-uN7m/BzVKQnCUF/iW8jYea67v++2u7m5UgENbHRtdDVclOUP+FMPlCNdmk0h/ysGyo2tavMJEDqJAkJdRa1vMA==} + engines: {node: '>= 0.4'} + + function.prototype.name@1.1.6: + resolution: {integrity: sha512-Z5kx79swU5P27WEayXM1tBi5Ze/lbIyiNgU3qyXUOf9b2rgXYyF9Dy9Cx+IQv/Lc8WCG6L82zwUPpSS9hGehIg==} + engines: {node: '>= 0.4'} + + functions-have-names@1.2.3: + resolution: {integrity: sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ==} + + gaxios@6.1.1: + resolution: {integrity: sha512-bw8smrX+XlAoo9o1JAksBwX+hi/RG15J+NTSxmNPIclKC3ZVK6C2afwY8OSdRvOK0+ZLecUJYtj2MmjOt3Dm0w==} + engines: {node: '>=14'} + + gcp-metadata@6.1.0: + resolution: {integrity: sha512-Jh/AIwwgaxan+7ZUUmRLCjtchyDiqh4KjBJ5tW3plBZb5iL/BPcso8A5DlzeD9qlw0duCamnNdpFjxwaT0KyKg==} + engines: {node: '>=14'} + + generic-names@4.0.0: + resolution: {integrity: sha512-ySFolZQfw9FoDb3ed9d80Cm9f0+r7qj+HJkWjeD9RBfpxEVTlVhol+gvaQB/78WbwYfbnNh8nWHHBSlg072y6A==} + + generic-pool@3.9.0: + resolution: {integrity: sha512-hymDOu5B53XvN4QT9dBmZxPX4CWhBPPLguTZ9MMFeFa/Kg0xWVfylOVNlJji/E7yTZWFd/q9GO5TxDLq156D7g==} + engines: {node: '>= 4'} + + gensync@1.0.0-beta.2: + resolution: {integrity: sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==} + engines: {node: '>=6.9.0'} + + get-caller-file@2.0.5: + resolution: {integrity: sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==} + engines: {node: 6.* || 8.* || >= 10.*} + + get-east-asian-width@1.2.0: + resolution: {integrity: sha512-2nk+7SIVb14QrgXFHcm84tD4bKQz0RxPuMT8Ag5KPOq7J5fEmAg0UbXdTOSHqNuHSU28k55qnceesxXRZGzKWA==} + engines: {node: '>=18'} + + get-func-name@2.0.2: + resolution: {integrity: sha512-8vXOvuE167CtIc3OyItco7N/dpRtBbYOsPsXCz7X/PMnlGjYjSGuZJgM1Y7mmew7BKf9BqvLX2tnOVy1BBUsxQ==} + + get-intrinsic@1.2.4: + resolution: {integrity: sha512-5uYhsJH8VJBTv7oslg4BznJYhDoRI6waYCxMmCdnTrcCrHA/fCFKoTFz2JKKE0HdDFUF7/oQuhzumXJK7paBRQ==} + engines: {node: '>= 0.4'} + + get-package-type@0.1.0: + resolution: {integrity: sha512-pjzuKtY64GYfWizNAJ0fr9VqttZkNiK2iS430LtIHzjBEr6bX8Am2zm4sW4Ro5wjWW5cAlRL1qAMTcXbjNAO2Q==} + engines: {node: '>=8.0.0'} + + get-port@4.2.0: + resolution: {integrity: sha512-/b3jarXkH8KJoOMQc3uVGHASwGLPq3gSFJ7tgJm2diza+bydJPTGOibin2steecKeOylE8oY2JERlVWkAJO6yw==} + engines: {node: '>=6'} + + get-set-props@0.1.0: + resolution: {integrity: sha512-7oKuKzAGKj0ag+eWZwcGw2fjiZ78tXnXQoBgY0aU7ZOxTu4bB7hSuQSDgtKy978EDH062P5FmD2EWiDpQS9K9Q==} + engines: {node: '>=0.10.0'} + + get-stack-trace@2.1.1: + resolution: {integrity: sha512-dhqSDD9lHU/6FvIZ9KbXGmVK6IKr9ZskZtNOUvhlCiONlnqatu4FmAeRbxCfJJVuQ0NWfz6dAbibKQg19B7AmQ==} + engines: {node: '>=8.0'} + + get-stream@5.2.0: + resolution: {integrity: sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==} + engines: {node: '>=8'} + + get-stream@6.0.1: + resolution: {integrity: sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==} + engines: {node: '>=10'} + + get-stream@8.0.1: + resolution: {integrity: sha512-VaUJspBffn/LMCJVoMvSAdmscJyS1auj5Zulnn5UoYcY531UWmdwhRWkcGKnGU93m5HSXP9LP2usOryrBtQowA==} + engines: {node: '>=16'} + + get-symbol-description@1.0.0: + resolution: {integrity: sha512-2EmdH1YvIQiZpltCNgkuiUnyukzxM/R6NDJX31Ke3BG1Nq5b0S2PhX59UKi9vZpPDQVdqn+1IcaAwnzTT5vCjw==} + engines: {node: '>= 0.4'} + + get-symbol-description@1.0.2: + resolution: {integrity: sha512-g0QYk1dZBxGwk+Ngc+ltRH2IBp2f7zBkBMBJZCDerh6EhlhSR6+9irMCuT/09zD6qkarHUSn529sK/yL4S27mg==} + engines: {node: '>= 0.4'} + + get-tsconfig@4.7.3: + resolution: {integrity: sha512-ZvkrzoUA0PQZM6fy6+/Hce561s+faD1rsNwhnO5FelNjyy7EMGJ3Rz1AQ8GYDWjhRs/7dBLOEJvhK8MiEJOAFg==} + + get-uri@6.0.1: + resolution: {integrity: sha512-7ZqONUVqaabogsYNWlYj0t3YZaL6dhuEueZXGF+/YVmf6dHmaFg8/6psJKqhx9QykIDKzpGcy2cn4oV4YC7V/Q==} + engines: {node: '>= 14'} + + git-raw-commits@4.0.0: + resolution: {integrity: sha512-ICsMM1Wk8xSGMowkOmPrzo2Fgmfo4bMHLNX6ytHjajRJUqvHOw/TFapQ+QG75c3X/tTDDhOSRPGC52dDbNM8FQ==} + engines: {node: '>=16'} + hasBin: true + + glob-parent@5.1.2: + resolution: {integrity: sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==} + engines: {node: '>= 6'} + + glob-parent@6.0.2: + resolution: {integrity: sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==} + engines: {node: '>=10.13.0'} + + glob@10.3.12: + resolution: {integrity: sha512-TCNv8vJ+xz4QiqTpfOJA7HvYv+tNIRHKfUWw/q+v2jdgN4ebz+KY9tGx5J4rHP0o84mNP+ApH66HRX8us3Khqg==} + engines: {node: '>=16 || 14 >=14.17'} + hasBin: true + + glob@7.2.3: + resolution: {integrity: sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==} + + glob@8.1.0: + resolution: {integrity: sha512-r8hpEjiQEYlF2QU0df3dS+nxxSIreXQS1qRhMJM0Q5NDdR386C7jb7Hwwod8Fgiuex+k0GFjgft18yvxm5XoCQ==} + engines: {node: '>=12'} + + global-directory@4.0.1: + resolution: {integrity: sha512-wHTUcDUoZ1H5/0iVqEudYW4/kAlN5cZ3j/bXn0Dpbizl9iaUVeWSHqiOjsgk6OW2bkLclbBjzewBz6weQ1zA2Q==} + engines: {node: '>=18'} + + global-modules@0.2.3: + resolution: {integrity: sha512-JeXuCbvYzYXcwE6acL9V2bAOeSIGl4dD+iwLY9iUx2VBJJ80R18HCn+JCwHM9Oegdfya3lEkGCdaRkSyc10hDA==} + engines: {node: '>=0.10.0'} + + global-modules@2.0.0: + resolution: {integrity: sha512-NGbfmJBp9x8IxyJSd1P+otYK8vonoJactOogrVfFRIAEY1ukil8RSKDz2Yo7wh1oihl51l/r6W4epkeKJHqL8A==} + engines: {node: '>=6'} + + global-prefix@0.1.5: + resolution: {integrity: sha512-gOPiyxcD9dJGCEArAhF4Hd0BAqvAe/JzERP7tYumE4yIkmIedPUVXcJFWbV3/p/ovIIvKjkrTk+f1UVkq7vvbw==} + engines: {node: '>=0.10.0'} + + global-prefix@3.0.0: + resolution: {integrity: sha512-awConJSVCHVGND6x3tmMaKcQvwXLhjdkmomy2W+Goaui8YPgYgXJZewhg3fWC+DlfqqQuWg8AwqjGTD2nAPVWg==} + engines: {node: '>=6'} + + globals@11.12.0: + resolution: {integrity: sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==} + engines: {node: '>=4'} + + globals@13.20.0: + resolution: {integrity: sha512-Qg5QtVkCy/kv3FUSlu4ukeZDVf9ee0iXLAUYX13gbR17bnejFTzr4iS9bY7kwCf1NztRNm1t91fjOiyx4CSwPQ==} + engines: {node: '>=8'} + + globals@14.0.0: + resolution: {integrity: sha512-oahGvuMGQlPw/ivIYBjVSrWAfWLBeku5tpPE2fOPLi+WHffIWbuh2tCjhyQhTBPMf5E9jDEH4FOmTYgYwbKwtQ==} + engines: {node: '>=18'} + + globalthis@1.0.2: + resolution: {integrity: sha512-ZQnSFO1la8P7auIOQECnm0sSuoMeaSq0EEdXMBFF2QJO4uNcwbyhSgG3MruWNbFTqCLmxVwGOl7LZ9kASvHdeQ==} + engines: {node: '>= 0.4'} + + globalthis@1.0.3: + resolution: {integrity: sha512-sFdI5LyBiNTHjRd7cGPWapiHWMOXKyuBNX/cWJ3NfzrZQVa8GI/8cofCl74AOVqq9W5kNmguTIzJ/1s2gyI9wA==} + engines: {node: '>= 0.4'} + + globby@11.1.0: + resolution: {integrity: sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==} + engines: {node: '>=10'} + + globjoin@0.1.4: + resolution: {integrity: sha512-xYfnw62CKG8nLkZBfWbhWwDw02CHty86jfPcc2cr3ZfeuK9ysoVPPEUxf21bAD/rWAgk52SuBrLJlefNy8mvFg==} + + goober@2.1.8: + resolution: {integrity: sha512-S0C85gCzcfFCMSdjD/CxyQMt1rbf2qEg6hmDzxk2FfD7+7Ogk55m8ZFUMtqNaZM4VVX/qaU9AzSORG+Gf4ZpAQ==} + peerDependencies: + csstype: ^3.0.10 + + google-auth-library@9.8.0: + resolution: {integrity: sha512-TJJXFzMlVGRlIH27gYZ6XXyPf5Y3OItsKFfefsDAafNNywYRTkei83nEO29IrYj8GtdHWU78YnW+YZdaZaXIJA==} + engines: {node: '>=14'} + + gopd@1.0.1: + resolution: {integrity: sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==} + + got@13.0.0: + resolution: {integrity: sha512-XfBk1CxOOScDcMr9O1yKkNaQyy865NbYs+F7dr4H0LZMVgCj2Le59k6PqbNHoL5ToeaEQUYh6c6yMfVcc6SJxA==} + engines: {node: '>=16'} + + got@14.0.0: + resolution: {integrity: sha512-X01vTgaX9SwaMq5DfImvS+3GMQFFs5HtrrlS9CuzUSzkxAf/tWGEyynuI+Qy7BjciMczZGjyVSmawYbP4eYhYA==} + engines: {node: '>=20'} + + graceful-fs@4.2.10: + resolution: {integrity: sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA==} + + graceful-fs@4.2.11: + resolution: {integrity: sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==} + + grapheme-splitter@1.0.4: + resolution: {integrity: sha512-bzh50DW9kTPM00T8y4o8vQg89Di9oLJVLW/KaOGIXJWP/iqCN6WKYkbNOF04vFLJhwcpYUh9ydh/+5vpOqV4YQ==} + + graphemer@1.4.0: + resolution: {integrity: sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==} + + gtoken@7.0.1: + resolution: {integrity: sha512-KcFVtoP1CVFtQu0aSk3AyAt2og66PFhZAlkUOuWKwzMLoulHXG5W5wE5xAnHb+yl3/wEFoqGW7/cDGMU8igDZQ==} + engines: {node: '>=14.0.0'} + + gzip-size@7.0.0: + resolution: {integrity: sha512-O1Ld7Dr+nqPnmGpdhzLmMTQ4vAsD+rHwMm1NLUmoUFFymBOMKxCCrtDxqdBRYXdeEPEi3SyoR4TizJLQrnKBNA==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + + hard-rejection@2.1.0: + resolution: {integrity: sha512-VIZB+ibDhx7ObhAe7OVtoEbuP4h/MuOTHJ+J8h/eBXotJYl0fBgR72xDFCKgIh22OJZIOVNxBMWuhAr10r8HdA==} + engines: {node: '>=6'} + + harmony-reflect@1.6.2: + resolution: {integrity: sha512-HIp/n38R9kQjDEziXyDTuW3vvoxxyxjxFzXLrBr18uB47GnSt+G9D29fqrpM5ZkspMcPICud3XsBJQ4Y2URg8g==} + + has-bigints@1.0.2: + resolution: {integrity: sha512-tSvCKtBr9lkF0Ex0aQiP9N+OpV4zi2r/Nee5VkRDbaqv35RLYMzbwQfFSZZH0kR+Rd6302UJZ2p/bJCEoR3VoQ==} + + has-flag@3.0.0: + resolution: {integrity: sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==} + engines: {node: '>=4'} + + has-flag@4.0.0: + resolution: {integrity: sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==} + engines: {node: '>=8'} + + has-property-descriptors@1.0.0: + resolution: {integrity: sha512-62DVLZGoiEBDHQyqG4w9xCuZ7eJEwNmJRWw2VY84Oedb7WFcA27fiEVe8oUQx9hAUJ4ekurquucTGwsyO1XGdQ==} + + has-property-descriptors@1.0.2: + resolution: {integrity: sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==} + + has-proto@1.0.3: + resolution: {integrity: sha512-SJ1amZAJUiZS+PhsVLf5tGydlaVB8EdFpaSO4gmiUKUOxk8qzn5AIy4ZeJUmh22znIdk/uMAUT2pl3FxzVUH+Q==} + engines: {node: '>= 0.4'} + + has-symbols@1.0.3: + resolution: {integrity: sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==} + engines: {node: '>= 0.4'} + + has-tostringtag@1.0.0: + resolution: {integrity: sha512-kFjcSNhnlGV1kyoGk7OXKSawH5JOb/LzUc5w9B02hOTO0dfFRjbHQKvg1d6cf3HbeUmtU9VbbV3qzZ2Teh97WQ==} + engines: {node: '>= 0.4'} + + has-tostringtag@1.0.2: + resolution: {integrity: sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==} + engines: {node: '>= 0.4'} + + has@1.0.3: + resolution: {integrity: sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==} + engines: {node: '>= 0.4.0'} + + hash-wasm@4.9.0: + resolution: {integrity: sha512-7SW7ejyfnRxuOc7ptQHSf4LDoZaWOivfzqw+5rpcQku0nHfmicPKE51ra9BiRLAmT8+gGLestr1XroUkqdjL6w==} + + hasown@2.0.2: + resolution: {integrity: sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==} + engines: {node: '>= 0.4'} + + hast-to-hyperscript@9.0.1: + resolution: {integrity: sha512-zQgLKqF+O2F72S1aa4y2ivxzSlko3MAvxkwG8ehGmNiqd98BIN3JM1rAJPmplEyLmGLO2QZYJtIneOSZ2YbJuA==} + + hast-util-from-parse5@6.0.1: + resolution: {integrity: sha512-jeJUWiN5pSxW12Rh01smtVkZgZr33wBokLzKLwinYOUfSzm1Nl/c3GUGebDyOKjdsRgMvoVbV0VpAcpjF4NrJA==} + + hast-util-parse-selector@2.2.5: + resolution: {integrity: sha512-7j6mrk/qqkSehsM92wQjdIgWM2/BW61u/53G6xmC8i1OmEdKLHbk419QKQUjz6LglWsfqoiHmyMRkP1BGjecNQ==} + + hast-util-raw@6.0.1: + resolution: {integrity: sha512-ZMuiYA+UF7BXBtsTBNcLBF5HzXzkyE6MLzJnL605LKE8GJylNjGc4jjxazAHUtcwT5/CEt6afRKViYB4X66dig==} + + hast-util-to-jsx-runtime@2.2.0: + resolution: {integrity: sha512-wSlp23N45CMjDg/BPW8zvhEi3R+8eRE1qFbjEyAUzMCzu2l1Wzwakq+Tlia9nkCtEl5mDxa7nKHsvYJ6Gfn21A==} + + hast-util-to-parse5@6.0.0: + resolution: {integrity: sha512-Lu5m6Lgm/fWuz8eWnrKezHtVY83JeRGaNQ2kn9aJgqaxvVkFCZQBEhgodZUDUvoodgyROHDb3r5IxAEdl6suJQ==} + + hast-util-whitespace@3.0.0: + resolution: {integrity: sha512-88JUN06ipLwsnv+dVn+OIYOvAuvBMy/Qoi6O7mQHxdPXpjy+Cd6xRkWwux7DKO+4sYILtLBRIKgsdpS2gQc7qw==} + + hastscript@6.0.0: + resolution: {integrity: sha512-nDM6bvd7lIqDUiYEiu5Sl/+6ReP0BMk/2f4U/Rooccxkj0P5nm+acM5PrGJ/t5I8qPGiqZSE6hVAwZEdZIvP4w==} + + helmet@7.0.0: + resolution: {integrity: sha512-MsIgYmdBh460ZZ8cJC81q4XJknjG567wzEmv46WOBblDb6TUd3z8/GhgmsM9pn8g2B80tAJ4m5/d3Bi1KrSUBQ==} + engines: {node: '>=16.0.0'} + + hexoid@1.0.0: + resolution: {integrity: sha512-QFLV0taWQOZtvIRIAdBChesmogZrtuXvVWsFHZTk2SU+anspqZ2vMnoLg7IE1+Uk16N19APic1BuF8bC8c2m5g==} + engines: {node: '>=8'} + + highlight.js@10.7.3: + resolution: {integrity: sha512-tzcUFauisWKNHaRkN4Wjl/ZA07gENAjFl3J/c480dprkGTg5EQstgaNFqBfUqCq54kZRIEcreTsAgF/m2quD7A==} + + history@5.3.0: + resolution: {integrity: sha512-ZqaKwjjrAYUYfLG+htGaIIZ4nioX2L70ZUMIFysS3xvBsSG4x/n1V6TXV3N8ZYNuFGlDirFg32T7B6WOUPDYcQ==} + + hoist-non-react-statics@3.3.2: + resolution: {integrity: sha512-/gGivxi8JPKWNm/W0jSmzcMPpfpPLc3dY/6GxhX2hQ9iGj3aDfklV4ET7NjKpSinLpJ5vafa9iiGIEZg10SfBw==} + + homedir-polyfill@1.0.3: + resolution: {integrity: sha512-eSmmWE5bZTK2Nou4g0AI3zZ9rswp7GRKoKXS1BLUkvPviOqs4YTN1djQIqrXy9k5gEtdLPy86JjRwsNM9tnDcA==} + engines: {node: '>=0.10.0'} + + hosted-git-info@2.8.9: + resolution: {integrity: sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw==} + + hosted-git-info@4.1.0: + resolution: {integrity: sha512-kyCuEOWjJqZuDbRHzL8V93NzQhwIB71oFWSyzVo+KPZI+pnQPPxucdkrOZvkLRnrf5URsQM+IJ09Dw29cRALIA==} + engines: {node: '>=10'} + + hpagent@1.2.0: + resolution: {integrity: sha512-A91dYTeIB6NoXG+PxTQpCCDDnfHsW9kc06Lvpu1TEe9gnd6ZFeiBoRO9JvzEv6xK7EX97/dUE8g/vBMTqTS3CA==} + engines: {node: '>=14'} + + html-encoding-sniffer@3.0.0: + resolution: {integrity: sha512-oWv4T4yJ52iKrufjnyZPkrN0CH3QnrUqdB6In1g5Fe1mia8GmF36gnfNySxoZtxD5+NmYw1EElVXiBk93UeskA==} + engines: {node: '>=12'} + + html-escaper@2.0.2: + resolution: {integrity: sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==} + + html-parse-stringify@3.0.1: + resolution: {integrity: sha512-KknJ50kTInJ7qIScF3jeaFRpMpE8/lfiTdzf/twXyPBLAGrLRTmkz3AdTnKeh40X8k9L2fdYwEp/42WGXIRGcg==} + + html-tags@3.3.1: + resolution: {integrity: sha512-ztqyC3kLto0e9WbNp0aeP+M3kTt+nbaIveGmUxAtZa+8iFgKLUOD4YKM5j+f3QD89bra7UeumolZHKuOXnTmeQ==} + engines: {node: '>=8'} + + html-url-attributes@3.0.0: + resolution: {integrity: sha512-/sXbVCWayk6GDVg3ctOX6nxaVj7So40FcFAnWlWGNAB1LpYKcV5Cd10APjPjW80O7zYW2MsjBV4zZ7IZO5fVow==} + + html-void-elements@1.0.5: + resolution: {integrity: sha512-uE/TxKuyNIcx44cIWnjr/rfIATDH7ZaOMmstu0CwhFG1Dunhlp4OC6/NMbhiwoq5BpW0ubi303qnEk/PZj614w==} + + htmlnano@2.0.3: + resolution: {integrity: sha512-S4PGGj9RbdgW8LhbILNK7W9JhmYP8zmDY7KDV/8eCiJBQJlbmltp5I0gv8c5ntLljfdxxfmJ+UJVSqyH4mb41A==} + peerDependencies: + cssnano: ^5.0.11 + postcss: ^8.3.11 + purgecss: ^5.0.0 + relateurl: ^0.2.7 + srcset: 4.0.0 + svgo: ^2.8.0 + terser: ^5.10.0 + uncss: ^0.17.3 + peerDependenciesMeta: + cssnano: + optional: true + postcss: + optional: true + purgecss: + optional: true + relateurl: + optional: true + srcset: + optional: true + svgo: + optional: true + terser: + optional: true + uncss: + optional: true + + htmlparser2@7.2.0: + resolution: {integrity: sha512-H7MImA4MS6cw7nbyURtLPO1Tms7C5H602LRETv95z1MxO/7CP7rDVROehUYeYBUYEON94NXXDEPmZuq+hX4sog==} + + http-assert@1.5.0: + resolution: {integrity: sha512-uPpH7OKX4H25hBmU6G1jWNaqJGpTXxey+YOUizJUAgu0AjLUeC8D73hTrhvDS5D+GJN1DN1+hhc/eF/wpxtp0w==} + engines: {node: '>= 0.8'} + + http-cache-semantics@4.1.1: + resolution: {integrity: sha512-er295DKPVsV82j5kw1Gjt+ADA/XYHsajl82cGNQG2eyoPkvgUhX+nDIyelzhIWbbsXP39EHcI6l5tYs2FYqYXQ==} + + http-errors@1.4.0: + resolution: {integrity: sha512-oLjPqve1tuOl5aRhv8GK5eHpqP1C9fb+Ol+XTLjKfLltE44zdDbEdjPSbU7Ch5rSNsVFqZn97SrMmZLdu1/YMw==} + engines: {node: '>= 0.6'} + + http-errors@1.6.3: + resolution: {integrity: sha512-lks+lVC8dgGyh97jxvxeYTWQFvh4uw4yC12gVl63Cg30sjPX4wuGcdkICVXDAESr6OJGjqGA8Iz5mkeN6zlD7A==} + engines: {node: '>= 0.6'} + + http-errors@1.8.1: + resolution: {integrity: sha512-Kpk9Sm7NmI+RHhnj6OIWDI1d6fIoFAtFt9RLaTMRlg/8w49juAStsrBgp0Dp4OdxdVbRIeKhtCUvoi/RuAhO4g==} + engines: {node: '>= 0.6'} + + http-errors@2.0.0: + resolution: {integrity: sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==} + engines: {node: '>= 0.8'} + + http-proxy-agent@5.0.0: + resolution: {integrity: sha512-n2hY8YdoRE1i7r6M0w9DIw5GgZN0G25P8zLCRQ8rjXtTU3vsNFBI/vWK/UIeE6g5MUUz6avwAPXmL6Fy9D/90w==} + engines: {node: '>= 6'} + + http-proxy-agent@7.0.2: + resolution: {integrity: sha512-T1gkAiYYDWYx3V5Bmyu7HcfcvL7mUrTWiM6yOfa3PIphViJ/gFPbvidQ+veqSOHci/PxBcDabeUNCzpOODJZig==} + engines: {node: '>= 14'} + + http-proxy@1.18.1: + resolution: {integrity: sha512-7mz/721AbnJwIVbnaSv1Cz3Am0ZLT/UBwkC92VlxhXv/k/BBQfM2fXElQNC27BVGr0uwUpplYPQM9LnaBMR5NQ==} + engines: {node: '>=8.0.0'} + + http2-wrapper@2.2.1: + resolution: {integrity: sha512-V5nVw1PAOgfI3Lmeaj2Exmeg7fenjhRUgz1lPSezy1CuhPYbgQtbQj4jZfEAEMlaL+vupsvhjqCyjzob0yxsmQ==} + engines: {node: '>=10.19.0'} + + https-proxy-agent@5.0.1: + resolution: {integrity: sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA==} + engines: {node: '>= 6'} + + https-proxy-agent@7.0.4: + resolution: {integrity: sha512-wlwpilI7YdjSkWaQ/7omYBMTliDcmCN8OLihO6I9B86g06lMyAoqgoDpV0XqoaPOKj+0DIdAvnsWfyAAhmimcg==} + engines: {node: '>= 14'} + + human-id@1.0.2: + resolution: {integrity: sha512-UNopramDEhHJD+VR+ehk8rOslwSfByxPIZyJRfV739NDhN5LF1fa1MqnzKm2lGTQRjNrjK19Q5fhkgIfjlVUKw==} + + human-signals@2.1.0: + resolution: {integrity: sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==} + engines: {node: '>=10.17.0'} + + human-signals@5.0.0: + resolution: {integrity: sha512-AXcZb6vzzrFAUE61HnN4mpLqd/cSIwNQjtNWR0euPm6y0iqx3G4gOXaIDdtdDwZmhwe82LA6+zinmW4UBWVePQ==} + engines: {node: '>=16.17.0'} + + humanize-number@0.0.2: + resolution: {integrity: sha1-EcCvakcWQ2M1iFiASPF5lUFInBg=} + + husky@9.0.7: + resolution: {integrity: sha512-vWdusw+y12DUEeoZqW1kplOFqk3tedGV8qlga8/SF6a3lOiWLqGZZQvfWvY0fQYdfiRi/u1DFNpudTSV9l1aCg==} + engines: {node: '>=18'} + hasBin: true + + i18next-browser-languagedetector@7.0.1: + resolution: {integrity: sha512-Pa5kFwaczXJAeHE56CHG2aWzFBMJNUNghf0Pm4SwSrEMps/PTKqW90EYWlIvhuYStf3Sn1K0vw+gH3+TLdkH1g==} + + i18next@22.4.15: + resolution: {integrity: sha512-yYudtbFrrmWKLEhl6jvKUYyYunj4bTBCe2qIUYAxbXoPusY7YmdwPvOE6fx6UIfWvmlbCWDItr7wIs8KEBZ5Zg==} + + iconv-lite@0.4.24: + resolution: {integrity: sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==} + engines: {node: '>=0.10.0'} + + iconv-lite@0.6.3: + resolution: {integrity: sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==} + engines: {node: '>=0.10.0'} + + icss-replace-symbols@1.1.0: + resolution: {integrity: sha1-Bupvg2ead0njhs/h/oEq5dsiPe0=} + + icss-utils@5.1.0: + resolution: {integrity: sha512-soFhflCVWLfRNOPU3iv5Z9VUdT44xFRbzjLsEzSr5AQmgqPMTHdU3PMT1Cf1ssx8fLNJDA1juftYl+PUcv3MqA==} + engines: {node: ^10 || ^12 || >= 14} + peerDependencies: + postcss: ^8.1.0 + + identity-obj-proxy@3.0.0: + resolution: {integrity: sha512-00n6YnVHKrinT9t0d9+5yZC6UBNJANpYEQvL2LlX6Ab9lnmxzIRcEmTPuyGScvl1+jKuCICX1Z0Ab1pPKKdikA==} + engines: {node: '>=4'} + + ieee754@1.2.1: + resolution: {integrity: sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==} + + ignore-by-default@1.0.1: + resolution: {integrity: sha512-Ius2VYcGNk7T90CppJqcIkS5ooHUZyIQK+ClZfMfMNFEF9VSE73Fq+906u/CWu92x4gzZMWOwfFYckPObzdEbA==} + + ignore@5.3.1: + resolution: {integrity: sha512-5Fytz/IraMjqpwfd34ke28PTVMjZjJG2MPn5t7OE4eUCUNf8BAa7b5WUS9/Qvr6mwOQS7Mk6vdsMno5he+T8Xw==} + engines: {node: '>= 4'} + + immutable@4.1.0: + resolution: {integrity: sha512-oNkuqVTA8jqG1Q6c+UglTOD1xhC1BtjKI7XkCXRkZHrN5m18/XsnUp8Q89GkQO/z+0WjonSvl0FLhDYftp46nQ==} + + import-fresh@3.3.0: + resolution: {integrity: sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==} + engines: {node: '>=6'} + + import-in-the-middle@1.4.2: + resolution: {integrity: sha512-9WOz1Yh/cvO/p69sxRmhyQwrIGGSp7EIdcb+fFNVi7CzQGQB8U1/1XrKVSbEd/GNOAeM0peJtmi7+qphe7NvAw==} + + import-lazy@4.0.0: + resolution: {integrity: sha512-rKtvo6a868b5Hu3heneU+L4yEQ4jYKLtjpnPeUdK7h0yzXGmyBTypknlkCvHFBqfX9YlorEiMM6Dnq/5atfHkw==} + engines: {node: '>=8'} + + import-local@3.1.0: + resolution: {integrity: sha512-ASB07uLtnDs1o6EHjKpX34BKYDSqnFerfTOJL2HvMqF70LnxpjkzDB8J44oT9pu4AMPkQwf8jl6szgvNd2tRIg==} + engines: {node: '>=8'} + hasBin: true + + import-meta-resolve@4.0.0: + resolution: {integrity: sha512-okYUR7ZQPH+efeuMJGlq4f8ubUgO50kByRPyt/Cy1Io4PSRsPjxME+YlVaCOx+NIToW7hCsZNFJyTPFFKepRSA==} + + import-modules@2.1.0: + resolution: {integrity: sha512-8HEWcnkbGpovH9yInoisxaSoIg9Brbul+Ju3Kqe2UsYDUBJD/iQjSgEj0zPcTDPKfPp2fs5xlv1i+JSye/m1/A==} + engines: {node: '>=8'} + + imurmurhash@0.1.4: + resolution: {integrity: sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==} + engines: {node: '>=0.8.19'} + + indent-string@4.0.0: + resolution: {integrity: sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==} + engines: {node: '>=8'} + + indent-string@5.0.0: + resolution: {integrity: sha512-m6FAo/spmsW2Ab2fU35JTYwtOKa2yAwXSwgjSv1TJzh4Mh7mC3lzAOVLBprb72XsTrgkEIsl7YrFNAiDiRhIGg==} + engines: {node: '>=12'} + + inflation@2.0.0: + resolution: {integrity: sha512-m3xv4hJYR2oXw4o4Y5l6P5P16WYmazYof+el6Al3f+YlggGj6qT9kImBAnzDelRALnP5d3h4jGBPKzYCizjZZw==} + engines: {node: '>= 0.8.0'} + + inflight@1.0.6: + resolution: {integrity: sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==} + + inherits@2.0.1: + resolution: {integrity: sha512-8nWq2nLTAwd02jTqJExUYFSD/fKq6VH9Y/oG2accc/kdI0V98Bag8d5a4gi3XHz73rDWa2PvTtvcWYquKqSENA==} + + inherits@2.0.3: + resolution: {integrity: sha512-x00IRNXNy63jwGkJmzPigoySHbaqpNuzKbBOmzK+g2OdZpQ9w+sxCN+VSB3ja7IAge2OP2qpfxTjeNcyjmW1uw==} + + inherits@2.0.4: + resolution: {integrity: sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==} + + ini@1.3.8: + resolution: {integrity: sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==} + + ini@4.1.1: + resolution: {integrity: sha512-QQnnxNyfvmHFIsj7gkPcYymR8Jdw/o7mp5ZFihxn6h8Ci6fh3Dx4E1gPjpQEpIuPo9XVNY/ZUwh4BPMjGyL01g==} + engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} + + inline-style-parser@0.1.1: + resolution: {integrity: sha512-7NXolsK4CAS5+xvdj5OMMbI962hU/wvwoxk+LWR9Ek9bVtyuuYScDN6eS0rUm6TxApFpw7CX1o4uJzcd4AyD3Q==} + + inquirer@9.1.4: + resolution: {integrity: sha512-9hiJxE5gkK/cM2d1mTEnuurGTAoHebbkX0BYl3h7iEg7FYfuNIom+nDfBCSWtvSnoSrWCeBxqqBZu26xdlJlXA==} + engines: {node: '>=12.0.0'} + + internal-slot@1.0.3: + resolution: {integrity: sha512-O0DB1JC/sPyZl7cIo78n5dR7eUSwwpYPiXRhTzNxZVAMUuB8vlnRFyLxdrVToks6XPLVnFfbzaVd5WLjhgg+vA==} + engines: {node: '>= 0.4'} + + internal-slot@1.0.7: + resolution: {integrity: sha512-NGnrKwXzSms2qUUih/ILZ5JBqNTSa1+ZmP6flaIp6KmSElgE9qdndzS3cqjrDovwFdmwsGsLdeFgB6suw+1e9g==} + engines: {node: '>= 0.4'} + + internmap@1.0.1: + resolution: {integrity: sha512-lDB5YccMydFBtasVtxnZ3MRBHuaoE8GKsppq+EchKL2U4nK/DmEpPHNH8MZe5HkMtpSiTSOZwfN0tzYjO/lJEw==} + + ip@1.1.9: + resolution: {integrity: sha512-cyRxvOEpNHNtchU3Ln9KC/auJgup87llfQpQ+t5ghoC/UhL16SWzbueiCsdTnWmqAWl7LadfuwhlqmtOaqMHdQ==} + + ip@2.0.1: + resolution: {integrity: sha512-lJUL9imLTNi1ZfXT+DU6rBBdbiKGBuay9B6xGSPVjUeQwaH1RIGqef8RZkUtHioLmSNpPR5M4HVKJGm1j8FWVQ==} + + ipaddr.js@2.1.0: + resolution: {integrity: sha512-LlbxQ7xKzfBusov6UMi4MFpEg0m+mAm9xyNGEduwXMEDuf4WfzB/RZwMVYEd7IKGvh4IUkEXYxtAVu9T3OelJQ==} + engines: {node: '>= 10'} + + is-alphabetical@1.0.4: + resolution: {integrity: sha512-DwzsA04LQ10FHTZuL0/grVDk4rFoVH1pjAToYwBrHSxcrBIGQuXrQMtD5U1b0U2XVgKZCTLLP8u2Qxqhy3l2Vg==} + + is-alphanumerical@1.0.4: + resolution: {integrity: sha512-UzoZUr+XfVz3t3v4KyGEniVL9BDRoQtY7tOyrRybkVNjDFWyo1yhXNGrrBTQxp3ib9BLAWs7k2YKBQsFRkZG9A==} + + is-array-buffer@3.0.4: + resolution: {integrity: sha512-wcjaerHw0ydZwfhiKbXJWLDY8A7yV7KhjQOpb83hGgGfId/aQa4TOvwyzn2PuswW2gPCYEL/nEAiSVpdOj1lXw==} + engines: {node: '>= 0.4'} + + is-arrayish@0.2.1: + resolution: {integrity: sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==} + + is-arrayish@0.3.2: + resolution: {integrity: sha512-eVRqCvVlZbuw3GrM63ovNSNAeA1K16kaR/LRY/92w0zxQ5/1YzwblUX652i4Xs9RwAGjW9d9y6X88t8OaAJfWQ==} + + is-async-function@2.0.0: + resolution: {integrity: sha512-Y1JXKrfykRJGdlDwdKlLpLyMIiWqWvuSd17TvZk68PLAOGOoF4Xyav1z0Xhoi+gCYjZVeC5SI+hYFOfvXmGRCA==} + engines: {node: '>= 0.4'} + + is-bigint@1.0.4: + resolution: {integrity: sha512-zB9CruMamjym81i2JZ3UMn54PKGsQzsJeo6xvN3HJJ4CAsQNB6iRutp2To77OfCNuoxspsIhzaPoO1zyCEhFOg==} + + is-binary-path@2.1.0: + resolution: {integrity: sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==} + engines: {node: '>=8'} + + is-boolean-object@1.1.2: + resolution: {integrity: sha512-gDYaKHJmnj4aWxyj6YHyXVpdQawtVLHU5cb+eztPGczf6cjuTdwve5ZIEfgXqH4e57An1D1AKf8CZ3kYrQRqYA==} + engines: {node: '>= 0.4'} + + is-buffer@2.0.5: + resolution: {integrity: sha512-i2R6zNFDwgEHJyQUtJEk0XFi1i0dPFn/oqjK3/vPCcDeJvW5NQ83V8QbicfF1SupOaB0h8ntgBC2YiE7dfyctQ==} + engines: {node: '>=4'} + + is-builtin-module@3.2.1: + resolution: {integrity: sha512-BSLE3HnV2syZ0FK0iMA/yUGplUeMmNz4AW5fnTunbCIqZi4vG3WjJT9FHMy5D69xmAYBHXQhJdALdpwVxV501A==} + engines: {node: '>=6'} + + is-callable@1.2.7: + resolution: {integrity: sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==} + engines: {node: '>= 0.4'} + + is-ci@3.0.1: + resolution: {integrity: sha512-ZYvCgrefwqoQ6yTyYUbQu64HsITZ3NfKX1lzaEYdkTDcfKzzCI/wthRRYKkdjHKFVgNiXKAKm65Zo1pk2as/QQ==} + hasBin: true + + is-core-module@2.12.1: + resolution: {integrity: sha512-Q4ZuBAe2FUsKtyQJoQHlvP8OvBERxO3jEmy1I7hcRXcJBGGHFh/aJBswbXuS9sgrDH2QUO8ilkwNPHvHMd8clg==} + + is-core-module@2.13.1: + resolution: {integrity: sha512-hHrIjvZsftOsvKSn2TRYl63zvxsgE0K+0mYMoH6gD4omR5IWB2KynivBQczo3+wF1cCkjzvptnI9Q0sPU66ilw==} + + is-data-view@1.0.1: + resolution: {integrity: sha512-AHkaJrsUVW6wq6JS8y3JnM/GJF/9cf+k20+iDzlSaJrinEo5+7vRiteOSwBhHRiAyQATN1AmY4hwzxJKPmYf+w==} + engines: {node: '>= 0.4'} + + is-date-object@1.0.5: + resolution: {integrity: sha512-9YQaSxsAiSwcvS33MBk3wTCVnWK+HhF8VZR2jRxehM16QcVOdHqPn4VPHmRK4lSr38n9JriurInLcP90xsYNfQ==} + engines: {node: '>= 0.4'} + + is-decimal@1.0.4: + resolution: {integrity: sha512-RGdriMmQQvZ2aqaQq3awNA6dCGtKpiDFcOzrTWrDAT2MiWrKQVPmxLGHl7Y2nNu6led0kEyoX0enY0qXYsv9zw==} + + is-extglob@2.1.1: + resolution: {integrity: sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==} + engines: {node: '>=0.10.0'} + + is-finalizationregistry@1.0.2: + resolution: {integrity: sha512-0by5vtUJs8iFQb5TYUHHPudOR+qXYIMKtiUzvLIZITZUjknFmziyBJuLhVRc+Ds0dREFlskDNJKYIdIzu/9pfw==} + + is-fullwidth-code-point@3.0.0: + resolution: {integrity: sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==} + engines: {node: '>=8'} + + is-fullwidth-code-point@4.0.0: + resolution: {integrity: sha512-O4L094N2/dZ7xqVdrXhh9r1KODPJpFms8B5sGdJLPy664AgvXsreZUyCQQNItZRDlYug4xStLjNp/sz3HvBowQ==} + engines: {node: '>=12'} + + is-generator-fn@2.1.0: + resolution: {integrity: sha512-cTIB4yPYL/Grw0EaSzASzg6bBy9gqCofvWN8okThAYIxKJZC+udlRAmGbM0XLeniEJSs8uEgHPGuHSe1XsOLSQ==} + engines: {node: '>=6'} + + is-generator-function@1.0.10: + resolution: {integrity: sha512-jsEjy9l3yiXEQ+PsXdmBwEPcOxaXWLspKdplFUVI9vq1iZgIekeC0L167qeu86czQaxed3q/Uzuw0swL0irL8A==} + engines: {node: '>= 0.4'} + + is-get-set-prop@1.0.0: + resolution: {integrity: sha512-DvAYZ1ZgGUz4lzxKMPYlt08qAUqyG9ckSg2pIjfvcQ7+pkVNUHk8yVLXOnCLe5WKXhLop8oorWFBJHpwWQpszQ==} + + is-glob@4.0.3: + resolution: {integrity: sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==} + engines: {node: '>=0.10.0'} + + is-hexadecimal@1.0.4: + resolution: {integrity: sha512-gyPJuv83bHMpocVYoqof5VDiZveEoGoFL8m3BXNb2VW8Xs+rz9kqO8LOQ5DH6EsuvilT1ApazU0pyl+ytbPtlw==} + + is-interactive@2.0.0: + resolution: {integrity: sha512-qP1vozQRI+BMOPcjFzrjXuQvdak2pHNUMZoeG2eRbiSqyvbEf/wQtEOTOX1guk6E3t36RkaqiSt8A/6YElNxLQ==} + engines: {node: '>=12'} + + is-js-type@2.0.0: + resolution: {integrity: sha512-Aj13l47+uyTjlQNHtXBV8Cji3jb037vxwMWCgopRR8h6xocgBGW3qG8qGlIOEmbXQtkKShKuBM9e8AA1OeQ+xw==} + + is-json@2.0.1: + resolution: {integrity: sha512-6BEnpVn1rcf3ngfmViLM6vjUjGErbdrL4rwlv+u1NO1XO8kqT4YGL8+19Q+Z/bas8tY90BTWMk2+fW1g6hQjbA==} + + is-map@2.0.3: + resolution: {integrity: sha512-1Qed0/Hr2m+YqxnM09CjA2d/i6YZNfF6R2oRAOj36eUdS6qIV/huPJNSEpKbupewFs+ZsJlxsjjPbc0/afW6Lw==} + engines: {node: '>= 0.4'} + + is-module@1.0.0: + resolution: {integrity: sha512-51ypPSPCoTEIN9dy5Oy+h4pShgJmPCygKfyRCISBI+JoWT/2oJvK8QPxmwv7b/p239jXrm9M1mlQbyKJ5A152g==} + + is-negative-zero@2.0.2: + resolution: {integrity: sha512-dqJvarLawXsFbNDeJW7zAz8ItJ9cd28YufuuFzh0G8pNHjJMnY08Dv7sYX2uF5UpQOwieAeOExEYAWWfu7ZZUA==} + engines: {node: '>= 0.4'} + + is-negative-zero@2.0.3: + resolution: {integrity: sha512-5KoIu2Ngpyek75jXodFvnafB6DJgr3u8uuK0LEZJjrU19DrMD3EVERaR8sjz8CCGgpZvxPl9SuE1GMVPFHx1mw==} + engines: {node: '>= 0.4'} + + is-number-object@1.0.7: + resolution: {integrity: sha512-k1U0IRzLMo7ZlYIfzRu23Oh6MiIFasgpb9X76eqfFZAqwH44UI4KTBvBYIZ1dSL9ZzChTB9ShHfLkR4pdW5krQ==} + engines: {node: '>= 0.4'} + + is-number@7.0.0: + resolution: {integrity: sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==} + engines: {node: '>=0.12.0'} + + is-obj-prop@1.0.0: + resolution: {integrity: sha512-5Idb61slRlJlsAzi0Wsfwbp+zZY+9LXKUAZpvT/1ySw+NxKLRWfa0Bzj+wXI3fX5O9hiddm5c3DAaRSNP/yl2w==} + + is-obj@2.0.0: + resolution: {integrity: sha512-drqDG3cbczxxEJRoOXcOjtdp1J/lyp1mNn0xaznRs8+muBhgQcrnbspox5X5fOw0HnMnbfDzvnEMEtqDEJEo8w==} + engines: {node: '>=8'} + + is-path-inside@3.0.3: + resolution: {integrity: sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==} + engines: {node: '>=8'} + + is-plain-obj@1.1.0: + resolution: {integrity: sha512-yvkRyxmFKEOQ4pNXCmJG5AEQNlXJS5LaONXo5/cLdTZdWvsZ1ioJEonLGAosKlMWE8lwUy/bJzMjcw8az73+Fg==} + engines: {node: '>=0.10.0'} + + is-plain-obj@2.1.0: + resolution: {integrity: sha512-YWnfyRwxL/+SsrWYfOpUtz5b3YD+nyfkHvjbcanzk8zgyO4ASD67uVMRt8k5bM4lLMDnXfriRhOpemw+NfT1eA==} + engines: {node: '>=8'} + + is-plain-obj@4.1.0: + resolution: {integrity: sha512-+Pgi+vMuUNkJyExiMBt5IlFoMyKnr5zhJ4Uspz58WOhBF5QoIZkFyNHIbBAtHwzVAgk5RtndVNsDRN61/mmDqg==} + engines: {node: '>=12'} + + is-plain-object@5.0.0: + resolution: {integrity: sha512-VRSzKkbMm5jMDoKLbltAkFQ5Qr7VDiTFGXxYFXXowVj387GeGNOCsOH6Msy00SGZ3Fp84b1Naa1psqgcCIEP5Q==} + engines: {node: '>=0.10.0'} + + is-potential-custom-element-name@1.0.1: + resolution: {integrity: sha512-bCYeRA2rVibKZd+s2625gGnGF/t7DSqDs4dP7CrLA1m7jKWz6pps0LpYLJN8Q64HtmPKJ1hrN3nzPNKFEKOUiQ==} + + is-proto-prop@2.0.0: + resolution: {integrity: sha512-jl3NbQ/fGLv5Jhan4uX+Ge9ohnemqyblWVVCpAvtTQzNFvV2xhJq+esnkIbYQ9F1nITXoLfDDQLp7LBw/zzncg==} + + is-reference@1.2.1: + resolution: {integrity: sha512-U82MsXXiFIrjCK4otLT+o2NA2Cd2g5MLoOVXUZjIOhLurrRxpEXzI8O0KZHr3IjLvlAH1kTPYSuqer5T9ZVBKQ==} + + is-regex@1.1.4: + resolution: {integrity: sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg==} + engines: {node: '>= 0.4'} + + is-set@2.0.3: + resolution: {integrity: sha512-iPAjerrse27/ygGLxw+EBR9agv9Y6uLeYVJMu+QNCoouJ1/1ri0mGrcWpfCqFZuzzx3WjtwxG098X+n4OuRkPg==} + engines: {node: '>= 0.4'} + + is-shared-array-buffer@1.0.2: + resolution: {integrity: sha512-sqN2UDu1/0y6uvXyStCOzyhAjCSlHceFoMKJW8W9EU9cvic/QdsZ0kEU93HEy3IUEFZIiH/3w+AH/UQbPHNdhA==} + + is-shared-array-buffer@1.0.3: + resolution: {integrity: sha512-nA2hv5XIhLR3uVzDDfCIknerhx8XUKnstuOERPNNIinXG7v9u+ohXF67vxm4TPTEPU6lm61ZkwP3c9PCB97rhg==} + engines: {node: '>= 0.4'} + + is-stream@2.0.1: + resolution: {integrity: sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==} + engines: {node: '>=8'} + + is-stream@3.0.0: + resolution: {integrity: sha512-LnQR4bZ9IADDRSkvpqMGvt/tEJWclzklNgSw48V5EAaAeDd6qGvN8ei6k5p0tvxSR171VmGyHuTiAOfxAbr8kA==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + + is-string@1.0.7: + resolution: {integrity: sha512-tE2UXzivje6ofPW7l23cjDOMa09gb7xlAqG6jG5ej6uPV32TlWP3NKPigtaGeHNu9fohccRYvIiZMfOOnOYUtg==} + engines: {node: '>= 0.4'} + + is-subdir@1.2.0: + resolution: {integrity: sha512-2AT6j+gXe/1ueqbW6fLZJiIw3F8iXGJtt0yDrZaBhAZEG1raiTxKWU+IPqMCzQAXOUCKdA4UDMgacKH25XG2Cw==} + engines: {node: '>=4'} + + is-symbol@1.0.4: + resolution: {integrity: sha512-C/CPBqKWnvdcxqIARxyOh4v1UUEOCHpgDa0WYgpKDFMszcrPcffg5uhwSgPCLD2WWxmq6isisz87tzT01tuGhg==} + engines: {node: '>= 0.4'} + + is-text-path@2.0.0: + resolution: {integrity: sha512-+oDTluR6WEjdXEJMnC2z6A4FRwFoYuvShVVEGsS7ewc0UTi2QtAKMDJuL4BDEVt+5T7MjFo12RP8ghOM75oKJw==} + engines: {node: '>=8'} + + is-typed-array@1.1.13: + resolution: {integrity: sha512-uZ25/bUAlUY5fR4OKT4rZQEBrzQWYV9ZJYGGsUmEJ6thodVJ1HX64ePQ6Z0qPWP+m+Uq6e9UugrE38jeYsDSMw==} + engines: {node: '>= 0.4'} + + is-unicode-supported@1.3.0: + resolution: {integrity: sha512-43r2mRvz+8JRIKnWJ+3j8JtjRKZ6GmjzfaE/qiBJnikNnYv/6bagRJ1kUhNk8R5EX/GkobD+r+sfxCPJsiKBLQ==} + engines: {node: '>=12'} + + is-unicode-supported@2.0.0: + resolution: {integrity: sha512-FRdAyx5lusK1iHG0TWpVtk9+1i+GjrzRffhDg4ovQ7mcidMQ6mj+MhKPmvh7Xwyv5gIS06ns49CA7Sqg7lC22Q==} + engines: {node: '>=18'} + + is-weakmap@2.0.2: + resolution: {integrity: sha512-K5pXYOm9wqY1RgjpL3YTkF39tni1XajUIkawTLUo9EZEVUFga5gSQJF8nNS7ZwJQ02y+1YCNYcMh+HIf1ZqE+w==} + engines: {node: '>= 0.4'} + + is-weakref@1.0.2: + resolution: {integrity: sha512-qctsuLZmIQ0+vSSMfoVvyFe2+GSEvnmZ2ezTup1SBse9+twCCeial6EEi3Nc2KFcf6+qz2FBPnjXsk8xhKSaPQ==} + + is-weakset@2.0.3: + resolution: {integrity: sha512-LvIm3/KWzS9oRFHugab7d+M/GcBXuXX5xZkzPmN+NxihdQlZUQ4dWuSV1xR/sq6upL1TJEDrfBgRepHFdBtSNQ==} + engines: {node: '>= 0.4'} + + is-whitespace-character@1.0.4: + resolution: {integrity: sha512-SDweEzfIZM0SJV0EUga669UTKlmL0Pq8Lno0QDQsPnvECB3IM2aP0gdx5TrU0A01MAPfViaZiI2V1QMZLaKK5w==} + + is-windows@0.2.0: + resolution: {integrity: sha512-n67eJYmXbniZB7RF4I/FTjK1s6RPOCTxhYrVYLRaCt3lF0mpWZPKr3T2LSZAqyjQsxR2qMmGYXXzK0YWwcPM1Q==} + engines: {node: '>=0.10.0'} + + is-windows@1.0.2: + resolution: {integrity: sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA==} + engines: {node: '>=0.10.0'} + + is-word-character@1.0.4: + resolution: {integrity: sha512-5SMO8RVennx3nZrqtKwCGyyetPE9VDba5ugvKLaD4KopPG5kR4mQ7tNt/r7feL5yt5h3lpuBbIUmCOG2eSzXHA==} + + isarray@0.0.1: + resolution: {integrity: sha512-D2S+3GLxWH+uhrNEcoh/fnmYeP8E8/zHl644d/jdA0g2uyXvy3sb0qxotE+ne0LtccHknQzWwZEzhak7oJ0COQ==} + + isarray@2.0.5: + resolution: {integrity: sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==} + + isexe@2.0.0: + resolution: {integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==} + + iso8601-duration@2.1.2: + resolution: {integrity: sha512-yXteYUiKv6x8seaDzyBwnZtPpmx766KfvQuaVNyPifYOjmPdOo3ajd4phDNa7Y5mTQGnXsNEcXFtVun1FjYXxQ==} + + istanbul-lib-coverage@3.2.2: + resolution: {integrity: sha512-O8dpsF+r0WV/8MNRKfnmrtCWhuKjxrq2w+jpzBL5UZKTi2LeVWnWOmWRxFlesJONmc+wLAGvKQZEOanko0LFTg==} + engines: {node: '>=8'} + + istanbul-lib-instrument@5.2.1: + resolution: {integrity: sha512-pzqtp31nLv/XFOzXGuvhCb8qhjmTVo5vjVk19XE4CRlSWz0KoeJ3bw9XsA7nOp9YBf4qHjwBxkDzKcME/J29Yg==} + engines: {node: '>=8'} + + istanbul-lib-instrument@6.0.1: + resolution: {integrity: sha512-EAMEJBsYuyyztxMxW3g7ugGPkrZsV57v0Hmv3mm1uQsmB+QnZuepg731CRaIgeUVSdmsTngOkSnauNF8p7FIhA==} + engines: {node: '>=10'} + + istanbul-lib-report@3.0.1: + resolution: {integrity: sha512-GCfE1mtsHGOELCU8e/Z7YWzpmybrx/+dSTfLrvY8qRmaY6zXTKWn6WQIjaAFw069icm6GVMNkgu0NzI4iPZUNw==} + engines: {node: '>=10'} + + istanbul-lib-source-maps@4.0.1: + resolution: {integrity: sha512-n3s8EwkdFIJCG3BPKBYvskgXGoy88ARzvegkitk60NxRdwltLOTaH7CUiMRXvwYorl0Q712iEjcWB+fK/MrWVw==} + engines: {node: '>=10'} + + istanbul-lib-source-maps@5.0.4: + resolution: {integrity: sha512-wHOoEsNJTVltaJp8eVkm8w+GVkVNHT2YDYo53YdzQEL2gWm1hBX5cGFR9hQJtuGLebidVX7et3+dmDZrmclduw==} + engines: {node: '>=10'} + + istanbul-reports@3.1.7: + resolution: {integrity: sha512-BewmUXImeuRk2YY0PVbxgKAysvhRPUQE0h5QRM++nVWyubKGV0l8qQ5op8+B2DOmwSe63Jivj0BjkPQVf8fP5g==} + engines: {node: '>=8'} + + iterator.prototype@1.1.2: + resolution: {integrity: sha512-DR33HMMr8EzwuRL8Y9D3u2BMj8+RqSE850jfGu59kS7tbmPLzGkZmVSfyCFSDxuZiEY6Rzt3T2NA/qU+NwVj1w==} + + jackspeak@2.3.6: + resolution: {integrity: sha512-N3yCS/NegsOBokc8GAdM8UcmfsKiSS8cipheD/nivzr700H+nsMOxJjQnvwOcRYVuFkdH0wGUvW2WbXGmrZGbQ==} + engines: {node: '>=14'} + + jest-changed-files@29.7.0: + resolution: {integrity: sha512-fEArFiwf1BpQ+4bXSprcDc3/x4HSzL4al2tozwVpDFpsxALjLYdyiIK4e5Vz66GQJIbXJ82+35PtysofptNX2w==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + jest-circus@29.7.0: + resolution: {integrity: sha512-3E1nCMgipcTkCocFwM90XXQab9bS+GMsjdpmPrlelaxwD93Ad8iVEjX/vvHPdLPnFf+L40u+5+iutRdA1N9myw==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + jest-cli@29.7.0: + resolution: {integrity: sha512-OVVobw2IubN/GSYsxETi+gOe7Ka59EFMR/twOU3Jb2GnKKeMGJB5SGUUrEz3SFVmJASUdZUzy83sLNNQ2gZslg==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + hasBin: true + peerDependencies: + node-notifier: ^8.0.1 || ^9.0.0 || ^10.0.0 + peerDependenciesMeta: + node-notifier: + optional: true + + jest-config@29.7.0: + resolution: {integrity: sha512-uXbpfeQ7R6TZBqI3/TxCU4q4ttk3u0PJeC+E0zbfSoSjq6bJ7buBPxzQPL0ifrkY4DNu4JUdk0ImlBUYi840eQ==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + peerDependencies: + '@types/node': '*' + ts-node: '>=9.0.0' + peerDependenciesMeta: + '@types/node': + optional: true + ts-node: + optional: true + + jest-dev-server@10.0.0: + resolution: {integrity: sha512-FtyBBDxrAIfTX3hyKSOwj5KU6Z7fFLew5pQYOFpwyf+qpPpULL8aYxtsFkbkAwcs+Mb7qhcNbVLeiWsLOd7CKw==} + engines: {node: '>=16'} + + jest-diff@29.7.0: + resolution: {integrity: sha512-LMIgiIrhigmPrs03JHpxUh2yISK3vLFPkAodPeo0+BuF7wA2FoQbkEg1u8gBYBThncu7e1oEDUfIXVuTqLRUjw==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + jest-docblock@29.7.0: + resolution: {integrity: sha512-q617Auw3A612guyaFgsbFeYpNP5t2aoUNLwBUbc/0kD1R4t9ixDbyFTHd1nok4epoVFpr7PmeWHrhvuV3XaJ4g==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + jest-each@29.7.0: + resolution: {integrity: sha512-gns+Er14+ZrEoC5fhOfYCY1LOHHr0TI+rQUHZS8Ttw2l7gl+80eHc/gFf2Ktkw0+SIACDTeWvpFcv3B04VembQ==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + jest-environment-jsdom@29.2.2: + resolution: {integrity: sha512-5mNtTcky1+RYv9kxkwMwt7fkzyX4EJUarV7iI+NQLigpV4Hz4sgfOdP4kOpCHXbkRWErV7tgXoXLm2CKtucr+A==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + peerDependencies: + canvas: ^2.5.0 + peerDependenciesMeta: + canvas: + optional: true + + jest-environment-node@29.7.0: + resolution: {integrity: sha512-DOSwCRqXirTOyheM+4d5YZOrWcdu0LNZ87ewUoywbcb2XR4wKgqiG8vNeYwhjFMbEkfju7wx2GYH0P2gevGvFw==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + jest-environment-puppeteer@10.0.1: + resolution: {integrity: sha512-FxMzVRyqieQqSy5CPWiwdK5t9dkRHid5eoRTVa8RtYeXLlpW6lU0dAmxEfPkdnDVCiPUhC2APeKOXq0J72bgag==} + engines: {node: '>=16'} + + jest-get-type@29.6.3: + resolution: {integrity: sha512-zrteXnqYxfQh7l5FHyL38jL39di8H8rHoecLH3JNxH3BwOrBsNeabdap5e0I23lD4HHI8W5VFBZqG4Eaq5LNcw==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + jest-haste-map@29.5.0: + resolution: {integrity: sha512-IspOPnnBro8YfVYSw6yDRKh/TiCdRngjxeacCps1cQ9cgVN6+10JUcuJ1EabrgYLOATsIAigxA0rLR9x/YlrSA==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + jest-haste-map@29.7.0: + resolution: {integrity: sha512-fP8u2pyfqx0K1rGn1R9pyE0/KTn+G7PxktWidOBTqFPLYX0b9ksaMFkhK5vrS3DVun09pckLdlx90QthlW7AmA==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + jest-leak-detector@29.7.0: + resolution: {integrity: sha512-kYA8IJcSYtST2BY9I+SMC32nDpBT3J2NvWJx8+JCuCdl/CR1I4EKUJROiP8XtCcxqgTTBGJNdbB1A8XRKbTetw==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + jest-matcher-specific-error@1.0.0: + resolution: {integrity: sha512-thJdy9ibhDo8k+0arFalNCQBJ0u7eqTfpTzS2MzL3iCLmbRCkI+yhhKSiAxEi55e5ZUyf01ySa0fMqzF+sblAw==} + + jest-matcher-utils@29.7.0: + resolution: {integrity: sha512-sBkD+Xi9DtcChsI3L3u0+N0opgPYnCRPtGcQYrgXmR+hmt/fYfWAL0xRXYU8eWOdfuLgBe0YCW3AFtnRLagq/g==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + jest-message-util@29.5.0: + resolution: {integrity: sha512-Kijeg9Dag6CKtIDA7O21zNTACqD5MD/8HfIV8pdD94vFyFuer52SigdC3IQMhab3vACxXMiFk+yMHNdbqtyTGA==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + jest-message-util@29.7.0: + resolution: {integrity: sha512-GBEV4GRADeP+qtB2+6u61stea8mGcOT4mCtrYISZwfu9/ISHFJ/5zOMXYbpBE9RsS5+Gb63DW4FgmnKJ79Kf6w==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + jest-mock@29.5.0: + resolution: {integrity: sha512-GqOzvdWDE4fAV2bWQLQCkujxYWL7RxjCnj71b5VhDAGOevB3qj3Ovg26A5NI84ZpODxyzaozXLOh2NCgkbvyaw==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + jest-mock@29.7.0: + resolution: {integrity: sha512-ITOMZn+UkYS4ZFh83xYAOzWStloNzJFO2s8DWrE4lhtGD+AorgnbkiKERe4wQVBydIGPx059g6riW5Btp6Llnw==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + jest-pnp-resolver@1.2.2: + resolution: {integrity: sha512-olV41bKSMm8BdnuMsewT4jqlZ8+3TCARAXjZGT9jcoSnrfUnRCqnMoF9XEeoWjbzObpqF9dRhHQj0Xb9QdF6/w==} + engines: {node: '>=6'} + peerDependencies: + jest-resolve: '*' + peerDependenciesMeta: + jest-resolve: + optional: true + + jest-puppeteer@10.0.1: + resolution: {integrity: sha512-FzC35XbqeuQEt1smXh1EOqhJaRkWqJkyWDMfGkcZ8C59QHXeJ7F/iOmiNqYi6l/OsycUuOPCk+IkjfGfS9YbrQ==} + engines: {node: '>=16'} + peerDependencies: + puppeteer: '>=19' + + jest-regex-util@29.4.3: + resolution: {integrity: sha512-O4FglZaMmWXbGHSQInfXewIsd1LMn9p3ZXB/6r4FOkyhX2/iP/soMG98jGvk/A3HAN78+5VWcBGO0BJAPRh4kg==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + jest-regex-util@29.6.3: + resolution: {integrity: sha512-KJJBsRCyyLNWCNBOvZyRDnAIfUiRJ8v+hOBQYGn8gDyF3UegwiP4gwRR3/SDa42g1YbVycTidUF3rKjyLFDWbg==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + jest-resolve-dependencies@29.7.0: + resolution: {integrity: sha512-un0zD/6qxJ+S0et7WxeI3H5XSe9lTBBR7bOHCHXkKR6luG5mwDDlIzVQ0V5cZCuoTgEdcdwzTghYkTWfubi+nA==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + jest-resolve@29.7.0: + resolution: {integrity: sha512-IOVhZSrg+UvVAshDSDtHyFCCBUl/Q3AAJv8iZ6ZjnZ74xzvwuzLXid9IIIPgTnY62SJjfuupMKZsZQRsCvxEgA==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + jest-runner@29.7.0: + resolution: {integrity: sha512-fsc4N6cPCAahybGBfTRcq5wFR6fpLznMg47sY5aDpsoejOcVYFb07AHuSnR0liMcPTgBsA3ZJL6kFOjPdoNipQ==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + jest-runtime@29.7.0: + resolution: {integrity: sha512-gUnLjgwdGqW7B4LvOIkbKs9WGbn+QLqRQQ9juC6HndeDiezIwhDP+mhMwHWCEcfQ5RUXa6OPnFF8BJh5xegwwQ==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + jest-snapshot@29.7.0: + resolution: {integrity: sha512-Rm0BMWtxBcioHr1/OX5YCP8Uov4riHvKPknOGs804Zg9JGZgmIBkbtlxJC/7Z4msKYVbIJtfU+tKb8xlYNfdkw==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + jest-transform-stub@2.0.0: + resolution: {integrity: sha512-lspHaCRx/mBbnm3h4uMMS3R5aZzMwyNpNIJLXj4cEsV0mIUtS4IjYJLSoyjRCtnxb6RIGJ4NL2quZzfIeNhbkg==} + + jest-transformer-svg@2.0.0: + resolution: {integrity: sha512-+f6er7UZTiHTeel9nma1i0NTAU8AjbEvhK2RYUoMxTNihwo98z2rrrDBIbppZI6ACDzeul3bhRmI9M6d25J/Nw==} + peerDependencies: + jest: ^28.1.0 || ^29.1.2 + react: ^17.0.0 || ^18.0.0 + + jest-util@29.5.0: + resolution: {integrity: sha512-RYMgG/MTadOr5t8KdhejfvUU82MxsCu5MF6KuDUHl+NuwzUt+Sm6jJWxTJVrDR1j5M/gJVCPKQEpWXY+yIQ6lQ==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + jest-util@29.7.0: + resolution: {integrity: sha512-z6EbKajIpqGKU56y5KBUgy1dt1ihhQJgWzUlZHArA/+X2ad7Cb5iF+AK1EWVL/Bo7Rz9uurpqw6SiBCefUbCGA==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + jest-validate@29.7.0: + resolution: {integrity: sha512-ZB7wHqaRGVw/9hST/OuFUReG7M8vKeq0/J2egIGLdvjHCmYqGARhzXmtgi+gVeZ5uXFF219aOc3Ls2yLg27tkw==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + jest-watcher@29.7.0: + resolution: {integrity: sha512-49Fg7WXkU3Vl2h6LbLtMQ/HyB6rXSIX7SqvBLQmssRBGN9I0PNvPmAmCWSOY6SOvrjhI/F7/bGAv9RtnsPA03g==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + jest-worker@29.5.0: + resolution: {integrity: sha512-NcrQnevGoSp4b5kg+akIpthoAFHxPBcb5P6mYPY0fUNT+sSvmtu6jlkEle3anczUKIKEbMxFimk9oTP/tpIPgA==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + jest-worker@29.7.0: + resolution: {integrity: sha512-eIz2msL/EzL9UFTFFx7jBTkeZfku0yUAyZZZmJ93H2TYEiroIx2PQjEXcwYtYl8zXCxb+PAmA2hLIt/6ZEkPHw==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + jest@29.7.0: + resolution: {integrity: sha512-NIy3oAFp9shda19hy4HK0HRTWKtPJmGdnvywu01nOqNC2vZg+Z+fvJDxpMQA88eb2I9EcafcdjYgsDthnYTvGw==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + hasBin: true + peerDependencies: + node-notifier: ^8.0.1 || ^9.0.0 || ^10.0.0 + peerDependenciesMeta: + node-notifier: + optional: true + + jiti@1.21.0: + resolution: {integrity: sha512-gFqAIbuKyyso/3G2qhiO2OM6shY6EPP/R0+mkDbyspxKazh8BXDC5FiFsUjlczgdNz/vfra0da2y+aHrusLG/Q==} + hasBin: true + + joi@17.12.2: + resolution: {integrity: sha512-RonXAIzCiHLc8ss3Ibuz45u28GOsWE1UpfDXLbN/9NKbL4tCJf8TWYVKsoYuuh+sAUt7fsSNpA+r2+TBA6Wjmw==} + + jose@5.0.1: + resolution: {integrity: sha512-gRVzy7s3RRdGbXmcTdlOswJOjhwPLx1ijIgAqLY6ktzFpOJxxYn4l0fC2vHaHHi4YBX/5FOL3aY+6W0cvQgpug==} + + jose@5.2.2: + resolution: {integrity: sha512-/WByRr4jDcsKlvMd1dRJnPfS1GVO3WuKyaurJ/vvXcOaUQO8rnNObCQMlv/5uCceVQIq5Q4WLF44ohsdiTohdg==} + + jose@5.2.4: + resolution: {integrity: sha512-6ScbIk2WWCeXkmzF6bRPmEuaqy1m8SbsRFMa/FLrSCkGIhj8OLVG/IH+XHVmNMx/KUo8cVWEE6oKR4dJ+S0Rkg==} + + js-base64@3.7.5: + resolution: {integrity: sha512-3MEt5DTINKqfScXKfJFrRbxkrnk2AxPWGBL/ycjz4dK8iqiSJ06UxD8jh8xuh6p10TX4t2+7FsBYVxxQbMg+qA==} + + js-tokens@4.0.0: + resolution: {integrity: sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==} + + js-tokens@8.0.3: + resolution: {integrity: sha512-UfJMcSJc+SEXEl9lH/VLHSZbThQyLpw1vLO1Lb+j4RWDvG3N2f7yj3PVQA3cmkTBNldJ9eFnM+xEXxHIXrYiJw==} + + js-types@1.0.0: + resolution: {integrity: sha512-bfwqBW9cC/Lp7xcRpug7YrXm0IVw+T9e3g4mCYnv0Pjr3zIzU9PCQElYU9oSGAWzXlbdl9X5SAMPejO9sxkeUw==} + engines: {node: '>=0.10.0'} + + js-yaml@3.14.1: + resolution: {integrity: sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==} + hasBin: true + + js-yaml@4.1.0: + resolution: {integrity: sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==} + hasBin: true + + jsdom@20.0.2: + resolution: {integrity: sha512-AHWa+QO/cgRg4N+DsmHg1Y7xnz+8KU3EflM0LVDTdmrYOc1WWTSkOjtpUveQH+1Bqd5rtcVnb/DuxV/UjDO4rA==} + engines: {node: '>=14'} + peerDependencies: + canvas: ^2.5.0 + peerDependenciesMeta: + canvas: + optional: true + + jsesc@0.5.0: + resolution: {integrity: sha512-uZz5UnB7u4T9LvwmFqXii7pZSouaRPorGs5who1Ip7VO0wxanFvBL7GkM6dTHlgX+jhBApRetaWpnDabOeTcnA==} + hasBin: true + + jsesc@2.5.2: + resolution: {integrity: sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==} + engines: {node: '>=4'} + hasBin: true + + jsesc@3.0.2: + resolution: {integrity: sha512-xKqzzWXDttJuOcawBt4KnKHHIf5oQ/Cxax+0PWFG+DFDgHNAdi+TXECADI+RYiFUMmx8792xsMbbgXj4CwnP4g==} + engines: {node: '>=6'} + hasBin: true + + json-bigint@1.0.0: + resolution: {integrity: sha512-SiPv/8VpZuWbvLSMtTDU8hEfrZWg/mH/nV/b4o0CYbSxu1UIQPLdwKOCIyLQX+VIPO5vrLX3i8qtqFyhdPSUSQ==} + + json-buffer@3.0.1: + resolution: {integrity: sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==} + + json-parse-even-better-errors@2.3.1: + resolution: {integrity: sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==} + + json-schema-traverse@0.4.1: + resolution: {integrity: sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==} + + json-schema-traverse@1.0.0: + resolution: {integrity: sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==} + + json-stable-stringify-without-jsonify@1.0.1: + resolution: {integrity: sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==} + + json-stringify-safe@5.0.1: + resolution: {integrity: sha512-ZClg6AaYvamvYEE82d3Iyd3vSSIjQ+odgjaTzRuO3s7toCdFKczob2i0zCh7JE8kWn17yvAWhUVxvqGwUalsRA==} + + json5@1.0.2: + resolution: {integrity: sha512-g1MWMLBiz8FKi1e4w0UyVL3w+iJceWAFBAaBnnGKOpNa5f8TLktkbre1+s6oICydWAm+HRUGTmI+//xv2hvXYA==} + hasBin: true + + json5@2.2.3: + resolution: {integrity: sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==} + engines: {node: '>=6'} + hasBin: true + + jsonc-eslint-parser@2.4.0: + resolution: {integrity: sha512-WYDyuc/uFcGp6YtM2H0uKmUwieOuzeE/5YocFJLnLfclZ4inf3mRn8ZVy1s7Hxji7Jxm6Ss8gqpexD/GlKoGgg==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + + jsonc-parser@3.2.0: + resolution: {integrity: sha512-gfFQZrcTc8CnKXp6Y4/CBT3fTc0OVuDofpre4aEeEpSBPV5X5v4+Vmx+8snU7RLPrNHPKSgLxGo9YuQzz20o+w==} + + jsonfile@4.0.0: + resolution: {integrity: sha512-m6F1R3z8jjlf2imQHS2Qez5sjKWQzbuuhuJ/FKYFRZvPE3PuHcSMVZzfsLhGVOkfd20obL5SWEBew5ShlquNxg==} + + jsonparse@1.3.1: + resolution: {integrity: sha512-POQXvpdL69+CluYsillJ7SUhKvytYjW9vG/GKpnf+xP8UWgYEM/RaMzHHofbALDiKbbP1W8UEYmgGl39WkPZsg==} + engines: {'0': node >= 0.2.0} + + jsonwebtoken@9.0.2: + resolution: {integrity: sha512-PRp66vJ865SSqOlgqS8hujT5U4AOgMfhrwYIuIhfKaoSCZcirrmASQr8CX7cUg+RMih+hgznrjp99o+W4pJLHQ==} + engines: {node: '>=12', npm: '>=6'} + + jsx-ast-utils@3.3.5: + resolution: {integrity: sha512-ZZow9HBI5O6EPgSJLUb8n2NKgmVWTwCvHGwFuJlMjvLFqlGG6pjirPhtdsseaLZjSibD8eegzmYpUZwoIlj2cQ==} + engines: {node: '>=4.0'} + + just-extend@4.2.1: + resolution: {integrity: sha512-g3UB796vUFIY90VIv/WX3L2c8CS2MdWUww3CNrYmqza1Fg0DURc2K/O4YrnklBdQarSJ/y8JnJYDGc+1iumQjg==} + + just-kebab-case@4.2.0: + resolution: {integrity: sha512-p2BdO7o4BI+pMun3J+dhaOfYan5JsZrw9wjshRjkWY9+p+u+kKSMhNWYnot2yHDR9CSahZ9iT3dcqJ+V72qHMw==} + + jwa@1.4.1: + resolution: {integrity: sha512-qiLX/xhEEFKUAJ6FiBMbes3w9ATzyk5W7Hvzpa/SLYdxNtng+gcurvrI7TbACjIXlsJyr05/S1oUhZrc63evQA==} + + jwa@2.0.0: + resolution: {integrity: sha512-jrZ2Qx916EA+fq9cEAeCROWPTfCwi1IVHqT2tapuqLEVVDKFDENFw1oL+MwrTvH6msKxsd1YTDVw6uKEcsrLEA==} + + jws@3.2.2: + resolution: {integrity: sha512-YHlZCB6lMTllWDtSPHz/ZXTsi8S00usEV6v1tjq8tOUZzw7DpSDWVXjXDre6ed1w/pd495ODpHZYSdkRTsa0HA==} + + jws@4.0.0: + resolution: {integrity: sha512-KDncfTmOZoOMTFG4mBlG0qUIOlc03fmzH+ru6RgYVZhPkyiy/92Owlt/8UEN+a4TXR1FQetfIpJE8ApdvdVxTg==} + + keygrip@1.1.0: + resolution: {integrity: sha512-iYSchDJ+liQ8iwbSI2QqsQOvqv58eJCEanyJPJi+Khyu8smkcKSFUCbPwzFcL7YVtZ6eONjqRX/38caJ7QjRAQ==} + engines: {node: '>= 0.6'} + + keyv@4.5.4: + resolution: {integrity: sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==} + + kind-of@6.0.3: + resolution: {integrity: sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==} + engines: {node: '>=0.10.0'} + + kleur@3.0.3: + resolution: {integrity: sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w==} + engines: {node: '>=6'} + + kleur@4.1.4: + resolution: {integrity: sha512-8QADVssbrFjivHWQU7KkMgptGTl6WAcSdlbBPY4uNF+mWr6DGcKrvY2w4FQJoXch7+fKMjj0dRrL75vk3k23OA==} + engines: {node: '>=6'} + + known-css-properties@0.29.0: + resolution: {integrity: sha512-Ne7wqW7/9Cz54PDt4I3tcV+hAyat8ypyOGzYRJQfdxnnjeWsTxt1cy8pjvvKeI5kfXuyvULyeeAvwvvtAX3ayQ==} + + koa-body@6.0.1: + resolution: {integrity: sha512-M8ZvMD8r+kPHy28aWP9VxL7kY8oPWA+C7ZgCljrCMeaU7uX6wsIQgDHskyrAr9sw+jqnIXyv4Mlxri5R4InIJg==} + + koa-compose@4.1.0: + resolution: {integrity: sha512-8ODW8TrDuMYvXRwra/Kh7/rJo9BtOfPc6qO8eAfC80CnCvSjSl0bkRM24X6/XBBEyj0v1nRUQ1LyOy3dbqOWXw==} + + koa-compress@5.1.0: + resolution: {integrity: sha512-G3Ppo9jrUwlchp6qdoRgQNMiGZtM0TAHkxRZQ7EoVvIG8E47J4nAsMJxXHAUQ+0oc7t0MDxSdONWTFcbzX7/Bg==} + engines: {node: '>= 8.0.0'} + + koa-convert@2.0.0: + resolution: {integrity: sha512-asOvN6bFlSnxewce2e/DK3p4tltyfC4VM7ZwuTuepI7dEQVcvpyFuBcEARu1+Hxg8DIwytce2n7jrZtRlPrARA==} + engines: {node: '>= 10'} + + koa-is-json@1.0.0: + resolution: {integrity: sha512-+97CtHAlWDx0ndt0J8y3P12EWLwTLMXIfMnYDev3wOTwH/RpBGMlfn4bDXlMEg1u73K6XRE9BbUp+5ZAYoRYWw==} + + koa-logger@3.2.1: + resolution: {integrity: sha512-MjlznhLLKy9+kG8nAXKJLM0/ClsQp/Or2vI3a5rbSQmgl8IJBQO0KI5FA70BvW+hqjtxjp49SpH2E7okS6NmHg==} + engines: {node: '>= 7.6.0'} + + koa-mount@4.0.0: + resolution: {integrity: sha512-rm71jaA/P+6HeCpoRhmCv8KVBIi0tfGuO/dMKicbQnQW/YJntJ6MnnspkodoA4QstMVEZArsCphmd0bJEtoMjQ==} + engines: {node: '>= 7.6.0'} + + koa-proxies@0.12.4: + resolution: {integrity: sha512-xxrEtN0e7s7/gNRoOMUltCbuIaCWqTQUTZNWQqet/8MoxSW0hG422lx2Al9FfYO3nCeA+b5c5/YmILRzavivDA==} + peerDependencies: + koa: '>=2' + + koa-router@12.0.0: + resolution: {integrity: sha512-zGrdiXygGYW8WvrzeGsHZvKnHs4DzyGoqJ9a8iHlRkiwuEAOAPyI27//OlhoWdgFAEIM3qbUgr0KCuRaP/TCag==} + engines: {node: '>= 12'} + + koa-send@5.0.1: + resolution: {integrity: sha512-tmcyQ/wXXuxpDxyNXv5yNNkdAMdFRqwtegBXUaowiQzUKqJehttS0x2j0eOZDQAyloAth5w6wwBImnFzkUz3pQ==} + engines: {node: '>= 8'} + + koa@2.13.4: + resolution: {integrity: sha512-43zkIKubNbnrULWlHdN5h1g3SEKXOEzoAlRsHOTFpnlDu8JlAOZSMJBLULusuXRequboiwJcj5vtYXKB3k7+2g==} + engines: {node: ^4.8.4 || ^6.10.1 || ^7.10.1 || >= 8.1.4} + + koa@2.15.3: + resolution: {integrity: sha512-j/8tY9j5t+GVMLeioLaxweJiKUayFhlGqNTzf2ZGwL0ZCQijd2RLHK0SLW5Tsko8YyyqCZC2cojIb0/s62qTAg==} + engines: {node: ^4.8.4 || ^6.10.1 || ^7.10.1 || >= 8.1.4} + + ky@1.2.3: + resolution: {integrity: sha512-2IM3VssHfG2zYz2FsHRUqIp8chhLc9uxDMcK2THxgFfv8pQhnMfN8L0ul+iW4RdBl5AglF8ooPIflRm3yNH0IA==} + engines: {node: '>=18'} + + language-subtag-registry@0.3.22: + resolution: {integrity: sha512-tN0MCzyWnoz/4nHS6uxdlFWoUZT7ABptwKPQ52Ea7URk6vll88bWBVhodtnlfEuCcKWNGoc+uGbw1cwa9IKh/w==} + + language-tags@1.0.9: + resolution: {integrity: sha512-MbjN408fEndfiQXbFQ1vnd+1NoLDsnQW41410oQBXiyXDMYH5z505juWa4KUE1LqxRC7DgOgZDbKLxHIwm27hA==} + engines: {node: '>=0.10'} + + leven@3.1.0: + resolution: {integrity: sha512-qsda+H8jTaUaN/x5vzW2rzc+8Rw4TAQ/4KjB46IwK5VH+IlVeeeje/EoZRpiXvIqjFgK84QffqPztGI3VBLG1A==} + engines: {node: '>=6'} + + levn@0.3.0: + resolution: {integrity: sha512-0OO4y2iOHix2W6ujICbKIaEQXvFQHue65vUG3pb5EUomzPI90z9hsA1VsO/dbIIpC53J8gxM9Q4Oho0jrCM/yA==} + engines: {node: '>= 0.8.0'} + + levn@0.4.1: + resolution: {integrity: sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==} + engines: {node: '>= 0.8.0'} + + libphonenumber-js@1.10.51: + resolution: {integrity: sha512-vY2I+rQwrDQzoPds0JeTEpeWzbUJgqoV0O4v31PauHBb/e+1KCXKylHcDnBMgJZ9fH9mErsEbROJY3Z3JtqEmg==} + + lightningcss-darwin-arm64@1.16.1: + resolution: {integrity: sha512-/J898YSAiGVqdybHdIF3Ao0Hbh2vyVVj5YNm3NznVzTSvkOi3qQCAtO97sfmNz+bSRHXga7ZPLm+89PpOM5gAg==} + engines: {node: '>= 12.0.0'} + cpu: [arm64] + os: [darwin] + + lightningcss-darwin-x64@1.16.1: + resolution: {integrity: sha512-vyKCNPRNRqke+5i078V+N0GLfMVLEaNcqIcv28hA/vUNRGk/90EDkDB9EndGay0MoPIrC2y0qE3Y74b/OyedqQ==} + engines: {node: '>= 12.0.0'} + cpu: [x64] + os: [darwin] + + lightningcss-linux-arm-gnueabihf@1.16.1: + resolution: {integrity: sha512-0AJC52l40VbrzkMJz6qRvlqVVGykkR2MgRS4bLjVC2ab0H0I/n4p6uPZXGvNIt5gw1PedeND/hq+BghNdgfuPQ==} + engines: {node: '>= 12.0.0'} + cpu: [arm] + os: [linux] + + lightningcss-linux-arm64-gnu@1.16.1: + resolution: {integrity: sha512-NqxYXsRvI3/Fb9AQLXKrYsU0Q61LqKz5It+Es9gidsfcw1lamny4lmlUgO3quisivkaLCxEkogaizcU6QeZeWQ==} + engines: {node: '>= 12.0.0'} + cpu: [arm64] + os: [linux] + + lightningcss-linux-arm64-musl@1.16.1: + resolution: {integrity: sha512-VUPQ4dmB9yDQxpJF8/imtwNcbIPzlL6ArLHSUInOGxipDk1lOAklhUjbKUvlL3HVlDwD3WHCxggAY01WpFcjiA==} + engines: {node: '>= 12.0.0'} + cpu: [arm64] + os: [linux] + + lightningcss-linux-x64-gnu@1.16.1: + resolution: {integrity: sha512-A40Jjnbellnvh4YF+kt047GLnUU59iLN2LFRCyWQG+QqQZeXOCzXfTQ6EJB4yvHB1mQvWOVdAzVrtEmRw3Vh8g==} + engines: {node: '>= 12.0.0'} + cpu: [x64] + os: [linux] + + lightningcss-linux-x64-musl@1.16.1: + resolution: {integrity: sha512-VZf76GxW+8mk238tpw0u9R66gBi/m0YB0TvD54oeGiOqvTZ/mabkBkbsuXTSWcKYj8DSrLW+A42qu+6PLRsIgA==} + engines: {node: '>= 12.0.0'} + cpu: [x64] + os: [linux] + + lightningcss-win32-x64-msvc@1.16.1: + resolution: {integrity: sha512-Djy+UzlTtJMayVJU3eFuUW5Gdo+zVTNPJhlYw25tNC9HAoMCkIdSDDrGsWEdEyibEV7xwB8ySTmLuxilfhBtgg==} + engines: {node: '>= 12.0.0'} + cpu: [x64] + os: [win32] + + lightningcss@1.16.1: + resolution: {integrity: sha512-zU8OTaps3VAodmI2MopfqqOQQ4A9L/2Eo7xoTH/4fNkecy6ftfiGwbbRMTQqtIqJjRg3f927e+lnyBBPhucY1Q==} + engines: {node: '>= 12.0.0'} + + lilconfig@2.1.0: + resolution: {integrity: sha512-utWOt/GHzuUxnLKxB6dk81RoOeoNeHgbrXiuGk4yyF5qlRz+iIVWu56E2fqGHFrXz0QNUhLB/8nKqvRH66JKGQ==} + engines: {node: '>=10'} + + lines-and-columns@1.2.4: + resolution: {integrity: sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==} + + lint-staged@15.0.2: + resolution: {integrity: sha512-vnEy7pFTHyVuDmCAIFKR5QDO8XLVlPFQQyujQ/STOxe40ICWqJ6knS2wSJ/ffX/Lw0rz83luRDh+ET7toN+rOw==} + engines: {node: '>=18.12.0'} + hasBin: true + + listr2@7.0.2: + resolution: {integrity: sha512-rJysbR9GKIalhTbVL2tYbF2hVyDnrf7pFUZBwjPaMIdadYHmeT+EVi/Bu3qd7ETQPahTotg2WRCatXwRBW554g==} + engines: {node: '>=16.0.0'} + + lmdb@2.7.11: + resolution: {integrity: sha512-x9bD4hVp7PFLUoELL8RglbNXhAMt5CYhkmss+CEau9KlNoilsTzNi9QDsPZb3KMpOGZXG6jmXhW3bBxE2XVztw==} + hasBin: true + + load-yaml-file@0.2.0: + resolution: {integrity: sha512-OfCBkGEw4nN6JLtgRidPX6QxjBQGQf72q3si2uvqyFEMbycSFFHwAZeXx6cJgFM9wmLrf9zBwCP3Ivqa+LLZPw==} + engines: {node: '>=6'} + + loader-utils@3.2.0: + resolution: {integrity: sha512-HVl9ZqccQihZ7JM85dco1MvO9G+ONvxoGa9rkhzFsneGLKSUg1gJf9bWzhRhcvm2qChhWpebQhP44qxjKIUCaQ==} + engines: {node: '>= 12.13.0'} + + local-pkg@0.5.0: + resolution: {integrity: sha512-ok6z3qlYyCDS4ZEU27HaU6x/xZa9Whf8jD4ptH5UZTQYZVYeb9bnZ3ojVhiJNLiXK1Hfc0GNbLXcmZ5plLDDBg==} + engines: {node: '>=14'} + + locate-path@5.0.0: + resolution: {integrity: sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==} + engines: {node: '>=8'} + + locate-path@6.0.0: + resolution: {integrity: sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==} + engines: {node: '>=10'} + + locate-path@7.2.0: + resolution: {integrity: sha512-gvVijfZvn7R+2qyPX8mAuKcFGDf6Nc61GdvGafQsHL0sBIxfKzA+usWn4GFC/bk+QdwPUD4kWFJLhElipq+0VA==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + + lodash-es@4.17.21: + resolution: {integrity: sha512-mKnC+QJ9pWVzv+C4/U3rRsHapFfHvQFoFB92e52xeyGMcX6/OlIl78je1u8vePzYZSkkogMPJ2yjxxsb89cxyw==} + + lodash.camelcase@4.3.0: + resolution: {integrity: sha512-TwuEnCnxbc3rAvhf/LbG7tJUDzhqXyFnv3dtzLOPgCG/hODL7WFnsbwktkD7yUV0RrreP/l1PALq/YSg6VvjlA==} + + lodash.get@4.4.2: + resolution: {integrity: sha512-z+Uw/vLuy6gQe8cfaFWD7p0wVv8fJl3mbzXh33RS+0oW2wvUqiRXiQ69gLWSLpgB5/6sU+r6BlQR0MBILadqTQ==} + + lodash.includes@4.3.0: + resolution: {integrity: sha512-W3Bx6mdkRTGtlJISOvVD/lbqjTlPPUDTMnlXZFnVwi9NKJ6tiAk6LVdlhZMm17VZisqhKcgzpO5Wz91PCt5b0w==} + + lodash.isboolean@3.0.3: + resolution: {integrity: sha512-Bz5mupy2SVbPHURB98VAcw+aHh4vRV5IPNhILUCsOzRmsTmSQ17jIuqopAentWoehktxGd9e/hbIXq980/1QJg==} + + lodash.isempty@4.4.0: + resolution: {integrity: sha512-oKMuF3xEeqDltrGMfDxAPGIVMSSRv8tbRSODbrs4KGsRRLEhrW8N8Rd4DRgB2+621hY8A8XwwrTVhXWpxFvMzg==} + + lodash.isinteger@4.0.4: + resolution: {integrity: sha512-DBwtEWN2caHQ9/imiNeEA5ys1JoRtRfY3d7V9wkqtbycnAmTvRRmbHKDV4a0EYc678/dia0jrte4tjYwVBaZUA==} + + lodash.isnumber@3.0.3: + resolution: {integrity: sha512-QYqzpfwO3/CWf3XP+Z+tkQsfaLL/EnUlXWVkIk5FUPc4sBdTehEqZONuyRt2P67PXAk+NXmTBcc97zw9t1FQrw==} + + lodash.isplainobject@4.0.6: + resolution: {integrity: sha512-oSXzaWypCMHkPC3NvBEaPHf0KsA5mvPrOPgQWDsbg8n7orZ290M0BmC/jgRZ4vcJ6DTAhjrsSYgdsW/F+MFOBA==} + + lodash.isstring@4.0.1: + resolution: {integrity: sha512-0wJxfxH1wgO3GrbuP+dTTk7op+6L41QCXbGINEmD+ny/G/eCqGzxyCsh7159S+mgDDcoarnBw6PC1PS5+wUGgw==} + + lodash.kebabcase@4.1.1: + resolution: {integrity: sha512-N8XRTIMMqqDgSy4VLKPnJ/+hpGZN+PHQiJnSenYqPaVV/NCqEogTnAdZLQiGKhxX+JCs8waWq2t1XHWKOmlY8g==} + + lodash.merge@4.6.2: + resolution: {integrity: sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==} + + lodash.mergewith@4.6.2: + resolution: {integrity: sha512-GK3g5RPZWTRSeLSpgP8Xhra+pnjBC56q9FZYe1d5RN3TJ35dbkGy3YqBSMbyCrlbi+CM9Z3Jk5yTL7RCsqboyQ==} + + lodash.once@4.1.1: + resolution: {integrity: sha512-Sb487aTOCr9drQVL8pIxOzVhafOjZN9UU54hiN8PU3uAiSV7lx1yYNpbNmex2PK6dSJoNTSJUUswT651yww3Mg==} + + lodash.snakecase@4.1.1: + resolution: {integrity: sha512-QZ1d4xoBHYUeuouhEq3lk3Uq7ldgyFXGBhg04+oRLnIz8o9T65Eh+8YdroUwn846zchkA9yDsDl5CVVaV2nqYw==} + + lodash.sortby@4.7.0: + resolution: {integrity: sha512-HDWXG8isMntAyRF5vZ7xKuEvOhT4AhlRt/3czTSjvGUxjYCBVRQY48ViDHyfYz9VIoBkW4TMGQNapx+l3RUwdA==} + + lodash.startcase@4.4.0: + resolution: {integrity: sha512-+WKqsK294HMSc2jEbNgpHpd0JfIBhp7rEV4aqXWqFr6AlXov+SlcgB1Fv01y2kGe3Gc8nMW7VA0SrGuSkRfIEg==} + + lodash.transform@4.6.0: + resolution: {integrity: sha512-LO37ZnhmBVx0GvOU/caQuipEh4GN82TcWv3yHlebGDgOxbxiwwzW5Pcx2AcvpIv2WmvmSMoC492yQFNhy/l/UQ==} + + lodash.truncate@4.4.2: + resolution: {integrity: sha512-jttmRe7bRse52OsWIMDLaXxWqRAmtIUccAQ3garviCqJjafXOfNMO0yMfNpdD6zbGaTU0P5Nz7e7gAT6cKmJRw==} + + lodash.uniq@4.5.0: + resolution: {integrity: sha512-xfBaXQd9ryd9dlSDvnvI0lvxfLJlYAZzXomUYzLKtUeOQvOP5piqAWuGtrhWeqaXK9hhoM/iyJc5AV+XfsX3HQ==} + + lodash.upperfirst@4.3.1: + resolution: {integrity: sha512-sReKOYJIJf74dhJONhU4e0/shzi1trVbSWDOhKYE5XV2O+H7Sb2Dihwuc7xWxVl+DgFPyTqIN3zMfT9cq5iWDg==} + + lodash.zip@4.2.0: + resolution: {integrity: sha512-C7IOaBBK/0gMORRBd8OETNx3kmOkgIWIPvyDpZSCTwUrpYmgZwJkjZeOD8ww4xbOUOs4/attY+pciKvadNfFbg==} + + lodash@4.17.21: + resolution: {integrity: sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==} + + log-symbols@5.1.0: + resolution: {integrity: sha512-l0x2DvrW294C9uDCoQe1VSU4gf529FkSZ6leBl4TiqZH/e+0R7hSfHQBNut2mNygDgHwvYHfFLn6Oxb3VWj2rA==} + engines: {node: '>=12'} + + log-symbols@6.0.0: + resolution: {integrity: sha512-i24m8rpwhmPIS4zscNzK6MSEhk0DUWa/8iYQWxhffV8jkI4Phvs3F+quL5xvS0gdQR0FyTCMMH33Y78dDTzzIw==} + engines: {node: '>=18'} + + log-update@5.0.1: + resolution: {integrity: sha512-5UtUDQ/6edw4ofyljDNcOVJQ4c7OjDro4h3y8e1GQL5iYElYclVHJ3zeWchylvMaKnDbDilC8irOVyexnA/Slw==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + + longest-streak@3.0.1: + resolution: {integrity: sha512-cHlYSUpL2s7Fb3394mYxwTYj8niTaNHUCLr0qdiCXQfSjfuA7CKofpX2uSwEfFDQ0EB7JcnMnm+GjbqqoinYYg==} + + loose-envify@1.4.0: + resolution: {integrity: sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==} + hasBin: true + + loupe@2.3.7: + resolution: {integrity: sha512-zSMINGVYkdpYSOBmLi0D1Uo7JU9nVdQKrHxC8eYlV+9YKK9WePqAlL7lSlorG/U2Fw1w0hTBmaa/jrQ3UbPHtA==} + + lower-case@2.0.2: + resolution: {integrity: sha512-7fm3l3NAF9WfN6W3JOmf5drwpVqX78JtoGJ3A6W0a6ZnldM41w2fV5D490psKFTpMds8TJse/eHLFFsNHHjHgg==} + + lowercase-keys@1.0.1: + resolution: {integrity: sha512-G2Lj61tXDnVFFOi8VZds+SoQjtQC3dgokKdDG2mTm1tx4m50NUHBOZSBwQQHyy0V12A0JTG4icfZQH+xPyh8VA==} + engines: {node: '>=0.10.0'} + + lowercase-keys@3.0.0: + resolution: {integrity: sha512-ozCC6gdQ+glXOQsveKD0YsDy8DSQFjDTz4zyzEHNV5+JP5D62LmfDZ6o1cycFx9ouG940M5dE8C8CTewdj2YWQ==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + + lowlight@1.20.0: + resolution: {integrity: sha512-8Ktj+prEb1RoCPkEOrPMYUN/nCggB7qAWe3a7OpMjWQkh3l2RD5wKRQ+o8Q8YuI9RG/xs95waaI/E6ym/7NsTw==} + + lru-cache@10.0.0: + resolution: {integrity: sha512-svTf/fzsKHffP42sujkO/Rjs37BCIsQVRCeNYIm9WN8rgT7ffoUnRtZCqU+6BqcSBdv8gwJeTz8knJpgACeQMw==} + engines: {node: 14 || >=16.14} + + lru-cache@10.2.0: + resolution: {integrity: sha512-2bIM8x+VAf6JT4bKAljS1qUWgMsqZRPGJS6FSahIMPVvctcNhyVp7AJu7quxOW9jwkryBReKZY5tY5JYv2n/7Q==} + engines: {node: 14 || >=16.14} + + lru-cache@4.1.5: + resolution: {integrity: sha512-sWZlbEP2OsHNkXrMl5GYk/jKk70MBng6UU4YI/qGDYbgf6YbP4EvmqISbXCoJiRKs+1bSpFHVgQxvJ17F2li5g==} + + lru-cache@5.1.1: + resolution: {integrity: sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==} + + lru-cache@6.0.0: + resolution: {integrity: sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==} + engines: {node: '>=10'} + + lru-cache@7.18.3: + resolution: {integrity: sha512-jumlc0BIUrS3qJGgIkWZsyfAM7NCWiBcCDhnd+3NNM5KbBmLTgHVfWBcg6W+rLUsIpzpERPsvwUP7CckAQSOoA==} + engines: {node: '>=12'} + + lz-string@1.5.0: + resolution: {integrity: sha512-h5bgJWpxJNswbU7qCrV0tIKQCaS3blPDrqKWx+QxzuzL1zGUzij9XCWLrSLsJPu5t+eWA/ycetzYAO5IOMcWAQ==} + hasBin: true + + magic-string@0.30.7: + resolution: {integrity: sha512-8vBuFF/I/+OSLRmdf2wwFCJCz+nSn0m6DPvGH1fS/KiQoSaR+sETbov0eIk9KhEKy8CYqIkIAnbohxT/4H0kuA==} + engines: {node: '>=12'} + + magicast@0.3.3: + resolution: {integrity: sha512-ZbrP1Qxnpoes8sz47AM0z08U+jW6TyRgZzcWy3Ma3vDhJttwMwAFDMMQFobwdBxByBD46JYmxRzeF7w2+wJEuw==} + + make-dir@4.0.0: + resolution: {integrity: sha512-hXdUTZYIVOt1Ex//jAQi+wTZZpUpwBj/0QsOzqegb3rGMMeJiSEu5xLHnYfBrRV4RH2+OCSOO95Is/7x1WJ4bw==} + engines: {node: '>=10'} + + make-error@1.3.6: + resolution: {integrity: sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==} + + makeerror@1.0.12: + resolution: {integrity: sha512-JmqCvUhmt43madlpFzG4BQzG2Z3m6tvQDNKdClZnO3VbIudJYmxsT0FNJMeiB2+JTSlTQTSbU8QdesVmwJcmLg==} + + map-obj@1.0.1: + resolution: {integrity: sha512-7N/q3lyZ+LVCp7PzuxrJr4KMbBE2hW7BT7YNia330OFxIf4d3r5zVpicP2650l7CPN6RM9zOJRl3NGpqSiw3Eg==} + engines: {node: '>=0.10.0'} + + map-obj@4.3.0: + resolution: {integrity: sha512-hdN1wVrZbb29eBGiGjJbeP8JbKjq1urkHJ/LIP/NY48MZ1QVXUsQBV1G1zvYFHn1XE06cwjBsOI2K3Ulnj1YXQ==} + engines: {node: '>=8'} + + map-obj@5.0.0: + resolution: {integrity: sha512-2L3MIgJynYrZ3TYMriLDLWocz15okFakV6J12HXvMXDHui2x/zgChzg1u9mFFGbbGWE+GsLpQByt4POb9Or+uA==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + + markdown-escapes@1.0.4: + resolution: {integrity: sha512-8z4efJYk43E0upd0NbVXwgSTQs6cT3T06etieCMEg7dRbzCbxUCK/GHlX8mhHRDcp+OLlHkPKsvqQTCvsRl2cg==} + + markdown-table@3.0.2: + resolution: {integrity: sha512-y8j3a5/DkJCmS5x4dMCQL+OR0+2EAq3DOtio1COSHsmW2BGXnNCK3v12hJt1LrUz5iZH5g0LmuYOjDdI+czghA==} + + material-colors@1.2.6: + resolution: {integrity: sha512-6qE4B9deFBIa9YSpOc9O0Sgc43zTeVYbgDT5veRKSlB2+ZuHNoVVxA1L/ckMUayV9Ay9y7Z/SZCLcGteW9i7bg==} + + mathml-tag-names@2.1.3: + resolution: {integrity: sha512-APMBEanjybaPzUrfqU0IMU5I0AswKMH7k8OTLs0vvV4KZpExkTkY87nR/zpbuTPj+gARop7aGUbl11pnDfW6xg==} + + mdast-squeeze-paragraphs@4.0.0: + resolution: {integrity: sha512-zxdPn69hkQ1rm4J+2Cs2j6wDEv7O17TfXTJ33tl/+JPIoEmtV9t2ZzBM5LPHE8QlHsmVD8t3vPKCyY3oH+H8MQ==} + + mdast-util-definitions@4.0.0: + resolution: {integrity: sha512-k8AJ6aNnUkB7IE+5azR9h81O5EQ/cTDXtWdMq9Kk5KcEW/8ritU5CeLg/9HhOC++nALHBlaogJ5jz0Ybk3kPMQ==} + + mdast-util-find-and-replace@3.0.1: + resolution: {integrity: sha512-SG21kZHGC3XRTSUhtofZkBzZTJNM5ecCi0SK2IMKmSXR8vO3peL+kb1O0z7Zl83jKtutG4k5Wv/W7V3/YHvzPA==} + + mdast-util-from-markdown@2.0.0: + resolution: {integrity: sha512-n7MTOr/z+8NAX/wmhhDji8O3bRvPTV/U0oTCaZJkjhPSKTPhS3xufVhKGF8s1pJ7Ox4QgoIU7KHseh09S+9rTA==} + + mdast-util-gfm-autolink-literal@2.0.0: + resolution: {integrity: sha512-FyzMsduZZHSc3i0Px3PQcBT4WJY/X/RCtEJKuybiC6sjPqLv7h1yqAkmILZtuxMSsUyaLUWNp71+vQH2zqp5cg==} + + mdast-util-gfm-footnote@2.0.0: + resolution: {integrity: sha512-5jOT2boTSVkMnQ7LTrd6n/18kqwjmuYqo7JUPe+tRCY6O7dAuTFMtTPauYYrMPpox9hlN0uOx/FL8XvEfG9/mQ==} + + mdast-util-gfm-strikethrough@2.0.0: + resolution: {integrity: sha512-mKKb915TF+OC5ptj5bJ7WFRPdYtuHv0yTRxK2tJvi+BDqbkiG7h7u/9SI89nRAYcmap2xHQL9D+QG/6wSrTtXg==} + + mdast-util-gfm-table@2.0.0: + resolution: {integrity: sha512-78UEvebzz/rJIxLvE7ZtDd/vIQ0RHv+3Mh5DR96p7cS7HsBhYIICDBCu8csTNWNO6tBWfqXPWekRuj2FNOGOZg==} + + mdast-util-gfm-task-list-item@2.0.0: + resolution: {integrity: sha512-IrtvNvjxC1o06taBAVJznEnkiHxLFTzgonUdy8hzFVeDun0uTjxxrRGVaNFqkU1wJR3RBPEfsxmU6jDWPofrTQ==} + + mdast-util-gfm@3.0.0: + resolution: {integrity: sha512-dgQEX5Amaq+DuUqf26jJqSK9qgixgd6rYDHAv4aTBuA92cTknZlKpPfa86Z/s8Dj8xsAQpFfBmPUHWJBWqS4Bw==} + + mdast-util-phrasing@4.0.0: + resolution: {integrity: sha512-xadSsJayQIucJ9n053dfQwVu1kuXg7jCTdYsMK8rqzKZh52nLfSH/k0sAxE0u+pj/zKZX+o5wB+ML5mRayOxFA==} + + mdast-util-to-hast@10.0.1: + resolution: {integrity: sha512-BW3LM9SEMnjf4HXXVApZMt8gLQWVNXc3jryK0nJu/rOXPOnlkUjmdkDlmxMirpbU9ILncGFIwLH/ubnWBbcdgA==} + + mdast-util-to-hast@13.0.2: + resolution: {integrity: sha512-U5I+500EOOw9e3ZrclN3Is3fRpw8c19SMyNZlZ2IS+7vLsNzb2Om11VpIVOR+/0137GhZsFEF6YiKD5+0Hr2Og==} + + mdast-util-to-markdown@2.1.0: + resolution: {integrity: sha512-SR2VnIEdVNCJbP6y7kVTJgPLifdr8WEU440fQec7qHoHOUz/oJ2jmNRqdDQ3rbiStOXb2mCDGTuwsK5OPUgYlQ==} + + mdast-util-to-string@4.0.0: + resolution: {integrity: sha512-0H44vDimn51F0YwvxSJSm0eCDOJTRlmN0R1yBh4HLj9wiV1Dn0QoXGbvFAWj2hSItVTlCmBF1hqKlIyUBVFLPg==} + + mdn-data@2.0.14: + resolution: {integrity: sha512-dn6wd0uw5GsdswPFfsgMp5NSB0/aDe6fK94YJV/AJDYXL6HVLWBsxeq7js7Ad+mU2K9LAlwpk6kN2D5mwCPVow==} + + mdn-data@2.0.30: + resolution: {integrity: sha512-GaqWWShW4kv/G9IEucWScBx9G1/vsFZZJUO+tD26M8J8z3Kw5RDQjaoZe03YAClgeS/SWPOcb4nkFBTEi5DUEA==} + + mdurl@1.0.1: + resolution: {integrity: sha512-/sKlQJCBYVY9Ers9hqzKou4H6V5UWc/M59TH2dvkt+84itfnq7uFOMLpOiOS4ujvHP4etln18fmIxA5R5fll0g==} + + media-typer@0.3.0: + resolution: {integrity: sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g=} + engines: {node: '>= 0.6'} + + meow@10.1.5: + resolution: {integrity: sha512-/d+PQ4GKmGvM9Bee/DPa8z3mXs/pkvJE2KEThngVNOqtmljC6K7NMPxtc2JeZYTmpWb9k/TmxjeL18ez3h7vCw==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + + meow@12.1.1: + resolution: {integrity: sha512-BhXM0Au22RwUneMPwSCnyhTOizdWoIEPU9sp0Aqa1PnDMR5Wv2FGXYDjuzJEIX+Eo2Rb8xuYe5jrnm5QowQFkw==} + engines: {node: '>=16.10'} + + meow@6.1.1: + resolution: {integrity: sha512-3YffViIt2QWgTy6Pale5QpopX/IvU3LPL03jOTqp6pGj3VjesdO/U8CuHMKpnQr4shCNCM5fd5XFFvIIl6JBHg==} + engines: {node: '>=8'} + + merge-descriptors@1.0.1: + resolution: {integrity: sha512-cCi6g3/Zr1iqQi6ySbseM1Xvooa98N0w31jzUYrXPX2xqObmFGHJ0tQ5u74H3mVh7wLouTseZyYIq39g8cNp1w==} + + merge-stream@2.0.0: + resolution: {integrity: sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==} + + merge2@1.4.1: + resolution: {integrity: sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==} + engines: {node: '>= 8'} + + methods@1.1.2: + resolution: {integrity: sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w==} + engines: {node: '>= 0.6'} + + micromark-core-commonmark@2.0.0: + resolution: {integrity: sha512-jThOz/pVmAYUtkroV3D5c1osFXAMv9e0ypGDOIZuCeAe91/sD6BoE2Sjzt30yuXtwOYUmySOhMas/PVyh02itA==} + + micromark-extension-gfm-autolink-literal@2.0.0: + resolution: {integrity: sha512-rTHfnpt/Q7dEAK1Y5ii0W8bhfJlVJFnJMHIPisfPK3gpVNuOP0VnRl96+YJ3RYWV/P4gFeQoGKNlT3RhuvpqAg==} + + micromark-extension-gfm-footnote@2.0.0: + resolution: {integrity: sha512-6Rzu0CYRKDv3BfLAUnZsSlzx3ak6HAoI85KTiijuKIz5UxZxbUI+pD6oHgw+6UtQuiRwnGRhzMmPRv4smcz0fg==} + + micromark-extension-gfm-strikethrough@2.0.0: + resolution: {integrity: sha512-c3BR1ClMp5fxxmwP6AoOY2fXO9U8uFMKs4ADD66ahLTNcwzSCyRVU4k7LPV5Nxo/VJiR4TdzxRQY2v3qIUceCw==} + + micromark-extension-gfm-table@2.0.0: + resolution: {integrity: sha512-PoHlhypg1ItIucOaHmKE8fbin3vTLpDOUg8KAr8gRCF1MOZI9Nquq2i/44wFvviM4WuxJzc3demT8Y3dkfvYrw==} + + micromark-extension-gfm-tagfilter@2.0.0: + resolution: {integrity: sha512-xHlTOmuCSotIA8TW1mDIM6X2O1SiX5P9IuDtqGonFhEK0qgRI4yeC6vMxEV2dgyr2TiD+2PQ10o+cOhdVAcwfg==} + + micromark-extension-gfm-task-list-item@2.0.1: + resolution: {integrity: sha512-cY5PzGcnULaN5O7T+cOzfMoHjBW7j+T9D2sucA5d/KbsBTPcYdebm9zUd9zzdgJGCwahV+/W78Z3nbulBYVbTw==} + + micromark-extension-gfm@3.0.0: + resolution: {integrity: sha512-vsKArQsicm7t0z2GugkCKtZehqUm31oeGBV/KVSorWSy8ZlNAv7ytjFhvaryUiCUJYqs+NoE6AFhpQvBTM6Q4w==} + + micromark-factory-destination@2.0.0: + resolution: {integrity: sha512-j9DGrQLm/Uhl2tCzcbLhy5kXsgkHUrjJHg4fFAeoMRwJmJerT9aw4FEhIbZStWN8A3qMwOp1uzHr4UL8AInxtA==} + + micromark-factory-label@2.0.0: + resolution: {integrity: sha512-RR3i96ohZGde//4WSe/dJsxOX6vxIg9TimLAS3i4EhBAFx8Sm5SmqVfR8E87DPSR31nEAjZfbt91OMZWcNgdZw==} + + micromark-factory-space@2.0.0: + resolution: {integrity: sha512-TKr+LIDX2pkBJXFLzpyPyljzYK3MtmllMUMODTQJIUfDGncESaqB90db9IAUcz4AZAJFdd8U9zOp9ty1458rxg==} + + micromark-factory-title@2.0.0: + resolution: {integrity: sha512-jY8CSxmpWLOxS+t8W+FG3Xigc0RDQA9bKMY/EwILvsesiRniiVMejYTE4wumNc2f4UbAa4WsHqe3J1QS1sli+A==} + + micromark-factory-whitespace@2.0.0: + resolution: {integrity: sha512-28kbwaBjc5yAI1XadbdPYHX/eDnqaUFVikLwrO7FDnKG7lpgxnvk/XGRhX/PN0mOZ+dBSZ+LgunHS+6tYQAzhA==} + + micromark-util-character@2.0.1: + resolution: {integrity: sha512-3wgnrmEAJ4T+mGXAUfMvMAbxU9RDG43XmGce4j6CwPtVxB3vfwXSZ6KhFwDzZ3mZHhmPimMAXg71veiBGzeAZw==} + + micromark-util-chunked@2.0.0: + resolution: {integrity: sha512-anK8SWmNphkXdaKgz5hJvGa7l00qmcaUQoMYsBwDlSKFKjc6gjGXPDw3FNL3Nbwq5L8gE+RCbGqTw49FK5Qyvg==} + + micromark-util-classify-character@2.0.0: + resolution: {integrity: sha512-S0ze2R9GH+fu41FA7pbSqNWObo/kzwf8rN/+IGlW/4tC6oACOs8B++bh+i9bVyNnwCcuksbFwsBme5OCKXCwIw==} + + micromark-util-combine-extensions@2.0.0: + resolution: {integrity: sha512-vZZio48k7ON0fVS3CUgFatWHoKbbLTK/rT7pzpJ4Bjp5JjkZeasRfrS9wsBdDJK2cJLHMckXZdzPSSr1B8a4oQ==} + + micromark-util-decode-numeric-character-reference@2.0.0: + resolution: {integrity: sha512-pIgcsGxpHEtTG/rPJRz/HOLSqp5VTuIIjXlPI+6JSDlK2oljApusG6KzpS8AF0ENUMCHlC/IBb5B9xdFiVlm5Q==} + + micromark-util-decode-string@2.0.0: + resolution: {integrity: sha512-r4Sc6leeUTn3P6gk20aFMj2ntPwn6qpDZqWvYmAG6NgvFTIlj4WtrAudLi65qYoaGdXYViXYw2pkmn7QnIFasA==} + + micromark-util-encode@2.0.0: + resolution: {integrity: sha512-pS+ROfCXAGLWCOc8egcBvT0kf27GoWMqtdarNfDcjb6YLuV5cM3ioG45Ys2qOVqeqSbjaKg72vU+Wby3eddPsA==} + + micromark-util-html-tag-name@2.0.0: + resolution: {integrity: sha512-xNn4Pqkj2puRhKdKTm8t1YHC/BAjx6CEwRFXntTaRf/x16aqka6ouVoutm+QdkISTlT7e2zU7U4ZdlDLJd2Mcw==} + + micromark-util-normalize-identifier@2.0.0: + resolution: {integrity: sha512-2xhYT0sfo85FMrUPtHcPo2rrp1lwbDEEzpx7jiH2xXJLqBuy4H0GgXk5ToU8IEwoROtXuL8ND0ttVa4rNqYK3w==} + + micromark-util-resolve-all@2.0.0: + resolution: {integrity: sha512-6KU6qO7DZ7GJkaCgwBNtplXCvGkJToU86ybBAUdavvgsCiG8lSSvYxr9MhwmQ+udpzywHsl4RpGJsYWG1pDOcA==} + + micromark-util-sanitize-uri@2.0.0: + resolution: {integrity: sha512-WhYv5UEcZrbAtlsnPuChHUAsu/iBPOVaEVsntLBIdpibO0ddy8OzavZz3iL2xVvBZOpolujSliP65Kq0/7KIYw==} + + micromark-util-subtokenize@2.0.0: + resolution: {integrity: sha512-vc93L1t+gpR3p8jxeVdaYlbV2jTYteDje19rNSS/H5dlhxUYll5Fy6vJ2cDwP8RnsXi818yGty1ayP55y3W6fg==} + + micromark-util-symbol@2.0.0: + resolution: {integrity: sha512-8JZt9ElZ5kyTnO94muPxIGS8oyElRJaiJO8EzV6ZSyGQ1Is8xwl4Q45qU5UOg+bGH4AikWziz0iN4sFLWs8PGw==} + + micromark-util-types@2.0.0: + resolution: {integrity: sha512-oNh6S2WMHWRZrmutsRmDDfkzKtxF+bc2VxLC9dvtrDIRFln627VsFP6fLMgTryGDljgLPjkrzQSDcPrjPyDJ5w==} + + micromark@4.0.0: + resolution: {integrity: sha512-o/sd0nMof8kYff+TqcDx3VSrgBTcZpSvYcAHIfHhv5VAuNmisCxjhx6YmxS8PFEpb9z5WKWKPdzf0jM23ro3RQ==} + + micromatch@4.0.5: + resolution: {integrity: sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==} + engines: {node: '>=8.6'} + + mime-db@1.52.0: + resolution: {integrity: sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==} + engines: {node: '>= 0.6'} + + mime-types@2.1.35: + resolution: {integrity: sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==} + engines: {node: '>= 0.6'} + + mime@1.6.0: + resolution: {integrity: sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==} + engines: {node: '>=4'} + hasBin: true + + mime@2.6.0: + resolution: {integrity: sha512-USPkMeET31rOMiarsBNIHZKLGgvKc/LrjofAnBlOttf5ajRvqiRA8QsenbcooctK6d6Ts6aqZXBA+XbkKthiQg==} + engines: {node: '>=4.0.0'} + hasBin: true + + mime@3.0.0: + resolution: {integrity: sha512-jSCU7/VB1loIWBZe14aEYHU/+1UMEHoaO7qxCOVJOw9GgH72VAWppxNcjU+x9a2k3GSIBXNKxXQFqRvvZ7vr3A==} + engines: {node: '>=10.0.0'} + hasBin: true + + mimic-fn@2.1.0: + resolution: {integrity: sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==} + engines: {node: '>=6'} + + mimic-fn@4.0.0: + resolution: {integrity: sha512-vqiC06CuhBTUdZH+RYl8sFrL096vA45Ok5ISO6sE/Mr1jRbGH4Csnhi8f3wKVl7x8mO4Au7Ir9D3Oyv1VYMFJw==} + engines: {node: '>=12'} + + mimic-response@3.1.0: + resolution: {integrity: sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ==} + engines: {node: '>=10'} + + mimic-response@4.0.0: + resolution: {integrity: sha512-e5ISH9xMYU0DzrT+jl8q2ze9D6eWBto+I8CNpe+VI+K2J/F/k3PdkdTdz4wvGVH4NTpo+NRYTVIuMQEMMcsLqg==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + + min-indent@1.0.1: + resolution: {integrity: sha512-I9jwMn07Sy/IwOj3zVkVik2JTvgpaykDZEigL6Rx6N9LbMywwUSMtxET+7lVoDLLd3O3IXwJwvuuns8UB/HeAg==} + engines: {node: '>=4'} + + minimatch@3.1.2: + resolution: {integrity: sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==} + + minimatch@5.1.6: + resolution: {integrity: sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==} + engines: {node: '>=10'} + + minimatch@9.0.4: + resolution: {integrity: sha512-KqWh+VchfxcMNRAJjj2tnsSJdNbHsVgnkBhTNrW7AjVo6OvLtxw8zfT9oLw1JSohlFzJ8jCoTgaoXvJ+kHt6fw==} + engines: {node: '>=16 || 14 >=14.17'} + + minimist-options@4.1.0: + resolution: {integrity: sha512-Q4r8ghd80yhO/0j1O3B2BjweX3fiHg9cdOwjJd2J76Q135c+NDxGCqdYKQ1SKBuFfgWbAUzBfvYjPUEeNgqN1A==} + engines: {node: '>= 6'} + + minimist@1.2.8: + resolution: {integrity: sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==} + + minipass@4.2.8: + resolution: {integrity: sha512-fNzuVyifolSLFL4NzpF+wEF4qrgqaaKX0haXPQEdQ7NKAN+WecoKMHV09YcuL/DHxrUsYQOK3MiuDf7Ip2OXfQ==} + engines: {node: '>=8'} + + minipass@5.0.0: + resolution: {integrity: sha512-3FnjYuehv9k6ovOEbyOswadCDPX1piCfhV8ncmYtHOjuPwylVWsghTLo7rabjC3Rx5xD4HDx8Wm1xnMF7S5qFQ==} + engines: {node: '>=8'} + + minipass@7.0.4: + resolution: {integrity: sha512-jYofLM5Dam9279rdkWzqHozUo4ybjdZmCsDHePy5V/PbBcVMiSZR97gmAy45aqi8CK1lG2ECd356FU86avfwUQ==} + engines: {node: '>=16 || 14 >=14.17'} + + minizlib@3.0.1: + resolution: {integrity: sha512-umcy022ILvb5/3Djuu8LWeqUa8D68JaBzlttKeMWen48SjabqS3iY5w/vzeMzMUNhLDifyhbOwKDSznB1vvrwg==} + engines: {node: '>= 18'} + + mitt@3.0.1: + resolution: {integrity: sha512-vKivATfr97l2/QBCYAkXYDbrIWPM2IIKEl7YPhjCvKlG3kE2gm+uBo6nEXK3M5/Ffh/FLpKExzOQ3JJoJGFKBw==} + + mixme@0.5.4: + resolution: {integrity: sha512-3KYa4m4Vlqx98GPdOHghxSdNtTvcP8E0kkaJ5Dlh+h2DRzF7zpuVVcA8B0QpKd11YJeP9QQ7ASkKzOeu195Wzw==} + engines: {node: '>= 8.0.0'} + + mkdirp@3.0.1: + resolution: {integrity: sha512-+NsyUUAZDmo6YVHzL/stxSu3t9YS1iljliy3BSDrXJ/dkn1KYdmtZODGGjLcc9XLgVVpH4KshHB8XmZgMhaBXg==} + engines: {node: '>=10'} + hasBin: true + + mlly@1.6.1: + resolution: {integrity: sha512-vLgaHvaeunuOXHSmEbZ9izxPx3USsk8KCQ8iC+aTlp5sKRSoZvwhHh5L9VbKSaVC6sJDqbyohIS76E2VmHIPAA==} + + module-details-from-path@1.0.3: + resolution: {integrity: sha512-ySViT69/76t8VhE1xXHK6Ch4NcDd26gx0MzKXLO+F7NOtnqH68d9zF94nT8ZWSxXh8ELOERsnJO/sWt1xZYw5A==} + + monaco-editor@0.47.0: + resolution: {integrity: sha512-VabVvHvQ9QmMwXu4du008ZDuyLnHs9j7ThVFsiJoXSOQk18+LF89N4ADzPbFenm0W4V2bGHnFBztIRQTgBfxzw==} + + ms@2.1.2: + resolution: {integrity: sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==} + + ms@2.1.3: + resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==} + + msgpackr-extract@3.0.2: + resolution: {integrity: sha512-SdzXp4kD/Qf8agZ9+iTu6eql0m3kWm1A2y1hkpTeVNENutaB0BwHlSvAIaMxwntmRUAUjon2V4L8Z/njd0Ct8A==} + hasBin: true + + msgpackr@1.8.5: + resolution: {integrity: sha512-mpPs3qqTug6ahbblkThoUY2DQdNXcm4IapwOS3Vm/87vmpzLVelvp9h3It1y9l1VPpiFLV11vfOXnmeEwiIXwg==} + + mute-stream@0.0.8: + resolution: {integrity: sha512-nnbWWOkoWyUsTjKrhgD0dcz22mdkSnpYqbEjIm2nhwhuxlSkpywJmBo8h0ZqJdkp73mb90SssHkN4rsRaBAfAA==} + + nanoid@3.3.6: + resolution: {integrity: sha512-BGcqMMJuToF7i1rt+2PWSNVnWIkGCU78jBG3RxO/bZlnZPK2Cmi2QaffxGO/2RvWi9sL+FAiRiXMgsyxQ1DIDA==} + engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1} + hasBin: true + + nanoid@3.3.7: + resolution: {integrity: sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g==} + engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1} + hasBin: true + + nanoid@4.0.2: + resolution: {integrity: sha512-7ZtY5KTCNheRGfEFxnedV5zFiORN1+Y1N6zvPTnHQd8ENUvfaDBeuJDZb2bN/oXwXxu3qkTXDzy57W5vAmDTBw==} + engines: {node: ^14 || ^16 || >=18} + hasBin: true + + nanoid@5.0.1: + resolution: {integrity: sha512-vWeVtV5Cw68aML/QaZvqN/3QQXc6fBfIieAlu05m7FZW2Dgb+3f0xc0TTxuJW+7u30t7iSDTV/j3kVI0oJqIfQ==} + engines: {node: ^18 || >=20} + hasBin: true + + nanoid@5.0.7: + resolution: {integrity: sha512-oLxFY2gd2IqnjcYyOXD8XGCftpGtZP2AbHbOkthDkvRywH5ayNtPVy9YlOPcHckXzbLTCHpkb7FB+yuxKV13pQ==} + engines: {node: ^18 || >=20} + hasBin: true + + natural-compare@1.4.0: + resolution: {integrity: sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==} + + negotiator@0.6.2: + resolution: {integrity: sha512-hZXc7K2e+PgeI1eDBe/10Ard4ekbfrrqG8Ep+8Jmf4JID2bNg7NvCPOZN+kfF574pFQI7mum2AUqDidoKqcTOw==} + engines: {node: '>= 0.6'} + + negotiator@0.6.3: + resolution: {integrity: sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==} + engines: {node: '>= 0.6'} + + netmask@2.0.2: + resolution: {integrity: sha512-dBpDMdxv9Irdq66304OLfEmQ9tbNRFnFTuZiLo+bD+r332bBmMJ8GBLXklIXXgxd3+v9+KUnZaUR5PJMa75Gsg==} + engines: {node: '>= 0.4.0'} + + nise@5.1.5: + resolution: {integrity: sha512-VJuPIfUFaXNRzETTQEEItTOP8Y171ijr+JLq42wHes3DiryR8vT+1TXQW/Rx8JNUhyYYWyIvjXTU6dOhJcs9Nw==} + + no-case@3.0.4: + resolution: {integrity: sha512-fgAN3jGAh+RoxUGZHTSOLJIqUc2wmoBwGR4tbpNAKmmovFoWq0OdRkb0VkldReO2a2iBT/OEulG9XSUc10r3zg==} + + no-case@4.0.0: + resolution: {integrity: sha512-WmS3EUGw+vXHlTgiUPi3NzbZNwH6+uGX0QLGgqG+aFSJ5rkX/Ee0nuwHBJfZTfQwwR8lGO819NEIwQ7CGhkdEQ==} + deprecated: Use `change-case` + + nock@13.3.1: + resolution: {integrity: sha512-vHnopocZuI93p2ccivFyGuUfzjq2fxNyNurp7816mlT5V5HF4SzXu8lvLrVzBbNqzs+ODooZ6OksuSUNM7Njkw==} + engines: {node: '>= 10.13'} + + nock@14.0.0-beta.5: + resolution: {integrity: sha512-u255tf4DYvyErTlPZA9uTfXghiZZy+NflUOFONPVKZ5tP0yaHwKig28zyFOLhu8y5YcCRC+V5vDk4HHileh2iw==} + engines: {node: '>= 18'} + + nock@14.0.0-beta.6: + resolution: {integrity: sha512-b7lc7qvj1dQzxtbU7TqyTMnKbNKwGQd585xsRtcCZOv3I/yOK9Vwv4nOgnLFxFtX9m1yjhQDRbgqFCqNh9HuEw==} + engines: {node: '>= 18'} + + node-addon-api@3.2.1: + resolution: {integrity: sha512-mmcei9JghVNDYydghQmeDX8KoAm0FAiYyIcUt/N4nhyAipB17pllZQDOJD2fotxABnt4Mdz+dKTO7eftLg4d0A==} + + node-addon-api@4.3.0: + resolution: {integrity: sha512-73sE9+3UaLYYFmDsFZnqCInzPyh3MqIwZO9cw58yIqAZhONrrabrYyYe3TuIqtIiOuTXVhsGau8hcrhhwSsDIQ==} + + node-fetch@2.7.0: + resolution: {integrity: sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==} + engines: {node: 4.x || >=6.0.0} + peerDependencies: + encoding: ^0.1.0 + peerDependenciesMeta: + encoding: + optional: true + + node-forge@1.3.1: + resolution: {integrity: sha512-dPEtOeMvF9VMcYV/1Wb8CPoVAXtp6MKMlcbAt4ddqmGqUJ6fQZFXkNZNkNlfevtNkGtaSoXf/vNNNSvgrdXwtA==} + engines: {node: '>= 6.13.0'} + + node-gyp-build-optional-packages@5.0.6: + resolution: {integrity: sha512-2ZJErHG4du9G3/8IWl/l9Bp5BBFy63rno5GVmjQijvTuUZKsl6g8RB4KH/x3NLcV5ZBb4GsXmAuTYr6dRml3Gw==} + hasBin: true + + node-gyp-build-optional-packages@5.0.7: + resolution: {integrity: sha512-YlCCc6Wffkx0kHkmam79GKvDQ6x+QZkMjFGrIMxgFNILFvGSbCp2fCBC55pGTT9gVaz8Na5CLmxt/urtzRv36w==} + hasBin: true + + node-gyp-build-optional-packages@5.1.1: + resolution: {integrity: sha512-+P72GAjVAbTxjjwUmwjVrqrdZROD4nf8KgpBoDxqXXTiYZZt/ud60dE5yvCSr9lRO8e8yv6kgJIC0K0PfZFVQw==} + hasBin: true + + node-gyp-build@4.5.0: + resolution: {integrity: sha512-2iGbaQBV+ITgCz76ZEjmhUKAKVf7xfY1sRl4UiKQspfZMH2h06SyhNsnSVy50cwkFQDGLyif6m/6uFXHkOZ6rg==} + hasBin: true + + node-int64@0.4.0: + resolution: {integrity: sha512-O5lz91xSOeoXP6DulyHfllpq+Eg00MWitZIbtPfoSEvqIHdl5gfcY6hYzDWnj0qD5tz52PI08u9qUvSVeUBeHw==} + + node-mocks-http@1.12.1: + resolution: {integrity: sha512-jrA7Sn3qI6GsHgWtUW3gMj0vO6Yz0nJjzg3jRZYjcfj4tzi8oWPauDK1qHVJoAxTbwuDHF1JiM9GISZ/ocI/ig==} + engines: {node: '>=0.6'} + + node-releases@2.0.14: + resolution: {integrity: sha512-y10wOWt8yZpqXmOgRo77WaHEmhYQYGNA6y421PKsKYWEK8aW+cqAphborZDhqfyKrbZEN92CN1X2KbafY2s7Yw==} + + node-releases@2.0.6: + resolution: {integrity: sha512-PiVXnNuFm5+iYkLBNeq5211hvO38y63T0i2KKh2KnUs3RpzJ+JtODFjkD8yjLwnDkTYF1eKXheUwdssR+NRZdg==} + + node-rsa@1.1.1: + resolution: {integrity: sha512-Jd4cvbJMryN21r5HgxQOpMEqv+ooke/korixNNK3mGqfGJmy0M77WDDzo/05969+OkMy3XW1UuZsSmW9KQm7Fw==} + + node-xmllint@1.0.0: + resolution: {integrity: sha512-71UV2HRUP+djvHpdyatiuv+Y1o8hI4ZI7bMfuuoACMLR1JJCErM4WXAclNeHd6BgHXkqeqnnAk3wpDkSQWmFXw==} + + nodemailer@6.9.9: + resolution: {integrity: sha512-dexTll8zqQoVJEZPwQAKzxxtFn0qTnjdQTchoU6Re9BUUGBJiOy3YMn/0ShTW6J5M0dfQ1NeDeRTTl4oIWgQMA==} + engines: {node: '>=6.0.0'} + + nodemon@3.0.0: + resolution: {integrity: sha512-yU9NSp3n+DUSt3S2LmtXss+4kOsmC8ZLpXeGe5mKuLdqkoSRwmaplk2lo5cmve7TPw5MgMcd2cazL0KpUscoSQ==} + engines: {node: '>=10'} + hasBin: true + + nopt@1.0.10: + resolution: {integrity: sha512-NWmpvLSqUrgrAC9HCuxEvb+PSloHpqVu+FqcO4eeF2h5qYRhA7ev6KvelyQAKtegUbC6RypJnlEOhd8vloNKYg==} + hasBin: true + + normalize-package-data@2.5.0: + resolution: {integrity: sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==} + + normalize-package-data@3.0.3: + resolution: {integrity: sha512-p2W1sgqij3zMMyRC067Dg16bfzVH+w7hyegmpIvZ4JNjqtGOVAIvLmjBx3yP7YTe9vKJgkoNOPjwQGogDoMXFA==} + engines: {node: '>=10'} + + normalize-path@3.0.0: + resolution: {integrity: sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==} + engines: {node: '>=0.10.0'} + + normalize-url@8.0.0: + resolution: {integrity: sha512-uVFpKhj5MheNBJRTiMZ9pE/7hD1QTeEvugSJW/OmLzAp78PB5O6adfMNTvmfKhXBkvCzC+rqifWcVYpGFwTjnw==} + engines: {node: '>=14.16'} + + npm-run-path@4.0.1: + resolution: {integrity: sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==} + engines: {node: '>=8'} + + npm-run-path@5.1.0: + resolution: {integrity: sha512-sJOdmRGrY2sjNTRMbSvluQqg+8X7ZK61yvzBEIDhz4f8z1TZFYABsqjjCBd/0PUNE9M6QDgHJXQkGUEm7Q+l9Q==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + + nth-check@2.1.1: + resolution: {integrity: sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w==} + + nullthrows@1.1.1: + resolution: {integrity: sha512-2vPPEi+Z7WqML2jZYddDIfy5Dqb0r2fze2zTxNNknZaFpVHU3mFB3R+DWeJWGVx0ecvttSGlJTI+WG+8Z4cDWw==} + + nwsapi@2.2.2: + resolution: {integrity: sha512-90yv+6538zuvUMnN+zCr8LuV6bPFdq50304114vJYJ8RDyK8D5O9Phpbd6SZWgI7PwzmmfN1upeOJlvybDSgCw==} + + obj-props@1.4.0: + resolution: {integrity: sha512-p7p/7ltzPDiBs6DqxOrIbtRdwxxVRBj5ROukeNb9RgA+fawhrz5n2hpNz8DDmYR//tviJSj7nUnlppGmONkjiQ==} + engines: {node: '>=0.10.0'} + + object-assign@4.1.1: + resolution: {integrity: sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==} + engines: {node: '>=0.10.0'} + + object-hash@3.0.0: + resolution: {integrity: sha512-RSn9F68PjH9HqtltsSnqYC1XXoWe9Bju5+213R98cNGttag9q9yAOTzdbsqvIa7aNm5WffBZFpWYr2aWrklWAw==} + engines: {node: '>= 6'} + + object-inspect@1.13.1: + resolution: {integrity: sha512-5qoj1RUiKOMsCCNLV1CBiPYE10sziTsnmNxkAI/rZhiD63CF7IqdFGC/XzjWjpSgLf0LxXX3bDFIh0E18f6UhQ==} + + object-keys@1.1.1: + resolution: {integrity: sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==} + engines: {node: '>= 0.4'} + + object.assign@4.1.4: + resolution: {integrity: sha512-1mxKf0e58bvyjSCtKYY4sRe9itRk3PJpquJOjeIkz885CczcI4IvJJDLPS72oowuSh+pBxUFROpX+TU++hxhZQ==} + engines: {node: '>= 0.4'} + + object.assign@4.1.5: + resolution: {integrity: sha512-byy+U7gp+FVwmyzKPYhW2h5l3crpmGsxl7X2s8y43IgxvG4g3QZ6CffDtsNQy1WsmZpQbO+ybo0AlW7TY6DcBQ==} + engines: {node: '>= 0.4'} + + object.entries@1.1.8: + resolution: {integrity: sha512-cmopxi8VwRIAw/fkijJohSfpef5PdN0pMQJN6VC/ZKvn0LIknWD8KtgY6KlQdEc4tIjcQ3HxSMmnvtzIscdaYQ==} + engines: {node: '>= 0.4'} + + object.fromentries@2.0.8: + resolution: {integrity: sha512-k6E21FzySsSK5a21KRADBd/NGneRegFO5pLHfdQLpRDETUNJueLXs3WCzyQ3tFRDYgbq3KHGXfTbi2bs8WQ6rQ==} + engines: {node: '>= 0.4'} + + object.groupby@1.0.3: + resolution: {integrity: sha512-+Lhy3TQTuzXI5hevh8sBGqbmurHbbIjAi0Z4S63nthVLmLxfbj4T54a4CfZrXIrt9iP4mVAPYMo/v99taj3wjQ==} + engines: {node: '>= 0.4'} + + object.hasown@1.1.4: + resolution: {integrity: sha512-FZ9LZt9/RHzGySlBARE3VF+gE26TxR38SdmqOqliuTnl9wrKulaQs+4dee1V+Io8VfxqzAfHu6YuRgUy8OHoTg==} + engines: {node: '>= 0.4'} + + object.values@1.2.0: + resolution: {integrity: sha512-yBYjY9QX2hnRmZHAjG/f13MzmBzxzYgQhFrke06TTyKY5zSTEqkOeukBzIdVA3j3ulu8Qa3MbVFShV7T2RmGtQ==} + engines: {node: '>= 0.4'} + + obuf@1.1.2: + resolution: {integrity: sha512-PX1wu0AmAdPqOL1mWhqmlOd8kOIZQwGZw6rh7uby9fTc5lhaOWFLX3I6R1hrF9k3zUY40e6igsLGkDXK92LJNg==} + + oidc-provider@8.4.6: + resolution: {integrity: sha512-liuHBXRaIjer6nPGWagrl5UjPhIZqahqLVPoYlc2WXsRR7XddwNCBUl1ks5r3Q3uCUfMdQTv1VsjmlaObdff8w==} + + oidc-token-hash@5.0.3: + resolution: {integrity: sha512-IF4PcGgzAr6XXSff26Sk/+P4KZFJVuHAJZj3wgO3vX2bMdNVp/QXTP3P7CEm9V1IdG8lDLY3HhiqpsE/nOwpPw==} + engines: {node: ^10.13.0 || >=12.0.0} + + on-finished@2.3.0: + resolution: {integrity: sha1-IPEzZIGwg811M3mSoWlxqi2QaUc=} + engines: {node: '>= 0.8'} + + on-finished@2.4.1: + resolution: {integrity: sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==} + engines: {node: '>= 0.8'} + + once@1.4.0: + resolution: {integrity: sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==} + + onetime@5.1.2: + resolution: {integrity: sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==} + engines: {node: '>=6'} + + onetime@6.0.0: + resolution: {integrity: sha512-1FlR+gjXK7X+AsAHso35MnyN5KqGwJRi/31ft6x0M194ht7S+rWAvd7PHss9xSKMzE0asv1pyIHaJYq+BbacAQ==} + engines: {node: '>=12'} + + only@0.0.2: + resolution: {integrity: sha1-Kv3oTQPlC5qO3EROMGEKcCle37Q=} + + openapi-schema-validator@12.1.3: + resolution: {integrity: sha512-xTHOmxU/VQGUgo7Cm0jhwbklOKobXby+/237EG967+3TQEYJztMgX9Q5UE2taZKwyKPUq0j11dngpGjUuxz1hQ==} + + openapi-types@12.1.3: + resolution: {integrity: sha512-N4YtSYJqghVu4iek2ZUvcN/0aqH1kRDuNqzcycDxhOUpg7GdvLa2F3DgS6yBNhInhv2r/6I0Flkn7CqL8+nIcw==} + + optionator@0.8.3: + resolution: {integrity: sha512-+IW9pACdk3XWmmTXG8m3upGUJst5XRGzxMRjXzAuJ1XnIFNvfhjjIuYkDvysnPQ7qzqVzLt78BCruntqRhWQbA==} + engines: {node: '>= 0.8.0'} + + optionator@0.9.3: + resolution: {integrity: sha512-JjCoypp+jKn1ttEFExxhetCKeJt9zhAgAve5FXHixTvFDW/5aEktX9bufBKLRRMdU7bNtpLfcGu94B3cdEJgjg==} + engines: {node: '>= 0.8.0'} + + ora@6.1.2: + resolution: {integrity: sha512-EJQ3NiP5Xo94wJXIzAyOtSb0QEIAUu7m8t6UZ9krbz0vAJqr92JpcK/lEXg91q6B9pEGqrykkd2EQplnifDSBw==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + + ora@8.0.1: + resolution: {integrity: sha512-ANIvzobt1rls2BDny5fWZ3ZVKyD6nscLvfFRpQgfWsythlcsVUC9kL0zq6j2Z5z9wwp1kd7wpsD/T9qNPVLCaQ==} + engines: {node: '>=18'} + + ordered-binary@1.4.0: + resolution: {integrity: sha512-EHQ/jk4/a9hLupIKxTfUsQRej1Yd/0QLQs3vGvIqg5ZtCYSzNhkzHoZc7Zf4e4kUlDaC3Uw8Q/1opOLNN2OKRQ==} + + os-homedir@1.0.2: + resolution: {integrity: sha512-B5JU3cabzk8c67mRRd3ECmROafjYMXbuzlwtqdM8IbS8ktlTix8aFGb2bAGKrSRIlnfKwovGUUr72JUPyOb6kQ==} + engines: {node: '>=0.10.0'} + + os-tmpdir@1.0.2: + resolution: {integrity: sha512-D2FR03Vir7FIu45XBY20mTb+/ZSWB00sjU9jdQXt83gDrI4Ztz5Fs7/yy74g2N5SVQY4xY1qDr4rNddwYRVX0g==} + engines: {node: '>=0.10.0'} + + otplib@12.0.1: + resolution: {integrity: sha512-xDGvUOQjop7RDgxTQ+o4pOol0/3xSZzawTiPKRrHnQWAy0WjhNs/5HdIDJCrqC4MBynmjXgULc6YfioaxZeFgg==} + + outdent@0.5.0: + resolution: {integrity: sha512-/jHxFIzoMXdqPzTaCpFzAAWhpkSjZPF4Vsn6jAfNpmbH/ymsmd7Qc6VE9BGn0L6YMj6uwpQLxCECpus4ukKS9Q==} + + overlayscrollbars-react@0.5.0: + resolution: {integrity: sha512-uCNTnkfWW74veoiEv3kSwoLelKt4e8gTNv65D771X3il0x5g5Yo0fUbro7SpQzR9yNgi23cvB2mQHTTdQH96pA==} + peerDependencies: + overlayscrollbars: ^2.0.0 + react: '>=16.8.0 || ^18.0.0' + + overlayscrollbars@2.0.3: + resolution: {integrity: sha512-boOkJFER1Tc21sxF4a7ghGl+ETV3WtP7YgsUyDPo1VTHUIPdQLfnTzMyOOdMkKkVcpJOYMKwwr4m+saCtgawCg==} + + p-cancelable@3.0.0: + resolution: {integrity: sha512-mlVgR3PGuzlo0MmTdk4cXqXWlwQDLnONTAg6sm62XkMJEiRxN3GL3SffkYvqwonbkJBcrI7Uvv5Zh9yjvn2iUw==} + engines: {node: '>=12.20'} + + p-cancelable@4.0.1: + resolution: {integrity: sha512-wBowNApzd45EIKdO1LaU+LrMBwAcjfPaYtVzV3lmfM3gf8Z4CHZsiIqlM8TZZ8okYvh5A1cP6gTfCRQtwUpaUg==} + engines: {node: '>=14.16'} + + p-defer@4.0.0: + resolution: {integrity: sha512-Vb3QRvQ0Y5XnF40ZUWW7JfLogicVh/EnA5gBIvKDJoYpeI82+1E3AlB9yOcKFS0AhHrWVnAQO39fbR0G99IVEQ==} + engines: {node: '>=12'} + + p-filter@2.1.0: + resolution: {integrity: sha512-ZBxxZ5sL2HghephhpGAQdoskxplTwr7ICaehZwLIlfL6acuVgZPm8yBNuRAFBGEqtD/hmUeq9eqLg2ys9Xr/yw==} + engines: {node: '>=8'} + + p-limit@2.3.0: + resolution: {integrity: sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==} + engines: {node: '>=6'} + + p-limit@3.1.0: + resolution: {integrity: sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==} + engines: {node: '>=10'} + + p-limit@4.0.0: + resolution: {integrity: sha512-5b0R4txpzjPWVw/cXXUResoD4hb6U/x9BH08L7nw+GN1sezDzPdxeRvpc9c433fZhBan/wusjbCsqwqm4EIBIQ==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + + p-limit@5.0.0: + resolution: {integrity: sha512-/Eaoq+QyLSiXQ4lyYV23f14mZRQcXnxfHrN0vCai+ak9G0pp9iEQukIIZq5NccEvwRB8PUnZT0KsOoDCINS1qQ==} + engines: {node: '>=18'} + + p-locate@4.1.0: + resolution: {integrity: sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==} + engines: {node: '>=8'} + + p-locate@5.0.0: + resolution: {integrity: sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==} + engines: {node: '>=10'} + + p-locate@6.0.0: + resolution: {integrity: sha512-wPrq66Llhl7/4AGC6I+cqxT07LhXvWL08LNXz1fENOw0Ap4sRZZ/gZpTTJ5jpurzzzfS2W/Ge9BY3LgLjCShcw==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + + p-map@2.1.0: + resolution: {integrity: sha512-y3b8Kpd8OAN444hxfBbFfj1FY/RjtTd8tzYwhUqNYXx0fXx2iX4maP4Qr6qhIKbQXI02wTLAda4fYUbDagTUFw==} + engines: {node: '>=6'} + + p-map@7.0.2: + resolution: {integrity: sha512-z4cYYMMdKHzw4O5UkWJImbZynVIo0lSGTXc7bzB1e/rrDqkgGUNysK/o4bTr+0+xKvvLoTyGqYC4Fgljy9qe1Q==} + engines: {node: '>=18'} + + p-queue@8.0.1: + resolution: {integrity: sha512-NXzu9aQJTAzbBqOt2hwsR63ea7yvxJc0PwN/zobNAudYfb1B7R08SzB4TsLeSbUCuG467NhnoT0oO6w1qRO+BA==} + engines: {node: '>=18'} + + p-retry@6.0.0: + resolution: {integrity: sha512-6NuuXu8Upembd4sNdo4PRbs+M6aHgBTrFE6lkH0YKjVzne3cDW4gkncB98ty/bkMxLxLVNeD5bX9FyWjM7WZ+A==} + engines: {node: '>=16.17'} + + p-timeout@6.1.2: + resolution: {integrity: sha512-UbD77BuZ9Bc9aABo74gfXhNvzC9Tx7SxtHSh1fxvx3jTLLYvmVhiQZZrJzqqU0jKbN32kb5VOKiLEQI/3bIjgQ==} + engines: {node: '>=14.16'} + + p-try@2.2.0: + resolution: {integrity: sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==} + engines: {node: '>=6'} + + pac-proxy-agent@7.0.1: + resolution: {integrity: sha512-ASV8yU4LLKBAjqIPMbrgtaKIvxQri/yh2OpI+S6hVa9JRkUI3Y3NPFbfngDtY7oFtSMD3w31Xns89mDa3Feo5A==} + engines: {node: '>= 14'} + + pac-resolver@7.0.0: + resolution: {integrity: sha512-Fd9lT9vJbHYRACT8OhCbZBbxr6KRSawSovFpy8nDGshaK99S/EBhVIHp9+crhxrsZOuvLpgL1n23iyPg6Rl2hg==} + engines: {node: '>= 14'} + + packet-reader@1.0.0: + resolution: {integrity: sha512-HAKu/fG3HpHFO0AA8WE8q2g+gBJaZ9MG7fcKk+IJPLTGAD6Psw4443l+9DGRbOIh3/aXr7Phy0TjilYivJo5XQ==} + + pako@1.0.11: + resolution: {integrity: sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw==} + + parcel-resolver-ignore@2.1.3: + resolution: {integrity: sha512-C8uLvR4o7SPRSsQ/Nylm1/PdsLwn/Z9bzCs66qT3XIebJC7ojaFFF3MDl/mie5audngjcFF8wzU0AoEQkZq2pA==} + engines: {parcel: '>=2.0.0'} + peerDependencies: + parcel: '>=2.0.0' + + parcel@2.9.3: + resolution: {integrity: sha512-2GTVocFkwblV/TIg9AmT7TI2fO4xdWkyN8aFUEVtiVNWt96GTR3FgQyHFValfCbcj1k9Xf962Ws2hYXYUr9k1Q==} + engines: {node: '>= 12.0.0'} + hasBin: true + peerDependenciesMeta: + '@parcel/core': + optional: true + + parent-module@1.0.1: + resolution: {integrity: sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==} + engines: {node: '>=6'} + + parse-entities@2.0.0: + resolution: {integrity: sha512-kkywGpCcRYhqQIchaWqZ875wzpS/bMKhz5HnN3p7wveJTkTtyAB/AlnS0f8DFSqYW1T82t6yEAkEcB+A1I3MbQ==} + + parse-json@5.2.0: + resolution: {integrity: sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==} + engines: {node: '>=8'} + + parse-passwd@1.0.0: + resolution: {integrity: sha512-1Y1A//QUXEZK7YKz+rD9WydcE1+EuPr6ZBgKecAB8tmoW6UFv0NREVJe1p+jRxtThkcbbKkfwIbWJe/IeE6m2Q==} + engines: {node: '>=0.10.0'} + + parse5@6.0.1: + resolution: {integrity: sha512-Ofn/CTFzRGTTxwpNEs9PP93gXShHcTq255nzRYSKe8AkVpZY7e1fpmTfOyoIvjP5HG7Z2ZM7VS9PPhQGW2pOpw==} + + parse5@7.1.1: + resolution: {integrity: sha512-kwpuwzB+px5WUg9pyK0IcK/shltJN5/OVhQagxhCQNtT9Y9QRZqNY2e1cmbu/paRh5LMnz/oVTVLBpjFmMZhSg==} + + parseurl@1.3.3: + resolution: {integrity: sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==} + engines: {node: '>= 0.8'} + + passthrough-counter@1.0.0: + resolution: {integrity: sha1-GWfZ5m2lcrXAI8eH2xEqOHqxZvo=} + + path-exists@4.0.0: + resolution: {integrity: sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==} + engines: {node: '>=8'} + + path-exists@5.0.0: + resolution: {integrity: sha512-RjhtfwJOxzcFmNOi6ltcbcu4Iu+FL3zEj83dk4kAS+fVpTxXLO1b38RvJgT/0QwvV/L3aY9TAnyv0EOqW4GoMQ==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + + path-is-absolute@1.0.1: + resolution: {integrity: sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==} + engines: {node: '>=0.10.0'} + + path-key@3.1.1: + resolution: {integrity: sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==} + engines: {node: '>=8'} + + path-key@4.0.0: + resolution: {integrity: sha512-haREypq7xkM7ErfgIyA0z+Bj4AGKlMSdlQE2jvJo6huWD1EdkKYV+G/T4nq0YEF2vgTT8kqMFKo1uHn950r4SQ==} + engines: {node: '>=12'} + + path-match@1.2.4: + resolution: {integrity: sha512-UWlehEdqu36jmh4h5CWJ7tARp1OEVKGHKm6+dg9qMq5RKUTV5WJrGgaZ3dN2m7WFAXDbjlHzvJvL/IUpy84Ktw==} + + path-parse@1.0.7: + resolution: {integrity: sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==} + + path-scurry@1.10.2: + resolution: {integrity: sha512-7xTavNy5RQXnsjANvVvMkEjvloOinkAjv/Z6Ildz9v2RinZ4SBKTWFOVRbaF8p0vpHnyjV/UwNDdKuUv6M5qcA==} + engines: {node: '>=16 || 14 >=14.17'} + + path-to-regexp@1.8.0: + resolution: {integrity: sha512-n43JRhlUKUAlibEJhPeir1ncUID16QnEjNpwzNdO3Lm4ywrBpBZ5oLD0I6br9evr1Y9JTqwRtAh7JLoOzAQdVA==} + + path-to-regexp@6.2.1: + resolution: {integrity: sha512-JLyh7xT1kizaEvcaXOQwOc2/Yhw6KZOvPf1S8401UyLk86CU79LN3vl7ztXGm/pZ+YjoyAJ4rxmHwbkBXJX+yw==} + + path-type@4.0.0: + resolution: {integrity: sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==} + engines: {node: '>=8'} + + pathe@1.1.2: + resolution: {integrity: sha512-whLdWMYL2TwI08hn8/ZqAbrVemu0LNaNNJZX73O6qaIdCTfXutsLhMkjdENX0qhsQ9uIimo4/aQOmXkoon2nDQ==} + + pathval@1.1.1: + resolution: {integrity: sha512-Dp6zGqpTdETdR63lehJYPeIOqpiNBNtc7BpWSLrOje7UaIsE5aY92r/AunQA7rsXvet3lrJ3JnZX29UPTKXyKQ==} + + pend@1.2.0: + resolution: {integrity: sha512-F3asv42UuXchdzt+xXqfW1OGlVBe+mxa2mqI0pg5yAHZPvFmY3Y6drSf/GQ1A86WgWEN9Kzh/WrgKa6iGcHXLg==} + + pg-cloudflare@1.1.1: + resolution: {integrity: sha512-xWPagP/4B6BgFO+EKz3JONXv3YDgvkbVrGw2mTo3D6tVDQRh1e7cqVGvyR3BE+eQgAvx1XhW/iEASj4/jCWl3Q==} + + pg-connection-string@2.5.0: + resolution: {integrity: sha512-r5o/V/ORTA6TmUnyWZR9nCj1klXCO2CEKNRlVuJptZe85QuhFayC7WeMic7ndayT5IRIR0S0xFxFi2ousartlQ==} + + pg-connection-string@2.6.2: + resolution: {integrity: sha512-ch6OwaeaPYcova4kKZ15sbJ2hKb/VP48ZD2gE7i1J+L4MspCtBMAx8nMgz7bksc7IojCIIWuEhHibSMFH8m8oA==} + + pg-cursor@2.10.3: + resolution: {integrity: sha512-rDyBVoqPVnx/PTmnwQAYgusSeAKlTL++gmpf5klVK+mYMFEqsOc6VHHZnPKc/4lOvr4r6fiMuoxSFuBF1dx4FQ==} + peerDependencies: + pg: ^8 + + pg-formatter@1.3.0: + resolution: {integrity: sha512-y1kNdgD+QWzhmYCm91z/k7VGyx6BekQg6ww/krFEEhw1IIB4zEk2xaB0pmueTcc59YFetpiHIKECgHEuw6gyvg==} + engines: {node: '>=10.0'} + hasBin: true + + pg-int8@1.0.1: + resolution: {integrity: sha512-WCtabS6t3c8SkpDBUlb1kjOs7l66xsGdKpIPZsg4wR+B3+u9UAum2odSsF9tnvxg80h4ZxLWMy4pRjOsFIqQpw==} + engines: {node: '>=4.0.0'} + + pg-numeric@1.0.2: + resolution: {integrity: sha512-BM/Thnrw5jm2kKLE5uJkXqqExRUY/toLHda65XgFTBTFYZyopbKjBe29Ii3RbkvlsMoFwD+tHeGaCjjv0gHlyw==} + engines: {node: '>=4'} + + pg-pool@3.5.2: + resolution: {integrity: sha512-His3Fh17Z4eg7oANLob6ZvH8xIVen3phEZh2QuyrIl4dQSDVEabNducv6ysROKpDNPSD+12tONZVWfSgMvDD9w==} + peerDependencies: + pg: '>=8.0' + + pg-pool@3.6.1: + resolution: {integrity: sha512-jizsIzhkIitxCGfPRzJn1ZdcosIt3pz9Sh3V01fm1vZnbnCMgmGl5wvGGdNN2EL9Rmb0EcFoCkixH4Pu+sP9Og==} + peerDependencies: + pg: '>=8.0' + + pg-protocol@1.6.0: + resolution: {integrity: sha512-M+PDm637OY5WM307051+bsDia5Xej6d9IR4GwJse1qA1DIhiKlksvrneZOYQq42OM+spubpcNYEo2FcKQrDk+Q==} + + pg-types@2.2.0: + resolution: {integrity: sha512-qTAAlrEsl8s4OiEQY69wDvcMIdQN6wdz5ojQiOy6YRMuynxenON0O5oCpJI6lshc6scgAY8qvJ2On/p+CXY0GA==} + engines: {node: '>=4'} + + pg-types@4.0.2: + resolution: {integrity: sha512-cRL3JpS3lKMGsKaWndugWQoLOCoP+Cic8oseVcbr0qhPzYD5DWXK+RZ9LY9wxRf7RQia4SCwQlXk0q6FCPrVng==} + engines: {node: '>=10'} + + pg@8.11.3: + resolution: {integrity: sha512-+9iuvG8QfaaUrrph+kpF24cXkH1YOOUeArRNYIxq1viYHZagBxrTno7cecY1Fa44tJeZvaoG+Djpkc3JwehN5g==} + engines: {node: '>= 8.0.0'} + peerDependencies: + pg-native: '>=3.0.1' + peerDependenciesMeta: + pg-native: + optional: true + + pg@8.8.0: + resolution: {integrity: sha512-UXYN0ziKj+AeNNP7VDMwrehpACThH7LUl/p8TDFpEUuSejCUIwGSfxpHsPvtM6/WXFy6SU4E5RG4IJV/TZAGjw==} + engines: {node: '>= 8.0.0'} + peerDependencies: + pg-native: '>=3.0.1' + peerDependenciesMeta: + pg-native: + optional: true + + pgpass@1.0.4: + resolution: {integrity: sha512-YmuA56alyBq7M59vxVBfPJrGSozru8QAdoNlWuW3cz8l+UX3cWge0vTvjKhsSHSJpo3Bom8/Mm6hf0TR5GY0+w==} + + picocolors@1.0.0: + resolution: {integrity: sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==} + + picomatch@2.3.1: + resolution: {integrity: sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==} + engines: {node: '>=8.6'} + + pidtree@0.6.0: + resolution: {integrity: sha512-eG2dWTVw5bzqGRztnHExczNxt5VGsE6OwTeCG3fdUf9KBsZzO3R5OIIIzWR+iZA0NtZ+RDVdaoE2dK1cn6jH4g==} + engines: {node: '>=0.10'} + hasBin: true + + pify@4.0.1: + resolution: {integrity: sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==} + engines: {node: '>=6'} + + pirates@4.0.5: + resolution: {integrity: sha512-8V9+HQPupnaXMA23c5hvl69zXvTwTzyAYasnkb0Tts4XvO4CliqONMOnvlq26rkhLC3nWDFBJf73LU1e1VZLaQ==} + engines: {node: '>= 6'} + + pkg-dir@4.2.0: + resolution: {integrity: sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==} + engines: {node: '>=8'} + + pkg-dir@5.0.0: + resolution: {integrity: sha512-NPE8TDbzl/3YQYY7CSS228s3g2ollTFnc+Qi3tqmqJp9Vg2ovUpixcJEo2HJScN2Ez+kEaal6y70c0ehqJBJeA==} + engines: {node: '>=10'} + + pkg-types@1.0.3: + resolution: {integrity: sha512-nN7pYi0AQqJnoLPC9eHFQ8AcyaixBUOwvqc5TDnIKCMEE6I0y8P7OKA7fPexsXGCGxQDl/cmrLAp26LhcwxZ4A==} + + pluralize@8.0.0: + resolution: {integrity: sha512-Nc3IT5yHzflTfbjgqWcCPpo7DaKy4FnpB0l/zCAW0Tc7jxAiuqSxHasntB3D7887LSrA93kDJ9IXovxJYxyLCA==} + engines: {node: '>=4'} + + pngjs@5.0.0: + resolution: {integrity: sha512-40QW5YalBNfQo5yRYmiw7Yz6TKKVr3h6970B2YE+3fQpsWcrbj1PzJgxeJ19DRQjhMbKPIuMY8rFaXc8moolVw==} + engines: {node: '>=10.13.0'} + + possible-typed-array-names@1.0.0: + resolution: {integrity: sha512-d7Uw+eZoloe0EHDIYoe+bQ5WXnGMOpmiZFTuMWCwpjzzkL2nTjcKiAk4hh8TjnGye2TwWOk3UXucZ+3rbmBa8Q==} + engines: {node: '>= 0.4'} + + postcss-media-query-parser@0.2.3: + resolution: {integrity: sha512-3sOlxmbKcSHMjlUXQZKQ06jOswE7oVkXPxmZdoB1r5l0q6gTFTQSHxNxOrCccElbW7dxNytifNEo8qidX2Vsig==} + + postcss-modules-extract-imports@3.0.0: + resolution: {integrity: sha512-bdHleFnP3kZ4NYDhuGlVK+CMrQ/pqUm8bx/oGL93K6gVwiclvX5x0n76fYMKuIGKzlABOy13zsvqjb0f92TEXw==} + engines: {node: ^10 || ^12 || >= 14} + peerDependencies: + postcss: ^8.1.0 + + postcss-modules-local-by-default@4.0.0: + resolution: {integrity: sha512-sT7ihtmGSF9yhm6ggikHdV0hlziDTX7oFoXtuVWeDd3hHObNkcHRo9V3yg7vCAY7cONyxJC/XXCmmiHHcvX7bQ==} + engines: {node: ^10 || ^12 || >= 14} + peerDependencies: + postcss: ^8.1.0 + + postcss-modules-scope@3.0.0: + resolution: {integrity: sha512-hncihwFA2yPath8oZ15PZqvWGkWf+XUfQgUGamS4LqoP1anQLOsOJw0vr7J7IwLpoY9fatA2qiGUGmuZL0Iqlg==} + engines: {node: ^10 || ^12 || >= 14} + peerDependencies: + postcss: ^8.1.0 + + postcss-modules-values@4.0.0: + resolution: {integrity: sha512-RDxHkAiEGI78gS2ofyvCsu7iycRv7oqw5xMWn9iMoR0N/7mf9D50ecQqUo5BZ9Zh2vH4bCUR/ktCqbB9m8vJjQ==} + engines: {node: ^10 || ^12 || >= 14} + peerDependencies: + postcss: ^8.1.0 + + postcss-modules@4.3.0: + resolution: {integrity: sha512-zoUttLDSsbWDinJM9jH37o7hulLRyEgH6fZm2PchxN7AZ8rkdWiALyNhnQ7+jg7cX9f10m6y5VhHsrjO0Mf/DA==} + peerDependencies: + postcss: ^8.0.0 + + postcss-resolve-nested-selector@0.1.1: + resolution: {integrity: sha512-HvExULSwLqHLgUy1rl3ANIqCsvMS0WHss2UOsXhXnQaZ9VCc2oBvIpXrl00IUFT5ZDITME0o6oiXeiHr2SAIfw==} + + postcss-safe-parser@6.0.0: + resolution: {integrity: sha512-FARHN8pwH+WiS2OPCxJI8FuRJpTVnn6ZNFiqAM2aeW2LwTHWWmWgIyKC6cUo0L8aeKiF/14MNvnpls6R2PBeMQ==} + engines: {node: '>=12.0'} + peerDependencies: + postcss: ^8.3.3 + + postcss-scss@4.0.9: + resolution: {integrity: sha512-AjKOeiwAitL/MXxQW2DliT28EKukvvbEWx3LBmJIRN8KfBGZbRTxNYW0kSqi1COiTZ57nZ9NW06S6ux//N1c9A==} + engines: {node: '>=12.0'} + peerDependencies: + postcss: ^8.4.29 + + postcss-selector-parser@6.0.11: + resolution: {integrity: sha512-zbARubNdogI9j7WY4nQJBiNqQf3sLS3wCP4WfOidu+p28LofJqDH1tcXypGrcmMHhDk2t9wGhCsYe/+szLTy1g==} + engines: {node: '>=4'} + + postcss-selector-parser@6.0.16: + resolution: {integrity: sha512-A0RVJrX+IUkVZbW3ClroRWurercFhieevHB38sr2+l9eUClMqome3LmEmnhlNy+5Mr2EYN6B2Kaw9wYdd+VHiw==} + engines: {node: '>=4'} + + postcss-sorting@8.0.2: + resolution: {integrity: sha512-M9dkSrmU00t/jK7rF6BZSZauA5MAaBW4i5EnJXspMwt4iqTh/L9j6fgMnbElEOfyRyfLfVbIHj/R52zHzAPe1Q==} + peerDependencies: + postcss: ^8.4.20 + + postcss-value-parser@3.3.1: + resolution: {integrity: sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==} + + postcss-value-parser@4.2.0: + resolution: {integrity: sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==} + + postcss@8.4.31: + resolution: {integrity: sha512-PS08Iboia9mts/2ygV3eLpY5ghnUcfLV/EXTOW1E2qYxJKGGBUtNjN76FYHnMs36RmARn41bC0AZmn+rR0OVpQ==} + engines: {node: ^10 || ^12 || >=14} + + postcss@8.4.38: + resolution: {integrity: sha512-Wglpdk03BSfXkHoQa3b/oulrotAkwrlLDRSOb9D0bN86FdRyE9lppSp33aHNPgBa0JKCoB+drFLZkQoRRYae5A==} + engines: {node: ^10 || ^12 || >=14} + + postgres-array@2.0.0: + resolution: {integrity: sha512-VpZrUqU5A69eQyW2c5CA1jtLecCsN2U/bD6VilrFDWq5+5UIEVO7nazS3TEcHf1zuPYO/sqGvUvW62g86RXZuA==} + engines: {node: '>=4'} + + postgres-array@3.0.2: + resolution: {integrity: sha512-6faShkdFugNQCLwucjPcY5ARoW1SlbnrZjmGl0IrrqewpvxvhSLHimCVzqeuULCbG0fQv7Dtk1yDbG3xv7Veog==} + engines: {node: '>=12'} + + postgres-bytea@1.0.0: + resolution: {integrity: sha512-xy3pmLuQqRBZBXDULy7KbaitYqLcmxigw14Q5sj8QBVLqEwXfeybIKVWiqAXTlcvdvb0+xkOtDbfQMOf4lST1w==} + engines: {node: '>=0.10.0'} + + postgres-bytea@3.0.0: + resolution: {integrity: sha512-CNd4jim9RFPkObHSjVHlVrxoVQXz7quwNFpz7RY1okNNme49+sVyiTvTRobiLV548Hx/hb1BG+iE7h9493WzFw==} + engines: {node: '>= 6'} + + postgres-date@1.0.7: + resolution: {integrity: sha512-suDmjLVQg78nMK2UZ454hAG+OAW+HQPZ6n++TNDUX+L0+uUlLywnoxJKDou51Zm+zTCjrCl0Nq6J9C5hP9vK/Q==} + engines: {node: '>=0.10.0'} + + postgres-date@2.1.0: + resolution: {integrity: sha512-K7Juri8gtgXVcDfZttFKVmhglp7epKb1K4pgrkLxehjqkrgPhfG6OO8LHLkfaqkbpjNRnra018XwAr1yQFWGcA==} + engines: {node: '>=12'} + + postgres-interval@1.2.0: + resolution: {integrity: sha512-9ZhXKM/rw350N1ovuWHbGxnGh/SNJ4cnxHiM0rxE4VN41wsg8P8zWn9hv/buK00RP4WvlOyr/RBDiptyxVbkZQ==} + engines: {node: '>=0.10.0'} + + postgres-interval@3.0.0: + resolution: {integrity: sha512-BSNDnbyZCXSxgA+1f5UU2GmwhoI0aU5yMxRGO8CdFEcY2BQF9xm/7MqKnYoM1nJDk8nONNWDk9WeSmePFhQdlw==} + engines: {node: '>=12'} + + postgres-interval@4.0.2: + resolution: {integrity: sha512-EMsphSQ1YkQqKZL2cuG0zHkmjCCzQqQ71l2GXITqRwjhRleCdv00bDk/ktaSi0LnlaPzAc3535KTrjXsTdtx7A==} + engines: {node: '>=12'} + + postgres-range@1.1.2: + resolution: {integrity: sha512-CmPJDSpd3/xYJrtw/tI0Cv029B0zMtnesUOHCZmgvypGBLn+eExXcjCS5OY7mpiw6imYEvd2IMD36sAOYA9U1w==} + + posthtml-parser@0.10.2: + resolution: {integrity: sha512-PId6zZ/2lyJi9LiKfe+i2xv57oEjJgWbsHGGANwos5AvdQp98i6AtamAl8gzSVFGfQ43Glb5D614cvZf012VKg==} + engines: {node: '>=12'} + + posthtml-parser@0.11.0: + resolution: {integrity: sha512-QecJtfLekJbWVo/dMAA+OSwY79wpRmbqS5TeXvXSX+f0c6pW4/SE6inzZ2qkU7oAMCPqIDkZDvd/bQsSFUnKyw==} + engines: {node: '>=12'} + + posthtml-render@3.0.0: + resolution: {integrity: sha512-z+16RoxK3fUPgwaIgH9NGnK1HKY9XIDpydky5eQGgAFVXTCSezalv9U2jQuNV+Z9qV1fDWNzldcw4eK0SSbqKA==} + engines: {node: '>=12'} + + posthtml@0.16.6: + resolution: {integrity: sha512-JcEmHlyLK/o0uGAlj65vgg+7LIms0xKXe60lcDOTU7oVX/3LuEuLwrQpW3VJ7de5TaFKiW4kWkaIpJL42FEgxQ==} + engines: {node: '>=12.0.0'} + + preferred-pm@3.0.3: + resolution: {integrity: sha512-+wZgbxNES/KlJs9q40F/1sfOd/j7f1O9JaHcW5Dsn3aUUOZg3L2bjpVUcKV2jvtElYfoTuQiNeMfQJ4kwUAhCQ==} + engines: {node: '>=10'} + + prelude-ls@1.1.2: + resolution: {integrity: sha512-ESF23V4SKG6lVSGZgYNpbsiaAkdab6ZgOxe52p7+Kid3W3u3bxR4Vfd/o21dmN7jSt0IwgZ4v5MUd26FEtXE9w==} + engines: {node: '>= 0.8.0'} + + prelude-ls@1.2.1: + resolution: {integrity: sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==} + engines: {node: '>= 0.8.0'} + + prettier-linter-helpers@1.0.0: + resolution: {integrity: sha512-GbK2cP9nraSSUF9N2XwUwqfzlAFlMNYYl+ShE/V+H8a9uNl/oUqB1w2EL54Jh0OlyRSd8RfWYJ3coVS4TROP2w==} + engines: {node: '>=6.0.0'} + + prettier@2.8.4: + resolution: {integrity: sha512-vIS4Rlc2FNh0BySk3Wkd6xmwxB0FpOndW5fisM5H8hsZSxU2VWVB5CWIkIjWvrHjIhxk2g3bfMKM87zNTrZddw==} + engines: {node: '>=10.13.0'} + hasBin: true + + prettier@3.0.0: + resolution: {integrity: sha512-zBf5eHpwHOGPC47h0zrPyNn+eAEIdEzfywMoYn2XPi0P44Zp0tSq64rq0xAREh4auw2cJZHo9QUob+NqCQky4g==} + engines: {node: '>=14'} + hasBin: true + + pretty-bytes@6.1.1: + resolution: {integrity: sha512-mQUvGU6aUFQ+rNvTIAcZuWGRT9a6f6Yrg9bHs4ImKF+HZCEK+plBvnAZYSIQztknZF2qnzNtr6F8s0+IuptdlQ==} + engines: {node: ^14.13.1 || >=16.0.0} + + pretty-format@27.5.1: + resolution: {integrity: sha512-Qb1gy5OrP5+zDf2Bvnzdl3jsTf1qXVMazbvCoKhtKqVs4/YK4ozX4gKQJJVyNe+cajNPn0KoC0MC3FUmaHWEmQ==} + engines: {node: ^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0} + + pretty-format@29.7.0: + resolution: {integrity: sha512-Pdlw/oPxN+aXdmM9R00JVC9WVFoCLTKJvDVLgmJ+qAffBMxsV85l/Lu7sNx4zSzPyoL2euImuEwHhOXdEgNFZQ==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + prismjs@1.27.0: + resolution: {integrity: sha512-t13BGPUlFDR7wRB5kQDG4jjl7XeuH6jbJGt11JHPL96qwsEHNX2+68tFXqc1/k+/jALsbSWJKUOT/hcYAZ5LkA==} + engines: {node: '>=6'} + + process@0.11.10: + resolution: {integrity: sha512-cdGef/drWFoydD1JsMzuFf8100nZl+GT+yacc2bEced5f9Rjk4z+WtFUTBu9PhOi9j/jfmBPu0mMEY4wIdAF8A==} + engines: {node: '>= 0.6.0'} + + progress@2.0.3: + resolution: {integrity: sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==} + engines: {node: '>=0.4.0'} + + prompts@2.4.2: + resolution: {integrity: sha512-NxNv/kLguCA7p3jE8oL2aEBsrJWgAakBpgmgK6lpPWV+WuOmY6r2/zbAVnP+T8bQlA0nzHXSJSJW0Hq7ylaD2Q==} + engines: {node: '>= 6'} + + prop-types@15.8.1: + resolution: {integrity: sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==} + + propagate@2.0.1: + resolution: {integrity: sha512-vGrhOavPSTz4QVNuBNdcNXePNdNMaO1xj9yBeH1ScQPjk/rhg9sSlCXPhMkFuaNNW/syTvYqsnbIJxMBfRbbag==} + engines: {node: '>= 8'} + + property-information@5.6.0: + resolution: {integrity: sha512-YUHSPk+A30YPv+0Qf8i9Mbfe/C0hdPXk1s1jPVToV8pk8BQtpw10ct89Eo7OWkutrwqvT0eicAxlOg3dOAu8JA==} + + property-information@6.2.0: + resolution: {integrity: sha512-kma4U7AFCTwpqq5twzC1YVIDXSqg6qQK6JN0smOw8fgRy1OkMi0CYSzFmsy6dnqSenamAtj0CyXMUJ1Mf6oROg==} + + proto-props@2.0.0: + resolution: {integrity: sha512-2yma2tog9VaRZY2mn3Wq51uiSW4NcPYT1cQdBagwyrznrilKSZwIZ0UG3ZPL/mx+axEns0hE35T5ufOYZXEnBQ==} + engines: {node: '>=4'} + + proxy-agent@6.4.0: + resolution: {integrity: sha512-u0piLU+nCOHMgGjRbimiXmA9kM/L9EHh3zL81xCdp7m+Y2pHIsnmbdDoEDoAz5geaonNR6q6+yOPQs6n4T6sBQ==} + engines: {node: '>= 14'} + + proxy-from-env@1.1.0: + resolution: {integrity: sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==} + + pseudomap@1.0.2: + resolution: {integrity: sha512-b/YwNhb8lk1Zz2+bXXpS/LK9OisiZZ1SNsSLxN1x2OXVEhW2Ckr/7mWE5vrC1ZTiJlD9g19jWszTmJsB+oEpFQ==} + + psl@1.9.0: + resolution: {integrity: sha512-E/ZsdU4HLs/68gYzgGTkMicWTLPdAftJLfJFlLUAAKZGkStNU72sZjT66SnMDVOfOWY/YAoiD7Jxa9iHvngcag==} + + pstree.remy@1.1.8: + resolution: {integrity: sha512-77DZwxQmxKnu3aR542U+X8FypNzbfJ+C5XQDk3uWjWxn6151aIMGthWYRXTqT1E5oJvg+ljaa2OJi+VfvCOQ8w==} + + pump@3.0.0: + resolution: {integrity: sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==} + + punycode@2.3.0: + resolution: {integrity: sha512-rRV+zQD8tVFys26lAGR9WUuS4iUAngJScM+ZRSKtvl5tKeZ2t5bvdNFdNHBW9FWR4guGHlgmsZ1G7BSm2wTbuA==} + engines: {node: '>=6'} + + puppeteer-core@22.6.5: + resolution: {integrity: sha512-s0/5XkAWe0/dWISiljdrybjwDCHhgN31Nu/wznOZPKeikgcJtZtbvPKBz0t802XWqfSQnQDt3L6xiAE5JLlfuw==} + engines: {node: '>=18'} + + puppeteer@22.6.5: + resolution: {integrity: sha512-YuoRKGj3MxHhUwrey7vmNvU4odGdUdNsj1ee8pfcqQlLWIXfMOXZCAXh8xdzpZESHH3tCGWp2xmPZE8E6iUEWg==} + engines: {node: '>=18'} + hasBin: true + + pure-rand@6.0.0: + resolution: {integrity: sha512-rLSBxJjP+4DQOgcJAx6RZHT2he2pkhQdSnofG5VWyVl6GRq/K02ISOuOLcsMOrtKDIJb8JN2zm3FFzWNbezdPw==} + + pvtsutils@1.3.5: + resolution: {integrity: sha512-ARvb14YB9Nm2Xi6nBq1ZX6dAM0FsJnuk+31aUp4TrcZEdKUlSqOqsxJHUPJDNE3qiIp+iUPEIeR6Je/tgV7zsA==} + + pvutils@1.1.3: + resolution: {integrity: sha512-pMpnA0qRdFp32b1sJl1wOJNxZLQ2cbQx+k6tjNtZ8CpvVhNqEPRgivZ2WOUev2YMajecdH7ctUPDvEe87nariQ==} + engines: {node: '>=6.0.0'} + + qrcode@1.5.3: + resolution: {integrity: sha512-puyri6ApkEHYiVl4CFzo1tDkAZ+ATcnbJrJ6RiBM1Fhctdn/ix9MTE3hRph33omisEbC/2fcfemsseiKgBPKZg==} + engines: {node: '>=10.13.0'} + hasBin: true + + qs@6.12.1: + resolution: {integrity: sha512-zWmv4RSuB9r2mYQw3zxQuHWeU+42aKi1wWig/j4ele4ygELZ7PEO6MM7rim9oAQH2A5MWfsAVf/jPvTPgCbvUQ==} + engines: {node: '>=0.6'} + + query-string@9.0.0: + resolution: {integrity: sha512-4EWwcRGsO2H+yzq6ddHcVqkCQ2EFUSfDMEjF8ryp8ReymyZhIuaFRGLomeOQLkrzacMHoyky2HW0Qe30UbzkKw==} + engines: {node: '>=18'} + + querystringify@2.2.0: + resolution: {integrity: sha512-FIqgj2EUvTa7R50u0rGsyTftzjYmv/a3hO345bZNrqabNqjtgiDMgmo4mkUjd+nzU5oF3dClKqFIPUKybUyqoQ==} + + queue-microtask@1.2.3: + resolution: {integrity: sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==} + + queue-tick@1.0.1: + resolution: {integrity: sha512-kJt5qhMxoszgU/62PLP1CJytzd2NKetjSRnyuj31fDd3Rlcz3fzlFdFLD1SItunPwyqEOkca6GbV612BWfaBag==} + + quick-lru@4.0.1: + resolution: {integrity: sha512-ARhCpm70fzdcvNQfPoy49IaanKkTlRWF2JMzqhcJbhSFRZv7nPTvZJdcY7301IPmvW+/p0RgIWnQDLJxifsQ7g==} + engines: {node: '>=8'} + + quick-lru@5.1.1: + resolution: {integrity: sha512-WuyALRjWPDGtt/wzJiadO5AXY+8hZ80hVpe6MyivgraREW751X3SbhRvG3eLKOYN+8VEvqLcf3wdnt44Z4S4SA==} + engines: {node: '>=10'} + + quick-lru@6.1.1: + resolution: {integrity: sha512-S27GBT+F0NTRiehtbrgaSE1idUAJ5bX8dPAQTdylEyNlrdcH5X4Lz7Edz3DYzecbsCluD5zO8ZNEe04z3D3u6Q==} + engines: {node: '>=12'} + + quick-lru@7.0.0: + resolution: {integrity: sha512-MX8gB7cVYTrYcFfAnfLlhRd0+Toyl8yX8uBx1MrX7K0jegiz9TumwOK27ldXrgDlHRdVi+MqU9Ssw6dr4BNreg==} + engines: {node: '>=18'} + + range-parser@1.2.1: + resolution: {integrity: sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==} + engines: {node: '>= 0.6'} + + raw-body@2.5.2: + resolution: {integrity: sha512-8zGqypfENjCIqGhgXToC8aB2r7YrBX+AQAfIPs/Mlk+BtPTztOvTS01NRW/3Eh60J+a48lt8qsCzirQ6loCVfA==} + engines: {node: '>= 0.8'} + + react-animate-height@3.0.4: + resolution: {integrity: sha512-k+mBS8yCzpFp+7BdrHsL5bXd6CO/2bYO2SvRGKfxK+Ss3nzplAJLlgnd6Zhcxe/avdpy/CgcziicFj7pIHgG5g==} + engines: {node: '>= 12.0.0'} + peerDependencies: + react: '>=16.8.0 || ^18.0.0' + react-dom: '>=16.8.0' + + react-color@2.19.3: + resolution: {integrity: sha512-LEeGE/ZzNLIsFWa1TMe8y5VYqr7bibneWmvJwm1pCn/eNmrabWDh659JSPn9BuaMpEfU83WTOJfnCcjDZwNQTA==} + peerDependencies: + react: '*' + + react-confetti@6.1.0: + resolution: {integrity: sha512-7Ypx4vz0+g8ECVxr88W9zhcQpbeujJAVqL14ZnXJ3I23mOI9/oBVTQ3dkJhUmB0D6XOtCZEM6N0Gm9PMngkORw==} + engines: {node: '>=10.18'} + peerDependencies: + react: ^16.3.0 || ^17.0.1 || ^18.0.0 + + react-device-detect@2.2.3: + resolution: {integrity: sha512-buYY3qrCnQVlIFHrC5UcUoAj7iANs/+srdkwsnNjI7anr3Tt7UY6MqNxtMLlr0tMBied0O49UZVK8XKs3ZIiPw==} + peerDependencies: + react: '>= 0.14.0 || ^18.0.0' + react-dom: '>= 0.14.0' + + react-dnd-html5-backend@16.0.0: + resolution: {integrity: sha512-be3lKEbbT8FQcoTjFlQ4ZXG/NVrFNJu9W0INc5rm/5EFQpHCkz+xpbB2U8j9uh5Bvk7AsJyQrZznEut0hrNPIA==} + + react-dnd@16.0.0: + resolution: {integrity: sha512-RCoeWRWhuwSoqdLaJV8N/weARLyXqsf43OC3QiBWPORIIGGovF/EqI8ckf14ca3bl6oZNI/igtxX49+IDmNDeQ==} + peerDependencies: + '@types/hoist-non-react-statics': '>= 3.3.1' + '@types/node': '>= 12' + '@types/react': '>= 16' + react: '>= 16.14 || ^18.0.0' + peerDependenciesMeta: + '@types/hoist-non-react-statics': + optional: true + '@types/node': + optional: true + '@types/react': + optional: true + + react-dom@18.2.0: + resolution: {integrity: sha512-6IMTriUmvsjHUjNtEDudZfuDQUoWXVxKHhlEGSk81n4YFS+r/Kl99wXiwlVXtPBtJenozv2P+hxDsw9eA7Xo6g==} + peerDependencies: + react: ^18.2.0 || ^18.0.0 + + react-dropzone@14.2.3: + resolution: {integrity: sha512-O3om8I+PkFKbxCukfIR3QAGftYXDZfOE2N1mr/7qebQJHs7U+/RSL/9xomJNpRg9kM5h9soQSdf0Gc7OHF5Fug==} + engines: {node: '>= 10.13'} + peerDependencies: + react: '>= 16.8 || 18.0.0 || ^18.0.0' + + react-error-boundary@3.1.4: + resolution: {integrity: sha512-uM9uPzZJTF6wRQORmSrvOIgt4lJ9MC1sNgEOj2XGsDTRE4kmpWxg7ENK9EWNKJRMAOY9z0MuF4yIfl6gp4sotA==} + engines: {node: '>=10', npm: '>=6'} + peerDependencies: + react: '>=16.13.1 || ^18.0.0' + + react-error-overlay@6.0.9: + resolution: {integrity: sha512-nQTTcUu+ATDbrSD1BZHr5kgSD4oF8OFjxun8uAaL8RwPBacGBNPf/yAuVVdx17N8XNzRDMrZ9XcKZHCjPW+9ew==} + + react-fast-compare@3.2.1: + resolution: {integrity: sha512-xTYf9zFim2pEif/Fw16dBiXpe0hoy5PxcD8+OwBnTtNLfIm3g6WxhKNurY+6OmdH1u6Ta/W/Vl6vjbYP1MFnDg==} + + react-helmet@6.1.0: + resolution: {integrity: sha512-4uMzEY9nlDlgxr61NL3XbKRy1hEkXmKNXhjbAIOVw5vcFrsdYbH2FEwcNyWvWinl103nXgzYNlns9ca+8kFiWw==} + peerDependencies: + react: '>=16.3.0 || ^18.0.0' + + react-hook-form@7.34.0: + resolution: {integrity: sha512-s0/TJ09NVlEk2JPp3yit1WnMuPNBXFmUKEQPulgDi9pYBw/ZmmAFHe6AXWq73Y+kp8ye4OcMf0Jv+i/qLPektg==} + engines: {node: '>=12.22.0'} + peerDependencies: + react: ^16.8.0 || ^17 || ^18 || ^18.0.0 + + react-hook-form@7.43.9: + resolution: {integrity: sha512-AUDN3Pz2NSeoxQ7Hs6OhQhDr6gtF9YRuutGDwPQqhSUAHJSgGl2VeY3qN19MG0SucpjgDiuMJ4iC5T5uB+eaNQ==} + engines: {node: '>=12.22.0'} + peerDependencies: + react: ^16.8.0 || ^17 || ^18 || ^18.0.0 + + react-hot-toast@2.2.0: + resolution: {integrity: sha512-248rXw13uhf/6TNDVzagX+y7R8J183rp7MwUMNkcrBRyHj/jWOggfXTGlM8zAOuh701WyVW+eUaWG2LeSufX9g==} + engines: {node: '>=10'} + peerDependencies: + react: '>=16 || ^18.0.0' + react-dom: '>=16' + + react-i18next@12.3.1: + resolution: {integrity: sha512-5v8E2XjZDFzK7K87eSwC7AJcAkcLt5xYZ4+yTPDAW1i7C93oOY1dnr4BaQM7un4Hm+GmghuiPvevWwlca5PwDA==} + peerDependencies: + i18next: '>= 19.0.0' + react: '>= 16.8.0 || ^18.0.0' + react-dom: '*' + react-native: '*' + peerDependenciesMeta: + react-dom: + optional: true + react-native: + optional: true + + react-is@16.13.1: + resolution: {integrity: sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==} + + react-is@17.0.2: + resolution: {integrity: sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==} + + react-is@18.2.0: + resolution: {integrity: sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==} + + react-lifecycles-compat@3.0.4: + resolution: {integrity: sha512-fBASbA6LnOU9dOU2eW7aQ8xmYBSXUIWr+UmF9b1efZBazGNO+rcXT/icdKnYm2pTwcRylVUYwW7H1PHfLekVzA==} + + react-markdown@9.0.0: + resolution: {integrity: sha512-v6yNf3AB8GfJ8lCpUvzxAXKxgsHpdmWPlcVRQ6Nocsezp255E/IDrF31kLQsPJeB/cKto/geUwjU36wH784FCA==} + peerDependencies: + '@types/react': '>=18' + react: '>=18 || ^18.0.0' + + react-modal@3.15.1: + resolution: {integrity: sha512-duB9bxOaYg7Zt6TMFldIFxQRtSP+Dg3F1ZX3FXxSUn+3tZZ/9JCgeAQKDg7rhZSAqopq8TFRw3yIbnx77gyFTw==} + engines: {node: '>=8'} + peerDependencies: + react: ^0.14.0 || ^15.0.0 || ^16 || ^17 || ^18 || ^18.0.0 + react-dom: ^0.14.0 || ^15.0.0 || ^16 || ^17 || ^18 + + react-paginate@8.1.3: + resolution: {integrity: sha512-zBp80DBRcaeBnAeHUfbGKD0XHfbGNUolQ+S60Ymfs8o7rusYaJYZMAt1j93ADDNLlzRmJ0tMF/NeTlcdKf7dlQ==} + peerDependencies: + react: ^16 || ^17 || ^18 || ^18.0.0 + + react-refresh@0.9.0: + resolution: {integrity: sha512-Gvzk7OZpiqKSkxsQvO/mbTN1poglhmAV7gR/DdIrRrSMXraRQQlfikRJOr3Nb9GTMPC5kof948Zy6jJZIFtDvQ==} + engines: {node: '>=0.10.0'} + + react-resize-detector@7.1.2: + resolution: {integrity: sha512-zXnPJ2m8+6oq9Nn8zsep/orts9vQv3elrpA+R8XTcW7DVVUJ9vwDwMXaBtykAYjMnkCIaOoK9vObyR7ZgFNlOw==} + peerDependencies: + react: ^16.0.0 || ^17.0.0 || ^18.0.0 + react-dom: ^16.0.0 || ^17.0.0 || ^18.0.0 + + react-router-dom@6.10.0: + resolution: {integrity: sha512-E5dfxRPuXKJqzwSe/qGcqdwa18QiWC6f3H3cWXM24qj4N0/beCIf/CWTipop2xm7mR0RCS99NnaqPNjHtrAzCg==} + engines: {node: '>=14'} + peerDependencies: + react: '>=16.8 || ^18.0.0' + react-dom: '>=16.8' + + react-router@6.10.0: + resolution: {integrity: sha512-Nrg0BWpQqrC3ZFFkyewrflCud9dio9ME3ojHCF/WLsprJVzkq3q3UeEhMCAW1dobjeGbWgjNn/PVF6m46ANxXQ==} + engines: {node: '>=14'} + peerDependencies: + react: '>=16.8 || ^18.0.0' + + react-side-effect@2.1.2: + resolution: {integrity: sha512-PVjOcvVOyIILrYoyGEpDN3vmYNLdy1CajSFNt4TDsVQC5KpTijDvWVoR+/7Rz2xT978D8/ZtFceXxzsPwZEDvw==} + peerDependencies: + react: ^16.3.0 || ^17.0.0 || ^18.0.0 + + react-smooth@2.0.1: + resolution: {integrity: sha512-Own9TA0GPPf3as4vSwFhDouVfXP15ie/wIHklhyKBH5AN6NFtdk0UpHBnonV11BtqDkAWlt40MOUc+5srmW7NA==} + peerDependencies: + prop-types: ^15.6.0 + react: ^15.0.0 || ^16.0.0 || ^17.0.0 || ^18.0.0 + react-dom: ^15.0.0 || ^16.0.0 || ^17.0.0 || ^18.0.0 + + react-string-replace@1.0.0: + resolution: {integrity: sha512-+iLsyE4AeSmnfctgswXOf1PmKRgns6wJ4LVb+8ADMU6mDK3jvBE11QzfMQf7CYtPUUiBCDjZ9ZppzXOIYrzCRg==} + engines: {node: '>=0.12.0'} + + react-syntax-highlighter@15.5.0: + resolution: {integrity: sha512-+zq2myprEnQmH5yw6Gqc8lD55QHnpKaU8TOcFeC/Lg/MQSs8UknEA0JC4nTZGFAXC2J2Hyj/ijJ7NlabyPi2gg==} + peerDependencies: + react: '>= 0.14.0 || ^18.0.0' + + react-timer-hook@3.0.5: + resolution: {integrity: sha512-n+98SdmYvui2ne3KyWb3Ldu4k0NYQa3g/VzW6VEIfZJ8GAk/jJsIY700M8Nd2vNSTj05c7wKyQfJBqZ0x7zfiA==} + peerDependencies: + react: '>=16.8.0 || ^18.0.0' + react-dom: '>=16.8.0' + + react-top-loading-bar@2.3.1: + resolution: {integrity: sha512-rQk2Nm+TOBrM1C4E3e6KwT65iXyRSgBHjCkr2FNja1S51WaPulRA5nKj/xazuQ3x89wDDdGsrqkqy0RBIfd0xg==} + engines: {node: '>=10'} + peerDependencies: + react: ^16 || ^17 || ^18 || ^18.0.0 + + react-transition-group@2.9.0: + resolution: {integrity: sha512-+HzNTCHpeQyl4MJ/bdE0u6XRMe9+XG/+aL4mCxVN4DnPBQ0/5bfHWPDuOZUzYdMj94daZaZdCCc1Dzt9R/xSSg==} + peerDependencies: + react: '>=15.0.0 || ^18.0.0' + react-dom: '>=15.0.0' + + react@18.2.0: + resolution: {integrity: sha512-/3IjMdb2L9QbBdWiW5e3P2/npwMBaU9mHCSCUzNln0ZCYbcfTsGbTJrU/kGemdH2IWmB2ioZ+zkxtmq6g09fGQ==} + engines: {node: '>=0.10.0'} + + reactcss@1.2.3: + resolution: {integrity: sha512-KiwVUcFu1RErkI97ywr8nvx8dNOpT03rbnma0SSalTYjkrPYaEajR4a/MRt6DZ46K6arDRbWMNHF+xH7G7n/8A==} + peerDependencies: + react: '*' + + read-pkg-up@7.0.1: + resolution: {integrity: sha512-zK0TB7Xd6JpCLmlLmufqykGE+/TlOePD6qKClNW7hHDKFh/J7/7gCWGR7joEQEW1bKq3a3yUZSObOoWLFQ4ohg==} + engines: {node: '>=8'} + + read-pkg-up@8.0.0: + resolution: {integrity: sha512-snVCqPczksT0HS2EC+SxUndvSzn6LRCwpfSvLrIfR5BKDQQZMaI6jPRC9dYvYFDRAuFEAnkwww8kBBNE/3VvzQ==} + engines: {node: '>=12'} + + read-pkg@5.2.0: + resolution: {integrity: sha512-Ug69mNOpfvKDAc2Q8DRpMjjzdtrnv9HcSMX+4VsZxD1aZ6ZzrIE7rlzXBtWTyhULSMKg076AW6WR5iZpD0JiOg==} + engines: {node: '>=8'} + + read-pkg@6.0.0: + resolution: {integrity: sha512-X1Fu3dPuk/8ZLsMhEj5f4wFAF0DWoK7qhGJvgaijocXxBmSToKfbFtqbxMO7bVjNA1dmE5huAzjXj/ey86iw9Q==} + engines: {node: '>=12'} + + read-yaml-file@1.1.0: + resolution: {integrity: sha512-VIMnQi/Z4HT2Fxuwg5KrY174U1VdUIASQVWXXyqtNRtxSr9IYkn1rsI6Tb6HsrHCmB7gVpNwX6JxPTHcH6IoTA==} + engines: {node: '>=6'} + + readable-stream@3.6.2: + resolution: {integrity: sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==} + engines: {node: '>= 6'} + + readdirp@3.6.0: + resolution: {integrity: sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==} + engines: {node: '>=8.10.0'} + + recharts-scale@0.4.5: + resolution: {integrity: sha512-kivNFO+0OcUNu7jQquLXAxz1FIwZj8nrj+YkOKc5694NbjCvcT6aSZiIzNzd2Kul4o4rTto8QVR9lMNtxD4G1w==} + + recharts@2.1.13: + resolution: {integrity: sha512-9VWu2nzExmfiMFDHKqRFhYlJVmjzQGVKH5rBetXR4EuyEXuu3Y6cVxQuNEdusHhbm4SoPPrVDCwlBdREL3sQPA==} + engines: {node: '>=12'} + peerDependencies: + prop-types: ^15.6.0 + react: ^16.0.0 || ^17.0.0 || ^18.0.0 + react-dom: ^16.0.0 || ^17.0.0 || ^18.0.0 + + redent@3.0.0: + resolution: {integrity: sha512-6tDA8g98We0zd0GvVeMT9arEOnTw9qM03L9cJXaCjrip1OO764RDBLBfrB4cwzNGDj5OA5ioymC9GkizgWJDUg==} + engines: {node: '>=8'} + + redent@4.0.0: + resolution: {integrity: sha512-tYkDkVVtYkSVhuQ4zBgfvciymHaeuel+zFKXShfDnFP5SyVEP7qo70Rf1jTOTCx3vGNAbnEi/xFkcfQVMIBWag==} + engines: {node: '>=12'} + + redis@4.6.5: + resolution: {integrity: sha512-O0OWA36gDQbswOdUuAhRL6mTZpHFN525HlgZgDaVNgCJIAZR3ya06NTESb0R+TUZ+BFaDpz6NnnVvoMx9meUFg==} + + reduce-css-calc@2.1.8: + resolution: {integrity: sha512-8liAVezDmUcH+tdzoEGrhfbGcP7nOV4NkGE3a74+qqvE7nt9i4sKLGBuZNOnpI4WiGksiNPklZxva80061QiPg==} + + redux@4.1.2: + resolution: {integrity: sha512-SH8PglcebESbd/shgf6mii6EIoRM0zrQyjcuQ+ojmfxjTtE0z9Y8pa62iA/OJ58qjP6j27uyW4kUF4jl/jd6sw==} + + reflect.getprototypeof@1.0.6: + resolution: {integrity: sha512-fmfw4XgoDke3kdI6h4xcUz1dG8uaiv5q9gcEwLS4Pnth2kxT+GZ7YehS1JTMGBQmtV7Y4GFGbs2re2NqhdozUg==} + engines: {node: '>= 0.4'} + + refractor@3.6.0: + resolution: {integrity: sha512-MY9W41IOWxxk31o+YvFCNyNzdkc9M20NoZK5vq6jkv4I/uh2zkWcfudj0Q1fovjUQJrNewS9NMzeTtqPf+n5EA==} + + regenerator-runtime@0.13.11: + resolution: {integrity: sha512-kY1AZVr2Ra+t+piVaJ4gxaFaReZVH40AKNo7UCX6W+dEwBo/2oZJzqfuN1qLq1oL45o56cPaTXELwrTh8Fpggg==} + + regenerator-runtime@0.14.1: + resolution: {integrity: sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw==} + + regexp-tree@0.1.27: + resolution: {integrity: sha512-iETxpjK6YoRWJG5o6hXLwvjYAoW+FEZn9os0PD/b6AP6xQwsa/Y7lCVgIixBbUPMfhu+i2LtdeAqVTgGlQarfA==} + hasBin: true + + regexp.prototype.flags@1.4.3: + resolution: {integrity: sha512-fjggEOO3slI6Wvgjwflkc4NFRCTZAu5CnNfBd5qOMYhWdn67nJBBu34/TkD++eeFmd8C9r9jfXJ27+nSiRkSUA==} + engines: {node: '>= 0.4'} + + regexp.prototype.flags@1.5.2: + resolution: {integrity: sha512-NcDiDkTLuPR+++OCKB0nWafEmhg/Da8aUPLPMQbK+bxKKCm1/S5he+AqYa4PlMCVBalb4/yxIRub6qkEx5yJbw==} + engines: {node: '>= 0.4'} + + regjsparser@0.10.0: + resolution: {integrity: sha512-qx+xQGZVsy55CH0a1hiVwHmqjLryfh7wQyF5HO07XJ9f7dQMY/gPQHhlyDkIzJKC+x2fUCpCcUODUUUFrm7SHA==} + hasBin: true + + remark-footnotes@2.0.0: + resolution: {integrity: sha512-3Clt8ZMH75Ayjp9q4CorNeyjwIxHFcTkaektplKGl2A1jNGEUey8cKL0ZC5vJwfcD5GFGsNLImLG/NGzWIzoMQ==} + + remark-gfm@4.0.0: + resolution: {integrity: sha512-U92vJgBPkbw4Zfu/IiW2oTZLSL3Zpv+uI7My2eq8JxKgqraFdU8YUGicEJCEgSbeaG+QDFqIcwwfMTOEelPxuA==} + + remark-mdx@1.6.22: + resolution: {integrity: sha512-phMHBJgeV76uyFkH4rvzCftLfKCr2RZuF+/gmVcaKrpsihyzmhXjA0BEMDaPTXG5y8qZOKPVo83NAOX01LPnOQ==} + + remark-parse@11.0.0: + resolution: {integrity: sha512-FCxlKLNGknS5ba/1lmpYijMUzX2esxW5xQqjWxw2eHFfS2MSdaHVINFmhjo+qN1WhZhNimq0dZATN9pH0IDrpA==} + + remark-parse@8.0.3: + resolution: {integrity: sha512-E1K9+QLGgggHxCQtLt++uXltxEprmWzNfg+MxpfHsZlrddKzZ/hZyWHDbK3/Ap8HJQqYJRXP+jHczdL6q6i85Q==} + + remark-rehype@11.0.0: + resolution: {integrity: sha512-vx8x2MDMcxuE4lBmQ46zYUDfcFMmvg80WYX+UNLeG6ixjdCCLcw1lrgAukwBTuOFsS78eoAedHGn9sNM0w7TPw==} + + remark-squeeze-paragraphs@4.0.0: + resolution: {integrity: sha512-8qRqmL9F4nuLPIgl92XUuxI3pFxize+F1H0e/W3llTk0UsjJaj01+RrirkMw7P21RKe4X6goQhYRSvNWX+70Rw==} + + remark-stringify@11.0.0: + resolution: {integrity: sha512-1OSmLd3awB/t8qdoEOMazZkNsfVTeY4fTsgzcQFdXNq8ToTN4ZGwrMnlda4K6smTFKD+GRV6O48i6Z4iKgPPpw==} + + repeat-string@1.6.1: + resolution: {integrity: sha512-PV0dzCYDNfRi1jCDbJzpW7jNNDRuCOG/jI5ctQcGKt/clZD+YcPS3yIlWuTJMmESC8aevCFmWJy5wjAFgNqN6w==} + engines: {node: '>=0.10'} + + require-directory@2.1.1: + resolution: {integrity: sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==} + engines: {node: '>=0.10.0'} + + require-from-string@2.0.2: + resolution: {integrity: sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==} + engines: {node: '>=0.10.0'} + + require-in-the-middle@7.2.0: + resolution: {integrity: sha512-3TLx5TGyAY6AOqLBoXmHkNql0HIf2RGbuMgCDT2WO/uGVAPJs6h7Kl+bN6TIZGd9bWhWPwnDnTHGtW8Iu77sdw==} + engines: {node: '>=8.6.0'} + + require-main-filename@2.0.0: + resolution: {integrity: sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==} + + requires-port@1.0.0: + resolution: {integrity: sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ==} + + resolve-alpn@1.2.1: + resolution: {integrity: sha512-0a1F4l73/ZFZOakJnQ3FvkJ2+gSTQWz/r2KE5OdDY0TxPm5h4GkqkWWfM47T7HsbnOtcJVEF4epCVy6u7Q3K+g==} + + resolve-cwd@3.0.0: + resolution: {integrity: sha512-OrZaX2Mb+rJCpH/6CpSqt9xFVpN++x01XnN2ie9g6P5/3xelLAkXWVADpdz1IHD/KFfEXyE6V0U01OQ3UO2rEg==} + engines: {node: '>=8'} + + resolve-dir@0.1.1: + resolution: {integrity: sha512-QxMPqI6le2u0dCLyiGzgy92kjkkL6zO0XyvHzjdTNH3zM6e5Hz3BwG6+aEyNgiQ5Xz6PwTwgQEj3U50dByPKIA==} + engines: {node: '>=0.10.0'} + + resolve-from@4.0.0: + resolution: {integrity: sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==} + engines: {node: '>=4'} + + resolve-from@5.0.0: + resolution: {integrity: sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==} + engines: {node: '>=8'} + + resolve-path@1.4.0: + resolution: {integrity: sha1-xL2p9e+y/OZSR4c6s2u02DT+Fvc=} + engines: {node: '>= 0.8'} + + resolve-pkg-maps@1.0.0: + resolution: {integrity: sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw==} + + resolve.exports@2.0.1: + resolution: {integrity: sha512-OEJWVeimw8mgQuj3HfkNl4KqRevH7lzeQNaWRPfx0PPse7Jk6ozcsG4FKVgtzDsC1KUF+YlTHh17NcgHOPykLw==} + engines: {node: '>=10'} + + resolve@1.22.2: + resolution: {integrity: sha512-Sb+mjNHOULsBv818T40qSPeRiuWLyaGMa5ewydRLFimneixmVy2zdivRl+AF6jaYPC8ERxGDmFSiqui6SfPd+g==} + hasBin: true + + resolve@1.22.8: + resolution: {integrity: sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw==} + hasBin: true + + resolve@2.0.0-next.5: + resolution: {integrity: sha512-U7WjGVG9sH8tvjW5SmGbQuui75FiyjAX72HX15DwBBwF9dNiQZRQAg9nnPhYy+TUnE0+VcrttuvNI8oSxZcocA==} + hasBin: true + + responselike@3.0.0: + resolution: {integrity: sha512-40yHxbNcl2+rzXvZuVkrYohathsSJlMTXKryG5y8uciHv1+xDLHQpgjG64JUO9nrEq2jGLH6IZ8BcZyw3wrweg==} + engines: {node: '>=14.16'} + + restore-cursor@4.0.0: + resolution: {integrity: sha512-I9fPXU9geO9bHOt9pHHOhOkYerIMsmVaWB0rA2AI9ERh/+x/i7MV5HKBNrg+ljO5eoPVgCcnFuRjJ9uH6I/3eg==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + + retry-request@7.0.2: + resolution: {integrity: sha512-dUOvLMJ0/JJYEn8NrpOaGNE7X3vpI5XlZS/u0ANjqtcZVKnIxP7IgCFwrKTxENw29emmwug53awKtaMm4i9g5w==} + engines: {node: '>=14'} + + retry@0.13.1: + resolution: {integrity: sha512-XQBQ3I8W1Cge0Seh+6gjj03LbmRFWuoszgK9ooCpwYIrhhoO80pfq4cUkU5DkknwfOfFteRwlZ56PYOGYyFWdg==} + engines: {node: '>= 4'} + + reusify@1.0.4: + resolution: {integrity: sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==} + engines: {iojs: '>=1.0.0', node: '>=0.10.0'} + + rfdc@1.3.0: + resolution: {integrity: sha512-V2hovdzFbOi77/WajaSMXk2OLm+xNIeQdMMuB7icj7bk6zi2F8GGAxigcnDFpJHbNyNcgyJDiP+8nOrY5cZGrA==} + + rimraf@3.0.2: + resolution: {integrity: sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==} + hasBin: true + + rimraf@5.0.5: + resolution: {integrity: sha512-CqDakW+hMe/Bz202FPEymy68P+G50RfMQK+Qo5YUqc9SPipvbGjCGKd0RSKEelbsfQuw3g5NZDSrlZZAJurH1A==} + engines: {node: '>=14'} + hasBin: true + + roarr@7.11.0: + resolution: {integrity: sha512-DKiMaEYHoOZ0JyD4Ohr5KRnqybQ162s3ZL/WNO9oy6EUszYvpp0eLYJErc/U4NI96HYnHsbROhFaH4LYuJPnDg==} + engines: {node: '>=12.0'} + + roarr@7.21.1: + resolution: {integrity: sha512-3niqt5bXFY1InKU8HKWqqYTYjtrBaxBMnXELXCXUYgtNYGUtZM5rB46HIC430AyacL95iEniGf7RgqsesykLmQ==} + engines: {node: '>=18.0'} + + rollup-plugin-output-size@1.3.0: + resolution: {integrity: sha512-OrTfhj8mxFAO4Yp7OEWwI388uhsiBNDCpfD6tOmcqPfNs5+CWZPDtVmTRZrmXMWfv8skWCOm5ToO4UPy7eRqYg==} + engines: {node: '>=14.16.0'} + peerDependencies: + rollup: ^2.0.0 || ^3.0.0 || ^4.0.0 + peerDependenciesMeta: + rollup: + optional: true + + rollup@4.12.0: + resolution: {integrity: sha512-wz66wn4t1OHIJw3+XU7mJJQV/2NAfw5OAk6G6Hoo3zcvz/XOfQ52Vgi+AN4Uxoxi0KBBwk2g8zPrTDA4btSB/Q==} + engines: {node: '>=18.0.0', npm: '>=8.0.0'} + hasBin: true + + rollup@4.14.3: + resolution: {integrity: sha512-ag5tTQKYsj1bhrFC9+OEWqb5O6VYgtQDO9hPDBMmIbePwhfSr+ExlcU741t8Dhw5DkPCQf6noz0jb36D6W9/hw==} + engines: {node: '>=18.0.0', npm: '>=8.0.0'} + hasBin: true + + run-async@2.4.1: + resolution: {integrity: sha512-tvVnVv01b8c1RrA6Ep7JkStj85Guv/YrMcwqYQnwjsAS2cTmmPGBBjAjpCW7RrSodNSoE2/qg9O4bceNvUuDgQ==} + engines: {node: '>=0.12.0'} + + run-parallel@1.2.0: + resolution: {integrity: sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==} + + rxjs@7.8.0: + resolution: {integrity: sha512-F2+gxDshqmIub1KdvZkaEfGDwLNpPvk9Fs6LD/MyQxNgMds/WH9OdDDXOmxUZpME+iSK3rQCctkL0DYyytUqMg==} + + rxjs@7.8.1: + resolution: {integrity: sha512-AA3TVj+0A2iuIoQkWEK/tqFjBq2j+6PO6Y0zJcvzLAFhEFIO3HL0vls9hWLncZbAAbK0mar7oZ4V079I/qPMxg==} + + safe-array-concat@1.1.2: + resolution: {integrity: sha512-vj6RsCsWBCf19jIeHEfkRMw8DPiBb+DMXklQ/1SGDHOMlHdPUkZXFQ2YdplS23zESTijAcurb1aSgJA3AgMu1Q==} + engines: {node: '>=0.4'} + + safe-buffer@5.2.1: + resolution: {integrity: sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==} + + safe-regex-test@1.0.0: + resolution: {integrity: sha512-JBUUzyOgEwXQY1NuPtvcj/qcBDbDmEvWufhlnXZIm75DEHp+afM1r1ujJpJsV/gSM4t59tpDyPi1sd6ZaPFfsA==} + + safe-regex-test@1.0.3: + resolution: {integrity: sha512-CdASjNJPvRa7roO6Ra/gLYBTzYzzPyyBXxIMdGW3USQLyjWEls2RgW5UBTXaQVp+OrpeCK3bLem8smtmheoRuw==} + engines: {node: '>= 0.4'} + + safe-stable-stringify@2.4.3: + resolution: {integrity: sha512-e2bDA2WJT0wxseVd4lsDP4+3ONX6HpMXQa1ZhFQ7SU+GjvORCmShbCMltrtIDfkYhVHrOcPtj+KhmDBdPdZD1g==} + engines: {node: '>=10'} + + safer-buffer@2.1.2: + resolution: {integrity: sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==} + + samlify@2.8.11: + resolution: {integrity: sha512-EDO9CMba0rtHSek2NyUcS8brIxK1E521X5fT+1qLKTRkm1dddITeuPqU8/by4Lcf95ngMKjsn5Z600eVhXDqxQ==} + + sass@1.56.1: + resolution: {integrity: sha512-VpEyKpyBPCxE7qGDtOcdJ6fFbcpOM+Emu7uZLxVrkX8KVU/Dp5UF7WLvzqRuUhB6mqqQt1xffLoG+AndxTZrCQ==} + engines: {node: '>=12.0.0'} + hasBin: true + + sax@1.2.4: + resolution: {integrity: sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw==} + + saxes@6.0.0: + resolution: {integrity: sha512-xAg7SOnEhrm5zI3puOOKyy1OMcMlIJZYNJY7xLBwSze0UjhPLnWfj2GF2EpT0jmzaJKIWKHLsaSSajf35bcYnA==} + engines: {node: '>=v12.22.7'} + + scheduler@0.23.0: + resolution: {integrity: sha512-CtuThmgHNg7zIZWAXi3AsyIzA3n4xx7aNyjwC2VJldO2LMVDhFK+63xGqq6CsJH4rTAt6/M+N4GhZiDYPx9eUw==} + + semver-compare@1.0.0: + resolution: {integrity: sha512-YM3/ITh2MJ5MtzaM429anh+x2jiLVjqILF4m4oyQB18W7Ggea7BfqdH/wGMK7dDiMghv/6WG7znWMwUDzJiXow==} + + semver@5.7.2: + resolution: {integrity: sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==} + hasBin: true + + semver@6.3.1: + resolution: {integrity: sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==} + hasBin: true + + semver@7.5.2: + resolution: {integrity: sha512-SoftuTROv/cRjCze/scjGyiDtcUyxw1rgYQSZY7XTmtR5hX+dm76iDbTH8TkLPHCQmlbQVSSbNZCPM2hb0knnQ==} + engines: {node: '>=10'} + hasBin: true + + semver@7.6.0: + resolution: {integrity: sha512-EnwXhrlwXMk9gKu5/flx5sv/an57AkRplG3hTK68W7FRDN+k+OWBj65M7719OkA82XLBxrcX0KSHj+X5COhOVg==} + engines: {node: '>=10'} + hasBin: true + + serialize-error@11.0.3: + resolution: {integrity: sha512-2G2y++21dhj2R7iHAdd0FIzjGwuKZld+7Pl/bTU6YIkrC2ZMbVUjm+luj6A6V34Rv9XfKJDKpTWu9W4Gse1D9g==} + engines: {node: '>=14.16'} + + set-blocking@2.0.0: + resolution: {integrity: sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw==} + + set-function-length@1.2.2: + resolution: {integrity: sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==} + engines: {node: '>= 0.4'} + + set-function-name@2.0.2: + resolution: {integrity: sha512-7PGFlmtwsEADb0WYyvCMa1t+yke6daIG4Wirafur5kcf+MhUnPms1UeR0CKQdTZD81yESwMHbtn+TR+dMviakQ==} + engines: {node: '>= 0.4'} + + setprototypeof@1.1.0: + resolution: {integrity: sha512-BvE/TwpZX4FXExxOxZyRGQQv651MSwmWKZGqvmPcRIjDqWub67kTKuIMx43cZZrS/cBBzwBcNDWoFxt2XEFIpQ==} + + setprototypeof@1.2.0: + resolution: {integrity: sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==} + + shebang-command@1.2.0: + resolution: {integrity: sha512-EV3L1+UQWGor21OmnvojK36mhg+TyIKDh3iFBKBohr5xeXIhNBcx8oWdgkTEEQ+BEFFYdLRuqMfd5L84N1V5Vg==} + engines: {node: '>=0.10.0'} + + shebang-command@2.0.0: + resolution: {integrity: sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==} + engines: {node: '>=8'} + + shebang-regex@1.0.0: + resolution: {integrity: sha512-wpoSFAxys6b2a2wHZ1XpDSgD7N9iVjg29Ph9uV/uaP9Ex/KXlkTZTeddxDPSYQpgvzKLGJke2UU0AzoGCjNIvQ==} + engines: {node: '>=0.10.0'} + + shebang-regex@3.0.0: + resolution: {integrity: sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==} + engines: {node: '>=8'} + + shell-quote@1.7.3: + resolution: {integrity: sha512-Vpfqwm4EnqGdlsBFNmHhxhElJYrdfcxPThu+ryKS5J8L/fhAwLazFZtq+S+TWZ9ANj2piSQLGj6NQg+lKPmxrw==} + + shimmer@1.2.1: + resolution: {integrity: sha512-sQTKC1Re/rM6XyFM6fIAGHRPVGvyXfgzIDvzoq608vM+jeyVD0Tu1E6Np0Kc2zAIFWIj963V2800iF/9LPieQw==} + + side-channel@1.0.6: + resolution: {integrity: sha512-fDW/EZ6Q9RiO8eFG8Hj+7u/oW+XrPTIChwCOM2+th2A6OblDtYYIpve9m+KvI9Z4C9qSEXlaGR6bTEYHReuglA==} + engines: {node: '>= 0.4'} + + siginfo@2.0.0: + resolution: {integrity: sha512-ybx0WO1/8bSBLEWXZvEd7gMW3Sn3JFlW3TvX1nREbDLRNQNaeNN8WK0meBwPdAaOI7TtRRRJn/Es1zhrrCHu7g==} + + signal-exit@3.0.7: + resolution: {integrity: sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==} + + signal-exit@4.1.0: + resolution: {integrity: sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==} + engines: {node: '>=14'} + + simple-swizzle@0.2.2: + resolution: {integrity: sha512-JA//kQgZtbuY83m+xT+tXJkmJncGMTFT+C+g2h2R9uxkYIrE2yy9sgmcLhCnw57/WSD+Eh3J97FPEDFnbXnDUg==} + + simple-update-notifier@2.0.0: + resolution: {integrity: sha512-a2B9Y0KlNXl9u/vsW6sTIu9vGEpfKu2wRV6l1H3XEas/0gUIzGzBoP/IouTcUQbm9JWZLH3COxyn03TYlFax6w==} + engines: {node: '>=10'} + + sinon@17.0.0: + resolution: {integrity: sha512-p4lJiYKBoOEVUxxVIC9H1MM2znG1/c8gud++I2BauJA5hsz7hHsst35eurNWXTusBsIq66FzOQbZ/uMdpvbPIQ==} + + sisteransi@1.0.5: + resolution: {integrity: sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg==} + + slash@3.0.0: + resolution: {integrity: sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==} + engines: {node: '>=8'} + + slice-ansi@4.0.0: + resolution: {integrity: sha512-qMCMfhY040cVHT43K9BFygqYbUPFZKHOg7K73mtTWJRb8pyP3fzf4Ixd5SzdEJQ6MRUg/WBnOLxghZtKKurENQ==} + engines: {node: '>=10'} + + slice-ansi@5.0.0: + resolution: {integrity: sha512-FC+lgizVPfie0kkhqUScwRu1O/lF6NOgJmlCgK+/LYxDCTk8sGelYaHDhFcDN+Sn3Cv+3VSa4Byeo+IMCzpMgQ==} + engines: {node: '>=12'} + + smart-buffer@4.2.0: + resolution: {integrity: sha512-94hK0Hh8rPqQl2xXc3HsaBoOXKV20MToPkcXvwbISWLEs+64sBq5kFgn2kJDHb1Pry9yrP0dxrCI9RRci7RXKg==} + engines: {node: '>= 6.0.0', npm: '>= 3.0.0'} + + smartwrap@2.0.2: + resolution: {integrity: sha512-vCsKNQxb7PnCNd2wY1WClWifAc2lwqsG8OaswpJkVJsvMGcnEntdTCDajZCkk93Ay1U3t/9puJmb525Rg5MZBA==} + engines: {node: '>=6'} + hasBin: true + + snake-case@3.0.4: + resolution: {integrity: sha512-LAOh4z89bGQvl9pFfNF8V146i7o7/CqFPbqzYgP+yYzDIDeS9HaNFtXABamRW+AQzEVODcvE79ljJ+8a9YSdMg==} + + snake-case@4.0.0: + resolution: {integrity: sha512-slvG6efKZ3GYUUZdhPOq/lLIqutwQ4TdPViD1VKqsbf0u76U/aPRswPKjOaAS9T7fAPmRmXuN6C/nM0xsMaFLQ==} + deprecated: Use `change-case` + + snakecase-keys@8.0.0: + resolution: {integrity: sha512-qS7XvESuFxskrmD8/O9tOMdLdV9YTuPfNLdRJIvNJKNEZtH9XVPwmZioROwl4TsVDbOFqlQ/o7pURuF8MnjYsg==} + engines: {node: '>=18'} + + socks-proxy-agent@8.0.2: + resolution: {integrity: sha512-8zuqoLv1aP/66PHF5TqwJ7Czm3Yv32urJQHrVyhD7mmA6d61Zv8cIXQYPTWwmg6qlupnPvs/QKDmfa4P/qct2g==} + engines: {node: '>= 14'} + + socks@2.7.1: + resolution: {integrity: sha512-7maUZy1N7uo6+WVEX6psASxtNlKaNVMlGQKkG/63nEDdLOWNbiUMoLK7X4uYoLhQstau72mLgfEWcXcwsaHbYQ==} + engines: {node: '>= 10.13.0', npm: '>= 3.0.0'} + + source-map-js@1.0.2: + resolution: {integrity: sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw==} + engines: {node: '>=0.10.0'} + + source-map-js@1.2.0: + resolution: {integrity: sha512-itJW8lvSA0TXEphiRoawsCksnlf8SyvmFzIhltqAHluXd88pkCd+cXJVHTDwdCr0IzwptSm035IHQktUu1QUMg==} + engines: {node: '>=0.10.0'} + + source-map-support@0.5.13: + resolution: {integrity: sha512-SHSKFHadjVA5oR4PPqhtAVdcBWwRYVd6g6cAXnIbRiIwc2EhPrTuKUBdSLvlEKyIP3GCf89fltvcZiP9MMFA1w==} + + source-map@0.5.7: + resolution: {integrity: sha512-LbrmJOMUSdEVxIKvdcJzQC+nQhe8FUZQTXQy6+I75skNgn3OoQ0DZA8YnFa7gp8tqtL3KPf1kmo0R5DoApeSGQ==} + engines: {node: '>=0.10.0'} + + source-map@0.6.1: + resolution: {integrity: sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==} + engines: {node: '>=0.10.0'} + + source-map@0.8.0-beta.0: + resolution: {integrity: sha512-2ymg6oRBpebeZi9UUNsgQ89bhx01TcTkmNTGnNO88imTmbSgy4nfujrgVEFKWpMTEGA11EDkTt7mqObTPdigIA==} + engines: {node: '>= 8'} + + space-separated-tokens@1.1.5: + resolution: {integrity: sha512-q/JSVd1Lptzhf5bkYm4ob4iWPjx0KiRe3sRFBNrVqbJkFaBm5vbbowy1mymoPNLRa52+oadOhJ+K49wsSeSjTA==} + + space-separated-tokens@2.0.1: + resolution: {integrity: sha512-ekwEbFp5aqSPKaqeY1PGrlGQxPNaq+Cnx4+bE2D8sciBQrHpbwoBbawqTN2+6jPs9IdWxxiUcN0K2pkczD3zmw==} + + spawnd@10.0.0: + resolution: {integrity: sha512-6GKcakMTryb5b1SWCvdubCDHEsR2k+5VZUD5G19umZRarkvj1RyCGyizcqhjewI7cqZo8fTVD8HpnDZbVOLMtg==} + engines: {node: '>=16'} + + spawndamnit@2.0.0: + resolution: {integrity: sha512-j4JKEcncSjFlqIwU5L/rp2N5SIPsdxaRsIv678+TZxZ0SRDJTm8JrxJMjE/XuiEZNEir3S8l0Fa3Ke339WI4qA==} + + spdx-correct@3.2.0: + resolution: {integrity: sha512-kN9dJbvnySHULIluDHy32WHRUu3Og7B9sbY7tsFLctQkIqnMh3hErYgdMjTYuqmcXX+lK5T1lnUt3G7zNswmZA==} + + spdx-exceptions@2.3.0: + resolution: {integrity: sha512-/tTrYOC7PPI1nUAgx34hUpqXuyJG+DTHJTnIULG4rDygi4xu/tfgmq1e1cIRwRzwZgo4NLySi+ricLkZkw4i5A==} + + spdx-expression-parse@3.0.1: + resolution: {integrity: sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q==} + + spdx-license-ids@3.0.13: + resolution: {integrity: sha512-XkD+zwiqXHikFZm4AX/7JSCXA98U5Db4AFd5XUg/+9UNtnH75+Z9KxtpYiJZx36mUDVOwH83pl7yvCer6ewM3w==} + + split-on-first@3.0.0: + resolution: {integrity: sha512-qxQJTx2ryR0Dw0ITYyekNQWpz6f8dGd7vffGNflQQ3Iqj9NJ6qiZ7ELpZsJ/QBhIVAiDfXdag3+Gp8RvWa62AA==} + engines: {node: '>=12'} + + split2@3.2.2: + resolution: {integrity: sha512-9NThjpgZnifTkJpzTZ7Eue85S49QwpNhZTq6GRJwObb6jnLFNGB7Qm73V5HewTROPyxD0C29xqmaI68bQtV+hg==} + + split2@4.2.0: + resolution: {integrity: sha512-UcjcJOWknrNkF6PLX83qcHM6KHgVKNkV62Y8a5uYDVv9ydGQVwAHMKqHdJje1VTWpljG0WYpCDhrCdAOYH4TWg==} + engines: {node: '>= 10.x'} + + sprintf-js@1.0.3: + resolution: {integrity: sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==} + + sql-parse@0.1.5: + resolution: {integrity: sha512-e2ExBX6iDHoCDC1zN2NvZV49UMhKVLvvwrDjzSVHFS3TKHKtIpl2nMDQkdlbTjDVvf2bxRYBq9iXAAMZvZpGVA==} + engines: {node: '>=0.10'} + + srcset@4.0.0: + resolution: {integrity: sha512-wvLeHgcVHKO8Sc/H/5lkGreJQVeYMm9rlmt8PuR1xE31rIuXhuzznUUqAt8MqLhB3MqJdFzlNAfpcWnxiFUcPw==} + engines: {node: '>=12'} + + stable@0.1.8: + resolution: {integrity: sha512-ji9qxRnOVfcuLDySj9qzhGSEFVobyt1kIOSkj1qZzYLzq7Tos/oUUWvotUPQLlrsidqsK6tBH89Bc9kL5zHA6w==} + deprecated: 'Modern JS already guarantees Array#sort() is a stable sort, so this library is deprecated. See the compatibility table on MDN: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/sort#browser_compatibility' + + stack-chain@1.3.7: + resolution: {integrity: sha512-D8cWtWVdIe/jBA7v5p5Hwl5yOSOrmZPWDPe2KxQ5UAGD+nxbxU0lKXA4h85Ta6+qgdKVL3vUxsbIZjc1kBG7ug==} + + stack-utils@2.0.5: + resolution: {integrity: sha512-xrQcmYhOsn/1kX+Vraq+7j4oE2j/6BFscZ0etmYg81xuM8Gq0022Pxb8+IqgOFUIaxHs0KaSb7T1+OegiNrNFA==} + engines: {node: '>=10'} + + stackback@0.0.2: + resolution: {integrity: sha512-1XMJE5fQo1jGH6Y/7ebnwPOBEkIEnT4QF32d5R1+VXdXveM0IBMJt8zfaxX1P3QhVwrYe+576+jkANtSS2mBbw==} + + state-local@1.0.7: + resolution: {integrity: sha512-HTEHMNieakEnoe33shBYcZ7NX83ACUjCu8c40iOGEZsngj9zRnkqS9j1pqQPXwobB0ZcVTk27REb7COQ0UR59w==} + + state-toggle@1.0.3: + resolution: {integrity: sha512-d/5Z4/2iiCnHw6Xzghyhb+GcmF89bxwgXG60wjIiZaxnymbyOmI8Hk4VqHXiVVp6u2ysaskFfXg3ekCj4WNftQ==} + + statuses@1.5.0: + resolution: {integrity: sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow=} + engines: {node: '>= 0.6'} + + statuses@2.0.1: + resolution: {integrity: sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==} + engines: {node: '>= 0.8'} + + std-env@3.7.0: + resolution: {integrity: sha512-JPbdCEQLj1w5GilpiHAx3qJvFndqybBysA3qUOnznweH4QbNYUsW/ea8QzSrnh0vNsezMMw5bcVool8lM0gwzg==} + + stdin-discarder@0.2.2: + resolution: {integrity: sha512-UhDfHmA92YAlNnCfhmq0VeNL5bDbiZGg7sZ2IvPsXubGkiNa9EC+tUTsjBRsYUAz87btI6/1wf4XoVvQ3uRnmQ==} + engines: {node: '>=18'} + + stream-events@1.0.5: + resolution: {integrity: sha512-E1GUzBSgvct8Jsb3v2X15pjzN1tYebtbLaMg+eBOUOAxgbLoSbT2NS91ckc5lJD1KfLjId+jXJRgo0qnV5Nerg==} + + stream-shift@1.0.3: + resolution: {integrity: sha512-76ORR0DO1o1hlKwTbi/DM3EXWGf3ZJYO8cXX5RJwnul2DEg2oyoZyjLNoQM8WsvZiFKCRfC1O0J7iCvie3RZmQ==} + + stream-transform@2.1.3: + resolution: {integrity: sha512-9GHUiM5hMiCi6Y03jD2ARC1ettBXkQBoQAe7nJsPknnI0ow10aXjTnew8QtYQmLjzn974BnmWEAJgCY6ZP1DeQ==} + + streamx@2.15.1: + resolution: {integrity: sha512-fQMzy2O/Q47rgwErk/eGeLu/roaFWV0jVsogDmrszM9uIw8L5OA+t+V93MgYlufNptfjmYR1tOMWhei/Eh7TQA==} + + string-argv@0.3.2: + resolution: {integrity: sha512-aqD2Q0144Z+/RqG52NeHEkZauTAUWJO8c6yTftGJKO3Tja5tUgIfmIl6kExvhtxSDP7fXB6DvzkfMpCd/F3G+Q==} + engines: {node: '>=0.6.19'} + + string-hash@1.1.3: + resolution: {integrity: sha1-6Kr8CsGFW0Zmkp7X3RJ1311sgRs=} + + string-length@4.0.2: + resolution: {integrity: sha512-+l6rNN5fYHNhZZy41RXsYptCjA2Igmq4EG7kZAYFQI1E1VTXarr6ZPXBg6eq7Y6eK4FEhY6AJlyuFIb/v/S0VQ==} + engines: {node: '>=10'} + + string-similarity@4.0.4: + resolution: {integrity: sha512-/q/8Q4Bl4ZKAPjj8WerIBJWALKkaPRfrvhfF8k/B23i4nzrlRj2/go1m90In7nG/3XDSbOo0+pu6RvCTM9RGMQ==} + + string-width@4.2.3: + resolution: {integrity: sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==} + engines: {node: '>=8'} + + string-width@5.1.2: + resolution: {integrity: sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==} + engines: {node: '>=12'} + + string-width@7.0.0: + resolution: {integrity: sha512-GPQHj7row82Hjo9hKZieKcHIhaAIKOJvFSIZXuCU9OASVZrMNUaZuz++SPVrBjnLsnk4k+z9f2EIypgxf2vNFw==} + engines: {node: '>=18'} + + string.prototype.matchall@4.0.11: + resolution: {integrity: sha512-NUdh0aDavY2og7IbBPenWqR9exH+E26Sv8e0/eTe1tltDGZL+GtBkDAnnyBtmekfK6/Dq3MkcGtzXFEd1LQrtg==} + engines: {node: '>= 0.4'} + + string.prototype.trim@1.2.9: + resolution: {integrity: sha512-klHuCNxiMZ8MlsOihJhJEBJAiMVqU3Z2nEXWfWnIqjN0gEFS9J9+IxKozWWtQGcgoa1WUZzLjKPTr4ZHNFTFxw==} + engines: {node: '>= 0.4'} + + string.prototype.trimend@1.0.5: + resolution: {integrity: sha512-I7RGvmjV4pJ7O3kdf+LXFpVfdNOxtCW/2C8f6jNiW4+PQchwxkCDzlk1/7p+Wl4bqFIZeF47qAHXLuHHWKAxog==} + + string.prototype.trimend@1.0.8: + resolution: {integrity: sha512-p73uL5VCHCO2BZZ6krwwQE3kCzM7NKmis8S//xEC6fQonchbum4eP6kR4DLEjQFO3Wnj3Fuo8NM0kOSjVdHjZQ==} + + string.prototype.trimstart@1.0.5: + resolution: {integrity: sha512-THx16TJCGlsN0o6dl2o6ncWUsdgnLRSA23rRE5pyGBw/mLr3Ej/R2LaqCtgP8VNMGZsvMWnf9ooZPyY2bHvUFg==} + + string.prototype.trimstart@1.0.8: + resolution: {integrity: sha512-UXSH262CSZY1tfu3G3Secr6uGLCFVPMhIqHjlgCUtCCcgihYc/xKs9djMTMUOb2j1mVSeU8EU6NWc/iQKU6Gfg==} + engines: {node: '>= 0.4'} + + string_decoder@1.3.0: + resolution: {integrity: sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==} + + strip-ansi@6.0.1: + resolution: {integrity: sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==} + engines: {node: '>=8'} + + strip-ansi@7.0.1: + resolution: {integrity: sha512-cXNxvT8dFNRVfhVME3JAe98mkXDYN2O1l7jmcwMnOslDeESg1rF/OZMtK0nRAhiari1unG5cD4jG3rapUAkLbw==} + engines: {node: '>=12'} + + strip-ansi@7.1.0: + resolution: {integrity: sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==} + engines: {node: '>=12'} + + strip-bom@3.0.0: + resolution: {integrity: sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==} + engines: {node: '>=4'} + + strip-bom@4.0.0: + resolution: {integrity: sha512-3xurFv5tEgii33Zi8Jtp55wEIILR9eh34FAW00PZf+JnSsTmV/ioewSgQl97JHvgjoRGwPShsWm+IdrxB35d0w==} + engines: {node: '>=8'} + + strip-final-newline@2.0.0: + resolution: {integrity: sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==} + engines: {node: '>=6'} + + strip-final-newline@3.0.0: + resolution: {integrity: sha512-dOESqjYr96iWYylGObzd39EuNTa5VJxyvVAEm5Jnh7KGo75V43Hk1odPQkNDyXNmUR6k+gEiDVXnjB8HJ3crXw==} + engines: {node: '>=12'} + + strip-indent@3.0.0: + resolution: {integrity: sha512-laJTa3Jb+VQpaC6DseHhF7dXVqHTfJPCRDaEbid/drOhgitgYku/letMUqOXFoWV0zIIUbjpdH2t+tYj4bQMRQ==} + engines: {node: '>=8'} + + strip-indent@4.0.0: + resolution: {integrity: sha512-mnVSV2l+Zv6BLpSD/8V87CW/y9EmmbYzGCIavsnsI6/nwn26DwffM/yztm30Z/I2DY9wdS3vXVCMnHDgZaVNoA==} + engines: {node: '>=12'} + + strip-json-comments@3.1.1: + resolution: {integrity: sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==} + engines: {node: '>=8'} + + strip-literal@2.0.0: + resolution: {integrity: sha512-f9vHgsCWBq2ugHAkGMiiYY+AYG0D/cbloKKg0nhaaaSNsujdGIpVXCNsrJpCKr5M0f4aI31mr13UjY6GAuXCKA==} + + strnum@1.0.5: + resolution: {integrity: sha512-J8bbNyKKXl5qYcR36TIO8W3mVGVHrmmxsd5PAItGkmyzwJvybiw2IVq5nqd0i4LSNSkB/sx9VHllbfFdr9k1JA==} + + stubs@3.0.0: + resolution: {integrity: sha512-PdHt7hHUJKxvTCgbKX9C1V/ftOcjJQgz8BZwNfV5c4B6dcGqlpelTbJ999jBGZ2jYiPAwcX5dP6oBwVlBlUbxw==} + + style-search@0.1.0: + resolution: {integrity: sha512-Dj1Okke1C3uKKwQcetra4jSuk0DqbzbYtXipzFlFMZtowbF1x7BKJwB9AayVMyFARvU8EDrZdcax4At/452cAg==} + + style-to-object@0.3.0: + resolution: {integrity: sha512-CzFnRRXhzWIdItT3OmF8SQfWyahHhjq3HwcMNCNLn+N7klOOqPjMeG/4JSu77D7ypZdGvSzvkrbyeTMizz2VrA==} + + style-to-object@0.4.2: + resolution: {integrity: sha512-1JGpfPB3lo42ZX8cuPrheZbfQ6kqPPnPHlKMyeRYtfKD+0jG+QsXgXN57O/dvJlzlB2elI6dGmrPnl5VPQFPaA==} + + stylelint-config-xo@0.22.0: + resolution: {integrity: sha512-E4IoDwgJqG+Q3LjeZGXNi3uOXOH5Sx6mCyxp1V4eaAm1DhuA+3X40c2GtobEIHfCv6itN/T3QKRb4V4/snIxUg==} + engines: {node: '>=16'} + peerDependencies: + stylelint: '>=14 || ^16.0.0' + + stylelint-declaration-block-no-ignored-properties@2.8.0: + resolution: {integrity: sha512-Ws8Cav7Y+SPN0JsV407LrnNXWOrqGjxShf+37GBtnU/C58Syve9c0+I/xpLcFOosST3ternykn3Lp77f3ITnFw==} + engines: {node: '>=6'} + peerDependencies: + stylelint: ^7.0.0 || ^8.0.0 || ^9.0.0 || ^10.0.0 || ^11.0.0 || ^12.0.0 || ^13.0.0 || ^14.0.0 || ^15.0.0 || ^16.0.0 + + stylelint-order@6.0.4: + resolution: {integrity: sha512-0UuKo4+s1hgQ/uAxlYU4h0o0HS4NiQDud0NAUNI0aa8FJdmYHA5ZZTFHiV5FpmE3071e9pZx5j0QpVJW5zOCUA==} + peerDependencies: + stylelint: ^14.0.0 || ^15.0.0 || ^16.0.1 || ^16.0.0 + + stylelint-scss@6.2.1: + resolution: {integrity: sha512-ZoGLbVb1keZYRVGQlhB8G6sZOoNqw61whzzzGFWp05N12ErqLFfBv3JPrXiMLZaW98sBS7K/vUQhRnvUj4vwdw==} + engines: {node: '>=18.12.0'} + peerDependencies: + stylelint: ^16.0.2 || ^16.0.0 + + stylelint@15.11.0: + resolution: {integrity: sha512-78O4c6IswZ9TzpcIiQJIN49K3qNoXTM8zEJzhaTE/xRTCZswaovSEVIa/uwbOltZrk16X4jAxjaOhzz/hTm1Kw==} + engines: {node: ^14.13.1 || >=16.0.0} + hasBin: true + + superagent@9.0.1: + resolution: {integrity: sha512-CcRSdb/P2oUVaEpQ87w9Obsl+E9FruRd6b2b7LdiBtJoyMr2DQt7a89anAfiX/EL59j9b2CbRFvf2S91DhuCww==} + engines: {node: '>=14.18.0'} + + superstruct@1.0.3: + resolution: {integrity: sha512-8iTn3oSS8nRGn+C2pgXSKPI3jmpm6FExNazNpjvqS6ZUJQCej3PUXEKM8NjHBOs54ExM+LPW/FBRhymrdcCiSg==} + engines: {node: '>=14.0.0'} + + supertest@7.0.0: + resolution: {integrity: sha512-qlsr7fIC0lSddmA3tzojvzubYxvlGtzumcdHgPwbFWMISQwL22MhM2Y3LNt+6w9Yyx7559VW5ab70dgphm8qQA==} + engines: {node: '>=14.18.0'} + + supports-color@5.5.0: + resolution: {integrity: sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==} + engines: {node: '>=4'} + + supports-color@7.2.0: + resolution: {integrity: sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==} + engines: {node: '>=8'} + + supports-color@8.1.1: + resolution: {integrity: sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==} + engines: {node: '>=10'} + + supports-hyperlinks@3.0.0: + resolution: {integrity: sha512-QBDPHyPQDRTy9ku4URNGY5Lah8PAaXs6tAAwp55sL5WCsSW7GIfdf6W5ixfziW+t7wh3GVvHyHHyQ1ESsoRvaA==} + engines: {node: '>=14.18'} + + supports-preserve-symlinks-flag@1.0.0: + resolution: {integrity: sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==} + engines: {node: '>= 0.4'} + + svg-parser@2.0.4: + resolution: {integrity: sha512-e4hG1hRwoOdRb37cIMSgzNsxyzKfayW6VOflrwvR+/bzrkyxY/31WkbgnQpgtrNp1SdpJvpUAGTa/ZoiPNDuRQ==} + + svg-tags@1.0.0: + resolution: {integrity: sha512-ovssysQTa+luh7A5Weu3Rta6FJlFBBbInjOh722LIt6klpU2/HtdUbszju/G4devcvk8PGt7FCLv5wftu3THUA==} + + svgo@2.8.0: + resolution: {integrity: sha512-+N/Q9kV1+F+UeWYoSiULYo4xYSDQlTgb+ayMobAXPwMnLvop7oxKMo9OzIrX5x3eS4L4f2UHhc9axXwY8DpChg==} + engines: {node: '>=10.13.0'} + hasBin: true + + swr@2.2.0: + resolution: {integrity: sha512-AjqHOv2lAhkuUdIiBu9xbuettzAzWXmCEcLONNKJRba87WAefz8Ca9d6ds/SzrPc235n1IxWYdhJ2zF3MNUaoQ==} + peerDependencies: + react: ^16.11.0 || ^17.0.0 || ^18.0.0 + + symbol-tree@3.2.4: + resolution: {integrity: sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw==} + + synckit@0.8.8: + resolution: {integrity: sha512-HwOKAP7Wc5aRGYdKH+dw0PRRpbO841v2DENBtjnR5HFWoiNByAl7vrx3p0G/rCyYXQsrxqtX48TImFtPcIHSpQ==} + engines: {node: ^14.18.0 || >=16.0.0} + + table@6.8.1: + resolution: {integrity: sha512-Y4X9zqrCftUhMeH2EptSSERdVKt/nEdijTOacGD/97EKjhQ/Qs8RTlEGABSJNNN8lac9kheH+af7yAkEWlgneA==} + engines: {node: '>=10.0.0'} + + tapable@2.2.1: + resolution: {integrity: sha512-GNzQvQTOIP6RyTfE2Qxb8ZVlNmw0n88vp1szwWRimP02mnTsx3Wtn5qRdqY9w2XduFNUgvOwhNnQsjwCp+kqaQ==} + engines: {node: '>=6'} + + tar-fs@3.0.5: + resolution: {integrity: sha512-JOgGAmZyMgbqpLwct7ZV8VzkEB6pxXFBVErLtb+XCOqzc6w1xiWKI9GVd6bwk68EX7eJ4DWmfXVmq8K2ziZTGg==} + + tar-stream@3.1.6: + resolution: {integrity: sha512-B/UyjYwPpMBv+PaFSWAmtYjwdrlEaZQEhMIBFNC5oEG8lpiW8XjcSdmEaClj28ArfKScKHs2nshz3k2le6crsg==} + + tar@7.0.1: + resolution: {integrity: sha512-IjMhdQMZFpKsHEQT3woZVxBtCQY+0wk3CVxdRkGXEgyGa0dNS/ehPvOMr2nmfC7x5Zj2N+l6yZUpmICjLGS35w==} + engines: {node: '>=18'} + + teeny-request@9.0.0: + resolution: {integrity: sha512-resvxdc6Mgb7YEThw6G6bExlXKkv6+YbuzGg9xuXxSgxJF7Ozs+o8Y9+2R3sArdWdW8nOokoQb1yrpFB0pQK2g==} + engines: {node: '>=14'} + + term-size@2.2.1: + resolution: {integrity: sha512-wK0Ri4fOGjv/XPy8SBHZChl8CM7uMc5VML7SqiQ0zG7+J5Vr+RMQDoHa2CNT6KHUnTGIXH34UDMkPzAUyapBZg==} + engines: {node: '>=8'} + + test-exclude@6.0.0: + resolution: {integrity: sha512-cAGWPIyOHU6zlmg88jwm7VRyXnMN7iV68OGAbYDk/Mh/xC/pzVPlQtY6ngoIH/5/tciuhGfvESU8GrHrcxD56w==} + engines: {node: '>=8'} + + text-encoder@0.0.4: + resolution: {integrity: sha512-12gllbNnC0Zdh9r+LCpEwpUdvncaE9hfUmCVm2ryCH1LEVUZbS6NdRq8omEgJI0zKgaGFTjwQVHbglGDCIbmNA==} + + text-extensions@2.4.0: + resolution: {integrity: sha512-te/NtwBwfiNRLf9Ijqx3T0nlqZiQ2XrrtBvu+cLL8ZRrGkO0NHTug8MYFKyoSrv/sHTaSKfilUkizV6XhxMJ3g==} + engines: {node: '>=8'} + + text-table@0.2.0: + resolution: {integrity: sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==} + + thirty-two@1.0.2: + resolution: {integrity: sha512-OEI0IWCe+Dw46019YLl6V10Us5bi574EvlJEOcAkB29IzQ/mYD1A6RyNHLjZPiHCmuodxvgF6U+vZO1L15lxVA==} + engines: {node: '>=0.2.6'} + + through2@4.0.2: + resolution: {integrity: sha512-iOqSav00cVxEEICeD7TjLB1sueEL+81Wpzp2bY17uZjZN0pWZPuo4suZ/61VujxmqSGFfgOcNuTZ85QJwNZQpw==} + + through@2.3.8: + resolution: {integrity: sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==} + + timsort@0.3.0: + resolution: {integrity: sha512-qsdtZH+vMoCARQtyod4imc2nIJwg9Cc7lPRrw9CzF8ZKR0khdr8+2nX80PBhET3tcyTtJDxAffGh2rXH4tyU8A==} + + tiny-cookie@2.4.1: + resolution: {integrity: sha512-h8ueaMyvUd/9ZfRqCfa1t+0tXqfVFhdK8WpLHz8VXMqsiaj3Sqg64AOCH/xevLQGZk0ZV+/75ouITdkvp3taVA==} + + tinybench@2.6.0: + resolution: {integrity: sha512-N8hW3PG/3aOoZAN5V/NSAEDz0ZixDSSt5b/a05iqtpgfLWMSVuCo7w0k2vVvEjdrIoeGqZzweX2WlyioNIHchA==} + + tinycolor2@1.6.0: + resolution: {integrity: sha512-XPaBkWQJdsf3pLKJV9p4qN/S+fm2Oj8AIPo1BTUhg5oxkvm9+SVEGFdhyOz7tTdUTfvxMiAs4sp6/eZO2Ew+pw==} + + tinypool@0.8.2: + resolution: {integrity: sha512-SUszKYe5wgsxnNOVlBYO6IC+8VGWdVGZWAqUxp3UErNBtptZvWbwyUOyzNL59zigz2rCA92QiL3wvG+JDSdJdQ==} + engines: {node: '>=14.0.0'} + + tinyspy@2.2.1: + resolution: {integrity: sha512-KYad6Vy5VDWV4GH3fjpseMQ/XU2BhIYP7Vzd0LG44qRWm/Yt2WCOTicFdvmgo6gWaqooMQCawTtILVQJupKu7A==} + engines: {node: '>=14.0.0'} + + titleize@4.0.0: + resolution: {integrity: sha512-ZgUJ1K83rhdu7uh7EHAC2BgY5DzoX8V5rTvoWI4vFysggi6YjLe5gUXABPWAU7VkvGP7P/0YiWq+dcPeYDsf1g==} + engines: {node: '>=18'} + + tmp@0.0.33: + resolution: {integrity: sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==} + engines: {node: '>=0.6.0'} + + tmpl@1.0.5: + resolution: {integrity: sha512-3f0uOEAQwIqGuWW2MVzYg8fV/QNnc/IpuJNG837rLuczAaLVHslWHZQj4IGiEl5Hs3kkbhwL9Ab7Hrsmuj+Smw==} + + to-fast-properties@2.0.0: + resolution: {integrity: sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog==} + engines: {node: '>=4'} + + to-regex-range@5.0.1: + resolution: {integrity: sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==} + engines: {node: '>=8.0'} + + toidentifier@1.0.1: + resolution: {integrity: sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==} + engines: {node: '>=0.6'} + + touch@3.1.0: + resolution: {integrity: sha512-WBx8Uy5TLtOSRtIq+M03/sKDrXCLHxwDcquSP2c43Le03/9serjQBIztjRz6FkJez9D/hleyAXTBGLwwZUw9lA==} + hasBin: true + + tough-cookie@4.1.3: + resolution: {integrity: sha512-aX/y5pVRkfRnfmuX+OdbSdXvPe6ieKX/G2s7e98f4poJHnqH3281gDPm/metm6E/WRamfx7WC4HUqkWHfQHprw==} + engines: {node: '>=6'} + + tr46@0.0.3: + resolution: {integrity: sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==} + + tr46@1.0.1: + resolution: {integrity: sha512-dTpowEjclQ7Kgx5SdBkqRzVhERQXov8/l9Ft9dVM9fmg0W0KQSVaXX9T4i6twCPNtYiZM53lpSSUAwJbFPOHxA==} + + tr46@3.0.0: + resolution: {integrity: sha512-l7FvfAHlcmulp8kr+flpQZmVwtu7nfRV7NZujtN0OqES8EL4O4e0qqzL0DC5gAvx/ZC/9lk6rhcUwYvkBnBnYA==} + engines: {node: '>=12'} + + tree-kill@1.2.2: + resolution: {integrity: sha512-L0Orpi8qGpRG//Nd+H90vFB+3iHnue1zSSGmNOOCh1GLJ7rUKVwV2HvijphGQS2UmhUZewS9VgvxYIdgr+fG1A==} + hasBin: true + + trim-lines@3.0.1: + resolution: {integrity: sha512-kRj8B+YHZCc9kQYdWfJB2/oUl9rA99qbowYYBtr4ui4mZyAQ2JpvVBd/6U2YloATfqBhBTSMhTpgBHtU0Mf3Rg==} + + trim-newlines@3.0.1: + resolution: {integrity: sha512-c1PTsA3tYrIsLGkJkzHF+w9F2EyxfXGo4UyJc4pFL++FMjnq0HJS69T3M7d//gKrFKwy429bouPescbjecU+Zw==} + engines: {node: '>=8'} + + trim-newlines@4.1.1: + resolution: {integrity: sha512-jRKj0n0jXWo6kh62nA5TEh3+4igKDXLvzBJcPpiizP7oOolUrYIxmVBG9TOtHYFHoddUk6YvAkGeGoSVTXfQXQ==} + engines: {node: '>=12'} + + trim-trailing-lines@1.1.4: + resolution: {integrity: sha512-rjUWSqnfTNrjbB9NQWfPMH/xRK1deHeGsHoVfpxJ++XeYXE0d6B1En37AHfw3jtfTU7dzMzZL2jjpe8Qb5gLIQ==} + + trim@0.0.1: + resolution: {integrity: sha1-WFhUf2spB1fulczMZm+1AITEYN0=} + + trough@1.0.5: + resolution: {integrity: sha512-rvuRbTarPXmMb79SmzEp8aqXNKcK+y0XaB298IXueQ8I2PsrATcPBCSPyK/dDNa2iWOhKlfNnOjdAOTBU/nkFA==} + + trough@2.1.0: + resolution: {integrity: sha512-AqTiAOLcj85xS7vQ8QkAV41hPDIJ71XJB4RCUrzo/1GM2CQwhkJGaf9Hgr7BOugMRpgGUrqRg/DrBDl4H40+8g==} + + ts-api-utils@1.3.0: + resolution: {integrity: sha512-UQMIo7pb8WRomKR1/+MFVLTroIvDVtMX3K6OUir8ynLyzB8Jeriont2bTAtmNPa1ekAgN7YPDyf6V+ygrdU+eQ==} + engines: {node: '>=16'} + peerDependencies: + typescript: '>=4.2.0' + + ts-node@10.9.2: + resolution: {integrity: sha512-f0FFpIdcHgn8zcPSbf1dRevwt047YMnaiJM3u2w2RewrB+fob/zePZcrOyQoLMMO7aBIddLcQIEK5dYjkLnGrQ==} + hasBin: true + peerDependencies: + '@swc/core': '>=1.2.50' + '@swc/wasm': '>=1.2.50' + '@types/node': '*' + typescript: '>=2.7' + peerDependenciesMeta: + '@swc/core': + optional: true + '@swc/wasm': + optional: true + + tsconfig-paths@3.15.0: + resolution: {integrity: sha512-2Ac2RgzDe/cn48GvOe3M+o82pEFewD3UPbyoUHHdKasHwJKjds4fLXWf/Ux5kATBKN20oaFGu+jbElp1pos0mg==} + + tslib@1.14.1: + resolution: {integrity: sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==} + + tslib@2.4.1: + resolution: {integrity: sha512-tGyy4dAjRIEwI7BzsB0lynWgOpfqjUdq91XXAlIWD2OwKBH7oCl/GZG/HT4BOHrTlPMOASlMQ7veyTqpmRcrNA==} + + tslib@2.5.0: + resolution: {integrity: sha512-336iVw3rtn2BUK7ORdIAHTyxHGRIHVReokCR3XjbckJMK7ms8FysBfhLR8IXnAgy7T0PTPNBWKiH514FOW/WSg==} + + tslib@2.6.2: + resolution: {integrity: sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q==} + + tsscmp@1.0.6: + resolution: {integrity: sha512-LxhtAkPDTkVCMQjt2h6eBVY28KCjikZqZfMcC15YBeNjkgUpdCfBu5HoiOTDu86v6smE8yOjyEktJ8hlbANHQA==} + engines: {node: '>=0.6.x'} + + tty-table@4.1.6: + resolution: {integrity: sha512-kRj5CBzOrakV4VRRY5kUWbNYvo/FpOsz65DzI5op9P+cHov3+IqPbo1JE1ZnQGkHdZgNFDsrEjrfqqy/Ply9fw==} + engines: {node: '>=8.0.0'} + hasBin: true + + tunnel@0.0.6: + resolution: {integrity: sha512-1h/Lnq9yajKY2PEbBadPXj3VxsDDu844OnaAo52UVmIzIvwwtBPIuNvkjuzBlTWpfJyUbG3ez0KSBibQkj4ojg==} + engines: {node: '>=0.6.11 <=0.7.0 || >=0.7.3'} + + tween-functions@1.2.0: + resolution: {integrity: sha512-PZBtLYcCLtEcjL14Fzb1gSxPBeL7nWvGhO5ZFPGqziCcr8uvHp0NDmdjBchp6KHL+tExcg0m3NISmKxhU394dA==} + + type-check@0.3.2: + resolution: {integrity: sha512-ZCmOJdvOWDBYJlzAoFkC+Q0+bUyEOS1ltgp1MGU03fqHG+dbi9tBFU2Rd9QKiDZFAYrhPh2JUf7rZRIuHRKtOg==} + engines: {node: '>= 0.8.0'} + + type-check@0.4.0: + resolution: {integrity: sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==} + engines: {node: '>= 0.8.0'} + + type-detect@4.0.8: + resolution: {integrity: sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==} + engines: {node: '>=4'} + + type-fest@0.13.1: + resolution: {integrity: sha512-34R7HTnG0XIJcBSn5XhDd7nNFPRcXYRZrBB2O2jdKqYODldSzBAqzsWoZYYvduky73toYS/ESqxPvkDf/F0XMg==} + engines: {node: '>=10'} + + type-fest@0.20.2: + resolution: {integrity: sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==} + engines: {node: '>=10'} + + type-fest@0.21.3: + resolution: {integrity: sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==} + engines: {node: '>=10'} + + type-fest@0.6.0: + resolution: {integrity: sha512-q+MB8nYR1KDLrgr4G5yemftpMC7/QLqVndBmEEdqzmNj5dcFOO4Oo8qlwZE3ULT3+Zim1F8Kq4cBnikNhlCMlg==} + engines: {node: '>=8'} + + type-fest@0.8.1: + resolution: {integrity: sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==} + engines: {node: '>=8'} + + type-fest@1.4.0: + resolution: {integrity: sha512-yGSza74xk0UG8k+pLh5oeoYirvIiWo5t0/o3zHHAO2tRDiZcxWP7fywNlXhqb6/r6sWvwi+RsyQMWhVLe4BVuA==} + engines: {node: '>=10'} + + type-fest@2.19.0: + resolution: {integrity: sha512-RAH822pAdBgcNMAfWnCBU3CFZcfZ/i1eZjwFU/dsLKumyuuP3niueg2UAukXYF0E2AAoc82ZSSf9J0WQBinzHA==} + engines: {node: '>=12.20'} + + type-fest@3.13.1: + resolution: {integrity: sha512-tLq3bSNx+xSpwvAJnzrK0Ep5CLNWjvFTOp71URMaAEWBfRb9nnJiBoUe0tF8bI4ZFO3omgBR6NvnbzVUT3Ly4g==} + engines: {node: '>=14.16'} + + type-fest@4.15.0: + resolution: {integrity: sha512-tB9lu0pQpX5KJq54g+oHOLumOx+pMep4RaM6liXh2PKmVRFF+/vAtUP0ZaJ0kOySfVNjF6doBWPHhBhISKdlIA==} + engines: {node: '>=16'} + + type-fest@4.2.0: + resolution: {integrity: sha512-5zknd7Dss75pMSED270A1RQS3KloqRJA9XbXLe0eCxyw7xXFb3rd+9B0UQ/0E+LQT6lnrLviEolYORlRWamn4w==} + engines: {node: '>=16'} + + type-is@1.6.18: + resolution: {integrity: sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==} + engines: {node: '>= 0.6'} + + typed-array-buffer@1.0.2: + resolution: {integrity: sha512-gEymJYKZtKXzzBzM4jqa9w6Q1Jjm7x2d+sh19AdsD4wqnMPDYyvwpsIc2Q/835kHuo3BEQ7CjelGhfTsoBb2MQ==} + engines: {node: '>= 0.4'} + + typed-array-byte-length@1.0.1: + resolution: {integrity: sha512-3iMJ9q0ao7WE9tWcaYKIptkNBuOIcZCCT0d4MRvuuH88fEoEH62IuQe0OtraD3ebQEoTRk8XCBoknUNc1Y67pw==} + engines: {node: '>= 0.4'} + + typed-array-byte-offset@1.0.2: + resolution: {integrity: sha512-Ous0vodHa56FviZucS2E63zkgtgrACj7omjwd/8lTEMEPFFyjfixMZ1ZXenpgCFBBt4EC1J2XsyVS2gkG0eTFA==} + engines: {node: '>= 0.4'} + + typed-array-length@1.0.6: + resolution: {integrity: sha512-/OxDN6OtAk5KBpGb28T+HZc2M+ADtvRxXrKKbUwtsLgdoxgX13hyy7ek6bFRl5+aBs2yZzB0c4CnQfAtVypW/g==} + engines: {node: '>= 0.4'} + + typescript@5.0.2: + resolution: {integrity: sha512-wVORMBGO/FAs/++blGNeAVdbNKtIh1rbBL2EyQ1+J9lClJ93KiiKe8PmFIVdXhHcyv44SL9oglmfeSsndo0jRw==} + engines: {node: '>=12.20'} + hasBin: true + + typescript@5.3.3: + resolution: {integrity: sha512-pXWcraxM0uxAS+tN0AG/BF2TyqmHO014Z070UsJ+pFvYuRSq8KH8DmWpnbXe0pEPDHXZV3FcAbJkijJ5oNEnWw==} + engines: {node: '>=14.17'} + hasBin: true + + ua-parser-js@1.0.37: + resolution: {integrity: sha512-bhTyI94tZofjo+Dn8SN6Zv8nBDvyXTymAdM3LDI/0IboIUwTu1rEhW7v2TfiVsoYWgkQ4kOVqnI8APUFbIQIFQ==} + + ufo@1.5.2: + resolution: {integrity: sha512-eiutMaL0J2MKdhcOM1tUy13pIrYnyR87fEd8STJQFrrAwImwvlXkxlZEjaKah8r2viPohld08lt73QfLG1NxMg==} + + unbox-primitive@1.0.2: + resolution: {integrity: sha512-61pPlCD9h51VoreyJ0BReideM3MDKMKnh6+V9L08331ipq6Q8OFXZYiqP6n/tbHx4s5I9uRhcye6BrbkizkBDw==} + + unbzip2-stream@1.4.3: + resolution: {integrity: sha512-mlExGW4w71ebDJviH16lQLtZS32VKqsSfk80GCfUlwT/4/hNRFsoscrF/c++9xinkMzECL1uL9DDwXqFWkruPg==} + + undefsafe@2.0.5: + resolution: {integrity: sha512-WxONCrssBM8TSPRqN5EmsjVrsv4A8X12J4ArBiiayv3DyyG3ZlIg6yysuuSYdZsVz3TKcTg2fd//Ujd4CHV1iA==} + + undici-types@5.26.5: + resolution: {integrity: sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==} + + unherit@1.1.3: + resolution: {integrity: sha512-Ft16BJcnapDKp0+J/rqFC3Rrk6Y/Ng4nzsC028k2jdDII/rdZ7Wd3pPT/6+vIIxRagwRc9K0IUX0Ra4fKvw+WQ==} + + unicorn-magic@0.1.0: + resolution: {integrity: sha512-lRfVq8fE8gz6QMBuDM6a+LO3IAzTi05H6gCVaUpir2E1Rwpo4ZUog45KpNXKC/Mn3Yb9UDuHumeFTo9iV/D9FQ==} + engines: {node: '>=18'} + + unified@11.0.3: + resolution: {integrity: sha512-jlCV402P+YDcFcB2VcN/n8JasOddqIiaxv118wNBoZXEhOn+lYG7BR4Bfg2BwxvlK58dwbuH2w7GX2esAjL6Mg==} + + unified@9.2.0: + resolution: {integrity: sha512-vx2Z0vY+a3YoTj8+pttM3tiJHCwY5UFbYdiWrwBEbHmK8pvsPj2rtAX2BFfgXen8T39CJWblWRDT4L5WGXtDdg==} + + unist-builder@2.0.3: + resolution: {integrity: sha512-f98yt5pnlMWlzP539tPc4grGMsFaQQlP/vM396b00jngsiINumNmsY8rkXjfoi1c6QaM8nQ3vaGDuoKWbe/1Uw==} + + unist-util-generated@1.1.6: + resolution: {integrity: sha512-cln2Mm1/CZzN5ttGK7vkoGw+RZ8VcUH6BtGbq98DDtRGquAAOXig1mrBQYelOwMXYS8rK+vZDyyojSjp7JX+Lg==} + + unist-util-is@4.1.0: + resolution: {integrity: sha512-ZOQSsnce92GrxSqlnEEseX0gi7GH9zTJZ0p9dtu87WRb/37mMPO2Ilx1s/t9vBHrFhbgweUwb+t7cIn5dxPhZg==} + + unist-util-is@6.0.0: + resolution: {integrity: sha512-2qCTHimwdxLfz+YzdGfkqNlH0tLi9xjTnHddPmJwtIG9MGsdbutfTc4P+haPD7l7Cjxf/WZj+we5qfVPvvxfYw==} + + unist-util-position@3.1.0: + resolution: {integrity: sha512-w+PkwCbYSFw8vpgWD0v7zRCl1FpY3fjDSQ3/N/wNd9Ffa4gPi8+4keqt99N3XW6F99t/mUzp2xAhNmfKWp95QA==} + + unist-util-position@5.0.0: + resolution: {integrity: sha512-fucsC7HjXvkB5R3kTCO7kUjRdrS0BJt3M/FPxmHMBOm8JQi2BsHAHFsy27E0EolP8rp0NzXsJ+jNPyDWvOJZPA==} + + unist-util-remove-position@2.0.1: + resolution: {integrity: sha512-fDZsLYIe2uT+oGFnuZmy73K6ZxOPG/Qcm+w7jbEjaFcJgbQ6cqjs/eSPzXhsmGpAsWPkqZM9pYjww5QTn3LHMA==} + + unist-util-remove@2.1.0: + resolution: {integrity: sha512-J8NYPyBm4baYLdCbjmf1bhPu45Cr1MWTm77qd9istEkzWpnN6O9tMsEbB2JhNnBCqGENRqEWomQ+He6au0B27Q==} + + unist-util-stringify-position@2.0.3: + resolution: {integrity: sha512-3faScn5I+hy9VleOq/qNbAd6pAx7iH5jYBMS9I1HgQVijz/4mv5Bvw5iw1sC/90CODiKo81G/ps8AJrISn687g==} + + unist-util-stringify-position@4.0.0: + resolution: {integrity: sha512-0ASV06AAoKCDkS2+xw5RXJywruurpbC4JZSm7nr7MOt1ojAzvyyaO+UxZf18j8FCF6kmzCZKcAgN/yu2gm2XgQ==} + + unist-util-visit-parents@3.1.1: + resolution: {integrity: sha512-1KROIZWo6bcMrZEwiH2UrXDyalAa0uqzWCxCJj6lPOvTve2WkfgCytoDTPaMnodXh1WrXOq0haVYHj99ynJlsg==} + + unist-util-visit-parents@6.0.1: + resolution: {integrity: sha512-L/PqWzfTP9lzzEa6CKs0k2nARxTdZduw3zyh8d2NVBnsyvHjSX4TWse388YrrQKbvI8w20fGjGlhgT96WwKykw==} + + unist-util-visit@2.0.3: + resolution: {integrity: sha512-iJ4/RczbJMkD0712mGktuGpm/U4By4FfDonL7N/9tATGIF4imikjOuagyMY53tnZq3NP6BcmlrHhEKAfGWjh7Q==} + + unist-util-visit@5.0.0: + resolution: {integrity: sha512-MR04uvD+07cwl/yhVuVWAtw+3GOR/knlL55Nd/wAdblk27GCVt3lqpTivy/tkJcZoNPzTwS1Y+KMojlLDhoTzg==} + + universalify@0.1.2: + resolution: {integrity: sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==} + engines: {node: '>= 4.0.0'} + + universalify@0.2.0: + resolution: {integrity: sha512-CJ1QgKmNg3CwvAv/kOFmtnEN05f0D/cn9QntgNOQlQF9dgvVTHj3t+8JPdjqawCHk7V/KA+fbUqzZ9XWhcqPUg==} + engines: {node: '>= 4.0.0'} + + unpipe@1.0.0: + resolution: {integrity: sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==} + engines: {node: '>= 0.8'} + + update-browserslist-db@1.0.10: + resolution: {integrity: sha512-OztqDenkfFkbSG+tRxBeAnCVPckDBcvibKd35yDONx6OU8N7sqgwc7rCbkJ/WcYtVRZ4ba68d6byhC21GFh7sQ==} + hasBin: true + peerDependencies: + browserslist: '>= 4.21.0' + + update-browserslist-db@1.0.13: + resolution: {integrity: sha512-xebP81SNcPuNpPP3uzeW1NYXxI3rxyJzF3pD6sH4jE7o/IX+WtSpwnVU+qIsDPyk0d3hmFQ7mjqc6AtV604hbg==} + hasBin: true + peerDependencies: + browserslist: '>= 4.21.0' + + uri-js@4.4.1: + resolution: {integrity: sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==} + + url-parse@1.5.10: + resolution: {integrity: sha512-WypcfiRhfeUP9vvF0j6rw0J3hrWrw6iZv3+22h6iRMJ/8z1Tj6XfLP4DsUix5MhMPnXpiHDoKyoZ/bdCkwBCiQ==} + + urlpattern-polyfill@10.0.0: + resolution: {integrity: sha512-H/A06tKD7sS1O1X2SshBVeA5FLycRpjqiBeqGKmBwBDBy28EnRjORxTNe269KSSr5un5qyWi1iL61wLxpd+ZOg==} + + use-debounced-loader@0.1.1: + resolution: {integrity: sha512-FbY/ynor7wZV55v1EvvAvu8CvSoEKT1azS2zFb/aLlL0vySbqTM7x9fIcaOJN++E52mVINNDe2VmWWd+Q00S+A==} + engines: {node: '>=10'} + peerDependencies: + react: '>=16 || ^18.0.0' + + use-sync-external-store@1.2.0: + resolution: {integrity: sha512-eEgnFxGQ1Ife9bzYs6VLi8/4X6CObHMw9Qr9tPY43iKwsPw8xE8+EFsf/2cFZ5S3esXgpWgtSCtLNS41F+sKPA==} + peerDependencies: + react: ^16.8.0 || ^17.0.0 || ^18.0.0 + + util-deprecate@1.0.2: + resolution: {integrity: sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==} + + utility-types@3.10.0: + resolution: {integrity: sha512-O11mqxmi7wMKCo6HKFt5AhO4BwY3VV68YU07tgxfz8zJTIxr4BpsezN49Ffwy9j3ZpwwJp4fkRwjRzq3uWE6Rg==} + engines: {node: '>= 4'} + + uuid@8.3.2: + resolution: {integrity: sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==} + hasBin: true + + uuid@9.0.1: + resolution: {integrity: sha512-b+1eJOlsR9K8HJpow9Ok3fiWOWSIcIzXodvv0rQjVoOVNpWMpxf1wZNpt4y9h10odCNrqnYp1OBzRktckBe3sA==} + hasBin: true + + v8-compile-cache-lib@3.0.1: + resolution: {integrity: sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==} + + v8-to-istanbul@9.2.0: + resolution: {integrity: sha512-/EH/sDgxU2eGxajKdwLCDmQ4FWq+kpi3uCmBGpw1xJtnAxEjlD8j8PEiGWpCIMIs3ciNAgH0d3TTJiUkYzyZjA==} + engines: {node: '>=10.12.0'} + + validate-npm-package-license@3.0.4: + resolution: {integrity: sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==} + + vary@1.1.2: + resolution: {integrity: sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==} + engines: {node: '>= 0.8'} + + vfile-location@3.2.0: + resolution: {integrity: sha512-aLEIZKv/oxuCDZ8lkJGhuhztf/BW4M+iHdCwglA/eWc+vtuRFJj8EtgceYFX4LRjOhCAAiNHsKGssC6onJ+jbA==} + + vfile-message@2.0.4: + resolution: {integrity: sha512-DjssxRGkMvifUOJre00juHoP9DPWuzjxKuMDrhNbk2TdaYYBNMStsNhEOt3idrtI12VQYM/1+iM0KOzXi4pxwQ==} + + vfile-message@4.0.2: + resolution: {integrity: sha512-jRDZ1IMLttGj41KcZvlrYAaI3CfqpLpfpf+Mfig13viT6NKvRzWZ+lXz0Y5D60w6uJIBAOGq9mSHf0gktF0duw==} + + vfile@4.2.1: + resolution: {integrity: sha512-O6AE4OskCG5S1emQ/4gl8zK586RqA3srz3nfK/Viy0UPToBc5Trp9BVFb1u0CjsKrAWwnpr4ifM/KBXPWwJbCA==} + + vfile@6.0.1: + resolution: {integrity: sha512-1bYqc7pt6NIADBJ98UiG0Bn/CHIVOoZ/IyEkqIruLg0mE1BKzkOXY2D6CSqQIcKqgadppE5lrxgWXJmXd7zZJw==} + + vite-node@1.4.0: + resolution: {integrity: sha512-VZDAseqjrHgNd4Kh8icYHWzTKSCZMhia7GyHfhtzLW33fZlG9SwsB6CEhgyVOWkJfJ2pFLrp/Gj1FSfAiqH9Lw==} + engines: {node: ^18.0.0 || >=20.0.0} + hasBin: true + + vite@5.2.9: + resolution: {integrity: sha512-uOQWfuZBlc6Y3W/DTuQ1Sr+oIXWvqljLvS881SVmAj00d5RdgShLcuXWxseWPd4HXwiYBFW/vXHfKFeqj9uQnw==} + 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 + + vitest@1.4.0: + 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 + + void-elements@3.1.0: + resolution: {integrity: sha1-YU9/v42AHwu18GYfWy9XhXUOTwk=} + engines: {node: '>=0.10.0'} + + w3c-xmlserializer@3.0.0: + resolution: {integrity: sha512-3WFqGEgSXIyGhOmAFtlicJNMjEps8b1MG31NCA0/vOF9+nKMUW1ckhi9cnNHmf88Rzw5V+dwIwsm2C7X8k9aQg==} + engines: {node: '>=12'} + + wait-on@7.2.0: + resolution: {integrity: sha512-wCQcHkRazgjG5XoAq9jbTMLpNIjoSlZslrJ2+N9MxDsGEv1HnFoVjOCexL0ESva7Y9cu350j+DWADdk54s4AFQ==} + engines: {node: '>=12.0.0'} + hasBin: true + + walker@1.0.8: + resolution: {integrity: sha512-ts/8E8l5b7kY0vlWLewOkDXMmPdLcVV4GmOQLyxuSswIJsweeFZtAsMF7k1Nszz+TYBQrlYRmzOnr398y1JemQ==} + + warning@4.0.3: + resolution: {integrity: sha512-rpJyN222KWIvHJ/F53XSZv0Zl/accqHR8et1kpaMTD/fLCRxtV8iX8czMzY7sVZupTI3zcUTg8eycS2kNF9l6w==} + + wcwidth@1.0.1: + resolution: {integrity: sha512-XHPEwS0q6TaxcvG85+8EYkbiCux2XtWG2mkc47Ng2A77BQu9+DqIOJldST4HgPkuea7dvKSj5VgX3P1d4rW8Tg==} + + weak-lru-cache@1.2.2: + resolution: {integrity: sha512-DEAoo25RfSYMuTGc9vPJzZcZullwIqRDSI9LOy+fkCJPi6hykCnfKaXTuPBDuXAUcqHXyOgFtHNp/kB2FjYHbw==} + + web-namespaces@1.1.4: + resolution: {integrity: sha512-wYxSGajtmoP4WxfejAPIr4l0fVh+jeMXZb08wNc0tMg6xsfZXj3cECqIK0G7ZAqUq0PP8WlMDtaOGVBTAWztNw==} + + webidl-conversions@3.0.1: + resolution: {integrity: sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==} + + webidl-conversions@4.0.2: + resolution: {integrity: sha512-YQ+BmxuTgd6UXZW3+ICGfyqRyHXVlD5GtQr5+qjiNW7bF0cqrzX500HVXPBOvgXb5YnzDd+h0zqyv61KUD7+Sg==} + + webidl-conversions@7.0.0: + resolution: {integrity: sha512-VwddBukDzu71offAQR975unBIGqfKZpM+8ZX6ySk8nYhVoo5CYaZyzt3YBvYtRtO+aoGlqxPg/B87NGVZ/fu6g==} + engines: {node: '>=12'} + + whatwg-encoding@2.0.0: + resolution: {integrity: sha512-p41ogyeMUrw3jWclHWTQg1k05DSVXPLcVxRTYsXUk+ZooOCZLcoYgPZ/HL/D/N+uQPOtcp1me1WhBEaX02mhWg==} + engines: {node: '>=12'} + + whatwg-mimetype@3.0.0: + resolution: {integrity: sha512-nt+N2dzIutVRxARx1nghPKGv1xHikU7HKdfafKkLNLindmPU/ch3U31NOCGGA/dmPcmb1VlofO0vnKAcsm0o/Q==} + engines: {node: '>=12'} + + whatwg-url@11.0.0: + resolution: {integrity: sha512-RKT8HExMpoYx4igMiVMY83lN6UeITKJlBQ+vR/8ZJ8OCdSiN3RwCq+9gH0+Xzj0+5IrM6i4j/6LuvzbZIQgEcQ==} + engines: {node: '>=12'} + + whatwg-url@5.0.0: + resolution: {integrity: sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==} + + whatwg-url@7.1.0: + resolution: {integrity: sha512-WUu7Rg1DroM7oQvGWfOiAK21n74Gg+T4elXEQYkOhtyLeWiJFoOGLXPKI/9gzIie9CtwVLm8wtw6YJdKyxSjeg==} + + which-boxed-primitive@1.0.2: + resolution: {integrity: sha512-bwZdv0AKLpplFY2KZRX6TvyuN7ojjr7lwkg6ml0roIy9YeuSr7JS372qlNW18UQYzgYK9ziGcerWqZOmEn9VNg==} + + which-builtin-type@1.1.3: + resolution: {integrity: sha512-YmjsSMDBYsM1CaFiayOVT06+KJeXf0o5M/CAd4o1lTadFAtacTUM49zoYxr/oroopFDfhvN6iEcBxUyc3gvKmw==} + engines: {node: '>= 0.4'} + + which-collection@1.0.2: + resolution: {integrity: sha512-K4jVyjnBdgvc86Y6BkaLZEN933SwYOuBFkdmBu9ZfkcAbdVbpITnDmjvZ/aQjRXQrv5EPkTnD1s39GiiqbngCw==} + engines: {node: '>= 0.4'} + + which-module@2.0.0: + resolution: {integrity: sha512-B+enWhmw6cjfVC7kS8Pj9pCrKSc5txArRyaYGe088shv/FGWH+0Rjx/xPgtsWfsUtS27FkP697E4DDhgrgoc0Q==} + + which-pm@2.0.0: + resolution: {integrity: sha512-Lhs9Pmyph0p5n5Z3mVnN0yWcbQYUAD7rbQUiMsQxOJ3T57k7RFe35SUwWMf7dsbDZks1uOmw4AecB/JMDj3v/w==} + engines: {node: '>=8.15'} + + which-typed-array@1.1.15: + resolution: {integrity: sha512-oV0jmFtUky6CXfkqehVvBP/LSWJ2sy4vWMioiENyJLePrBO/yKyV9OyJySfAKosh+RYkIl5zJCNZ8/4JncrpdA==} + engines: {node: '>= 0.4'} + + which@1.3.1: + resolution: {integrity: sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==} + hasBin: true + + which@2.0.2: + resolution: {integrity: sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==} + engines: {node: '>= 8'} + hasBin: true + + why-is-node-running@2.2.2: + resolution: {integrity: sha512-6tSwToZxTOcotxHeA+qGCq1mVzKR3CwcJGmVcY+QE8SHy6TnpFnh8PAvPNHYr7EcuVeG0QSMxtYCuO1ta/G/oA==} + engines: {node: '>=8'} + hasBin: true + + word-wrap@1.2.3: + resolution: {integrity: sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ==} + engines: {node: '>=0.10.0'} + + wrap-ansi@6.2.0: + resolution: {integrity: sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==} + engines: {node: '>=8'} + + wrap-ansi@7.0.0: + resolution: {integrity: sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==} + engines: {node: '>=10'} + + wrap-ansi@8.0.1: + resolution: {integrity: sha512-QFF+ufAqhoYHvoHdajT/Po7KoXVBPXS2bgjIam5isfWJPfIOnQZ50JtUiVvCv/sjgacf3yRrt2ZKUZ/V4itN4g==} + engines: {node: '>=12'} + + wrap-ansi@8.1.0: + resolution: {integrity: sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==} + engines: {node: '>=12'} + + wrappy@1.0.2: + resolution: {integrity: sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==} + + write-file-atomic@4.0.2: + resolution: {integrity: sha512-7KxauUdBmSdWnmpaGFg+ppNjKF8uNLry8LyzjauQDOVONfFLNKrKvQOxZ/VuTIcS/gge/YNahf5RIIQWTSarlg==} + engines: {node: ^12.13.0 || ^14.15.0 || >=16.0.0} + + write-file-atomic@5.0.1: + resolution: {integrity: sha512-+QU2zd6OTD8XWIJCbffaiQeH9U73qIqafo1x6V1snCWYGJf6cVE0cDR4D8xRzcEnfI21IFrUPzPGtcPf8AC+Rw==} + engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} + + ws@8.16.0: + resolution: {integrity: sha512-HS0c//TP7Ina87TfiPUz1rQzMhHrl/SG2guqRcTOIUYD2q8uhUdNHZYJUaQ8aTGPzCh+c6oawMKW35nFl1dxyQ==} + engines: {node: '>=10.0.0'} + peerDependencies: + bufferutil: ^4.0.1 + utf-8-validate: '>=5.0.2' + peerDependenciesMeta: + bufferutil: + optional: true + utf-8-validate: + optional: true + + xml-crypto@3.0.1: + resolution: {integrity: sha512-7XrwB3ujd95KCO6+u9fidb8ajvRJvIfGNWD0XLJoTWlBKz+tFpUzEYxsN+Il/6/gHtEs1RgRh2RH+TzhcWBZUw==} + engines: {node: '>=0.4.0'} + + xml-escape@1.1.0: + resolution: {integrity: sha512-B/T4sDK8Z6aUh/qNr7mjKAwwncIljFuUP+DO/D5hloYFj+90O88z8Wf7oSucZTHxBAsC1/CTP4rtx/x1Uf72Mg==} + + xml-name-validator@4.0.0: + resolution: {integrity: sha512-ICP2e+jsHvAj2E2lIHxa5tjXRlKDJo4IdvPvCXbXQGdzSfmSpNVyIKMvoZHjDY9DP0zV17iI85o90vRFXNccRw==} + engines: {node: '>=12'} + + xml2js@0.5.0: + resolution: {integrity: sha512-drPFnkQJik/O+uPKpqSgr22mpuFHqKdbS835iAQrUC73L2F5WkboIRd63ai/2Yg6I1jzifPFKH2NTK+cfglkIA==} + engines: {node: '>=4.0.0'} + + xml@1.0.1: + resolution: {integrity: sha512-huCv9IH9Tcf95zuYCsQraZtWnJvBtLVE0QHMOs8bWyZAFZNDcYjsPq1nEx8jKA9y+Beo9v+7OBPRisQTjinQMw==} + + xmlbuilder@11.0.1: + resolution: {integrity: sha512-fDlsI/kFEx7gLvbecc0/ohLG50fugQp8ryHzMTuW9vSa1GJ0XYWKnhsUx7oie3G98+r56aTQIUB4kht42R3JvA==} + engines: {node: '>=4.0'} + + xmlchars@2.2.0: + resolution: {integrity: sha512-JZnDKK8B0RCDw84FNdDAIpZK+JuJw+s7Lz8nksI7SIuU3UXJJslUthsi+uWBUYOwPFwW7W7PRLRfUKpxjtjFCw==} + + xpath@0.0.32: + resolution: {integrity: sha512-rxMJhSIoiO8vXcWvSifKqhvV96GjiD5wYb8/QHdoRyQvraTpp4IEv944nhGausZZ3u7dhQXteZuZbaqfpB7uYw==} + engines: {node: '>=0.6.0'} + + xtend@4.0.2: + resolution: {integrity: sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==} + engines: {node: '>=0.4'} + + xxhash-wasm@0.4.2: + resolution: {integrity: sha512-/eyHVRJQCirEkSZ1agRSCwriMhwlyUcFkXD5TPVSLP+IPzjsqMVzZwdoczLp1SoQU0R3dxz1RpIK+4YNQbCVOA==} + + y18n@4.0.3: + resolution: {integrity: sha512-JKhqTOwSrqNA1NY5lSztJ1GrBiUodLMmIZuLiDaMRJ+itFd+ABVE8XBjOvIWL+rSqNDC74LCSFmlb/U4UZ4hJQ==} + + y18n@5.0.8: + resolution: {integrity: sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==} + engines: {node: '>=10'} + + yallist@2.1.2: + resolution: {integrity: sha512-ncTzHV7NvsQZkYe1DW7cbDLm0YpzHmZF5r/iyP3ZnQtMiJ+pjzisCiMNI+Sj+xQF5pXhSHxSB3uDbsBTzY/c2A==} + + yallist@3.1.1: + resolution: {integrity: sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==} + + yallist@4.0.0: + resolution: {integrity: sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==} + + yallist@5.0.0: + resolution: {integrity: sha512-YgvUTfwqyc7UXVMrB+SImsVYSmTS8X/tSrtdNZMImM+n7+QTriRXyXim0mBrTXNeqzVF0KWGgHPeiyViFFrNDw==} + engines: {node: '>=18'} + + yaml@1.10.2: + resolution: {integrity: sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg==} + engines: {node: '>= 6'} + + yaml@2.3.3: + resolution: {integrity: sha512-zw0VAJxgeZ6+++/su5AFoqBbZbrEakwu+X0M5HmcwUiBL7AzcuPKjj5we4xfQLp78LkEMpD0cOnUhmgOVy3KdQ==} + engines: {node: '>= 14'} + + yargs-parser@18.1.3: + resolution: {integrity: sha512-o50j0JeToy/4K6OZcaQmW6lyXXKhq7csREXcDwk2omFPJEwUNOVtJKvmDr9EI1fAJZUyZcRF7kxGBWmRXudrCQ==} + engines: {node: '>=6'} + + yargs-parser@20.2.9: + resolution: {integrity: sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w==} + engines: {node: '>=10'} + + yargs-parser@21.1.1: + resolution: {integrity: sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==} + engines: {node: '>=12'} + + yargs@15.4.1: + resolution: {integrity: sha512-aePbxDmcYW++PaqBsJ+HYUFwCdv4LVvdnhBy78E57PIor8/OVvhMrADFFEDh8DHDFRv/O9i3lPhsENjO7QX0+A==} + engines: {node: '>=8'} + + yargs@17.6.0: + resolution: {integrity: sha512-8H/wTDqlSwoSnScvV2N/JHfLWOKuh5MVla9hqLjK3nsfyy6Y4kDSYSvkU5YCUEPOSnRXfIyx3Sq+B/IWudTo4g==} + engines: {node: '>=12'} + + yargs@17.7.2: + resolution: {integrity: sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==} + engines: {node: '>=12'} + + yauzl@2.10.0: + resolution: {integrity: sha512-p4a9I6X6nu6IhoGmBqAcbJy1mlC4j27vEPZX9F4L4/vZT3Lyq1VkFHw/V/PUcB9Buo+DG3iHkT0x3Qya58zc3g==} + + ylru@1.2.1: + resolution: {integrity: sha512-faQrqNMzcPCHGVC2aaOINk13K+aaBDUPjGWl0teOXywElLjyVAB6Oe2jj62jHYtwsU49jXhScYbvPENK+6zAvQ==} + engines: {node: '>= 4.0.0'} + + yn@3.1.1: + resolution: {integrity: sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==} + engines: {node: '>=6'} + + yocto-queue@0.1.0: + resolution: {integrity: sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==} + engines: {node: '>=10'} + + yocto-queue@1.0.0: + resolution: {integrity: sha512-9bnSc/HEW2uRy67wc+T8UwauLuPJVn28jb+GtJY16iiKWyvmYJRXVT4UamsAEGQfPohgr2q4Tq0sQbQlxTfi1g==} + engines: {node: '>=12.20'} + + zod-to-ts@1.2.0: + resolution: {integrity: sha512-x30XE43V+InwGpvTySRNz9kB7qFU8DlyEy7BsSTCHPH1R0QasMmHWZDCzYm6bVXtj/9NNJAZF3jW8rzFvH5OFA==} + peerDependencies: + typescript: ^4.9.4 || ^5.0.2 + zod: ^3 + + zod@3.22.4: + resolution: {integrity: sha512-iC+8Io04lddc+mVqQ9AZ7OQ2MrUKGN+oIQyq1vemgt46jwCwLfhq7/pwnBnNXXXZb8VTVLKwp9EDkx+ryxIWmg==} + + zwitch@1.0.5: + resolution: {integrity: sha512-V50KMwwzqJV0NpZIZFwfOD5/lyny3WlSzRiXgA0G7VUnRlqttta1L6UQIHzd6EuBY/cHGfwTIck7w1yH6Q5zUw==} + + zwitch@2.0.2: + resolution: {integrity: sha512-JZxotl7SxAJH0j7dN4pxsTV6ZLXoLdGME+PsjkL/DaBrVryK9kTGq06GfKrwcSOqypP+fdXGoCHE36b99fWVoA==} + +snapshots: + + '@aashutoshrathi/word-wrap@1.2.6': {} + + '@ampproject/remapping@2.3.0': dependencies: '@jridgewell/gen-mapping': 0.3.5 '@jridgewell/trace-mapping': 0.3.25 - dev: true - /@apidevtools/json-schema-ref-parser@9.0.6: - resolution: {integrity: sha512-M3YgsLjI0lZxvrpeGVk9Ap032W6TPQkH6pRAZz81Ac3WUNF79VQooAFnp8umjvVzUmD93NkogxEwbSce7qMsUg==} + '@apidevtools/json-schema-ref-parser@9.0.6': dependencies: '@jsdevtools/ono': 7.1.3 call-me-maybe: 1.0.2 js-yaml: 3.14.1 - dev: true - /@apidevtools/openapi-schemas@2.1.0: - resolution: {integrity: sha512-Zc1AlqrJlX3SlpupFGpiLi2EbteyP7fXmUOGup6/DnkRgjP9bgMM/ag+n91rsv0U1Gpz0H3VILA/o3bW7Ua6BQ==} - engines: {node: '>=10'} - dev: true + '@apidevtools/openapi-schemas@2.1.0': {} - /@apidevtools/swagger-methods@3.0.2: - resolution: {integrity: sha512-QAkD5kK2b1WfjDS/UQn/qQkbwF31uqRjPTrsCs5ZG9BQGAkjwvqGFjjPqAuzac/IYzpPtRzjCP1WrTuAIjMrXg==} - dev: true + '@apidevtools/swagger-methods@3.0.2': {} - /@apidevtools/swagger-parser@10.1.0(openapi-types@12.1.3): - resolution: {integrity: sha512-9Kt7EuS/7WbMAUv2gSziqjvxwDbFSg3Xeyfuj5laUODX8o/k/CpsAKiQ8W7/R88eXFTMbJYg6+7uAmOWNKmwnw==} - peerDependencies: - openapi-types: '>=7' + '@apidevtools/swagger-parser@10.1.0(openapi-types@12.1.3)': dependencies: '@apidevtools/json-schema-ref-parser': 9.0.6 '@apidevtools/openapi-schemas': 2.1.0 @@ -4155,50 +12955,35 @@ packages: ajv-draft-04: 1.0.0(ajv@8.12.0) call-me-maybe: 1.0.2 openapi-types: 12.1.3 - dev: true - /@authenio/samlify-node-xmllint@2.0.0(samlify@2.8.11): - resolution: {integrity: sha512-V9cQ0CHqu3JwOmbSecGPUnzIES5kHxD00FEZKnWh90ksQUJG5/TscV2r9XLbKp7MlRMOSUfWxecM35xPSLFdSg==} - peerDependencies: - samlify: '>= 2.6.0' + '@authenio/samlify-node-xmllint@2.0.0(samlify@2.8.11)': dependencies: node-xmllint: 1.0.0 samlify: 2.8.11 - dev: false - /@authenio/xml-encryption@2.0.2: - resolution: {integrity: sha512-cTlrKttbrRHEw3W+0/I609A2Matj5JQaRvfLtEIGZvlN0RaPi+3ANsMeqAyCAVlH/lUIW2tmtBlSMni74lcXeg==} - engines: {node: '>=12'} + '@authenio/xml-encryption@2.0.2': dependencies: '@xmldom/xmldom': 0.8.7 escape-html: 1.0.3 xpath: 0.0.32 - dev: false - /@aws-crypto/crc32@3.0.0: - resolution: {integrity: sha512-IzSgsrxUcsrejQbPVilIKy16kAT52EwB6zSaI+M3xxIhKh5+aldEyvI+z6erM7TCLB2BJsFrtHjp6/4/sr+3dA==} + '@aws-crypto/crc32@3.0.0': dependencies: '@aws-crypto/util': 3.0.0 '@aws-sdk/types': 3.535.0 tslib: 1.14.1 - dev: false - /@aws-crypto/crc32c@3.0.0: - resolution: {integrity: sha512-ENNPPManmnVJ4BTXlOjAgD7URidbAznURqD0KvfREyc4o20DPYdEldU1f5cQ7Jbj0CJJSPaMIk/9ZshdB3210w==} + '@aws-crypto/crc32c@3.0.0': dependencies: '@aws-crypto/util': 3.0.0 '@aws-sdk/types': 3.535.0 tslib: 1.14.1 - dev: false - /@aws-crypto/ie11-detection@3.0.0: - resolution: {integrity: sha512-341lBBkiY1DfDNKai/wXM3aujNBkXR7tq1URPQDL9wi3AUbI80NR74uF1TXHMm7po1AcnFk8iu2S2IeU/+/A+Q==} + '@aws-crypto/ie11-detection@3.0.0': dependencies: tslib: 1.14.1 - dev: false - /@aws-crypto/sha1-browser@3.0.0: - resolution: {integrity: sha512-NJth5c997GLHs6nOYTzFKTbYdMNA6/1XlKVgnZoaZcQ7z7UJlOgj2JdbHE8tiYLS3fzXNCguct77SPGat2raSw==} + '@aws-crypto/sha1-browser@3.0.0': dependencies: '@aws-crypto/ie11-detection': 3.0.0 '@aws-crypto/supports-web-crypto': 3.0.0 @@ -4207,10 +12992,8 @@ packages: '@aws-sdk/util-locate-window': 3.295.0 '@aws-sdk/util-utf8-browser': 3.188.0 tslib: 1.14.1 - dev: false - /@aws-crypto/sha256-browser@3.0.0: - resolution: {integrity: sha512-8VLmW2B+gjFbU5uMeqtQM6Nj0/F1bro80xQXCW6CQBWgosFWXTx77aeOF5CAIAmbOK64SdMBJdNr6J41yP5mvQ==} + '@aws-crypto/sha256-browser@3.0.0': dependencies: '@aws-crypto/ie11-detection': 3.0.0 '@aws-crypto/sha256-js': 3.0.0 @@ -4220,33 +13003,24 @@ packages: '@aws-sdk/util-locate-window': 3.295.0 '@aws-sdk/util-utf8-browser': 3.188.0 tslib: 1.14.1 - dev: false - /@aws-crypto/sha256-js@3.0.0: - resolution: {integrity: sha512-PnNN7os0+yd1XvXAy23CFOmTbMaDxgxXtTKHybrJ39Y8kGzBATgBFibWJKH6BhytLI/Zyszs87xCOBNyBig6vQ==} + '@aws-crypto/sha256-js@3.0.0': dependencies: '@aws-crypto/util': 3.0.0 '@aws-sdk/types': 3.535.0 tslib: 1.14.1 - dev: false - /@aws-crypto/supports-web-crypto@3.0.0: - resolution: {integrity: sha512-06hBdMwUAb2WFTuGG73LSC0wfPu93xWwo5vL2et9eymgmu3Id5vFAHBbajVWiGhPO37qcsdCap/FqXvJGJWPIg==} + '@aws-crypto/supports-web-crypto@3.0.0': dependencies: tslib: 1.14.1 - dev: false - /@aws-crypto/util@3.0.0: - resolution: {integrity: sha512-2OJlpeJpCR48CC8r+uKVChzs9Iungj9wkZrl8Z041DWEWvyIHILYKCPNzJghKsivj+S3mLo6BVc7mBNzdxA46w==} + '@aws-crypto/util@3.0.0': dependencies: '@aws-sdk/types': 3.535.0 '@aws-sdk/util-utf8-browser': 3.188.0 tslib: 1.14.1 - dev: false - /@aws-sdk/client-s3@3.556.0: - resolution: {integrity: sha512-6WF9Kuzz1/8zqX8hKBpqj9+FYwQ5uTsVcOKpTW94AMX2qtIeVRlwlnNnYyywWo61yqD3g59CMNHcqSsaqAwglg==} - engines: {node: '>=14.0.0'} + '@aws-sdk/client-s3@3.556.0': dependencies: '@aws-crypto/sha1-browser': 3.0.0 '@aws-crypto/sha256-browser': 3.0.0 @@ -4307,11 +13081,8 @@ packages: tslib: 2.6.2 transitivePeerDependencies: - aws-crt - dev: false - /@aws-sdk/client-sesv2@3.556.0: - resolution: {integrity: sha512-CYbCVlMlXJ72r+DrBRjgqw+Dm2yVUA9d1rxZWjfBhMulaypbV0EIZK2xLwgcQ5LvdfKdrrFEsFcViDA6q0w3Zg==} - engines: {node: '>=14.0.0'} + '@aws-sdk/client-sesv2@3.556.0': dependencies: '@aws-crypto/sha256-browser': 3.0.0 '@aws-crypto/sha256-js': 3.0.0 @@ -4355,13 +13126,8 @@ packages: tslib: 2.6.2 transitivePeerDependencies: - aws-crt - dev: false - /@aws-sdk/client-sso-oidc@3.556.0(@aws-sdk/credential-provider-node@3.556.0): - resolution: {integrity: sha512-AXKd2TB6nNrksu+OfmHl8uI07PdgzOo4o8AxoRO8SHlwoMAGvcT9optDGVSYoVfgOKTymCoE7h8/UoUfPc11wQ==} - engines: {node: '>=14.0.0'} - peerDependencies: - '@aws-sdk/credential-provider-node': ^3.556.0 + '@aws-sdk/client-sso-oidc@3.556.0(@aws-sdk/credential-provider-node@3.556.0)': dependencies: '@aws-crypto/sha256-browser': 3.0.0 '@aws-crypto/sha256-js': 3.0.0 @@ -4405,11 +13171,8 @@ packages: tslib: 2.6.2 transitivePeerDependencies: - aws-crt - dev: false - /@aws-sdk/client-sso@3.556.0: - resolution: {integrity: sha512-unXdWS7uvHqCcOyC1de+Fr8m3F2vMg2m24GPea0bg7rVGTYmiyn9mhUX11VCt+ozydrw+F50FQwL6OqoqPocmw==} - engines: {node: '>=14.0.0'} + '@aws-sdk/client-sso@3.556.0': dependencies: '@aws-crypto/sha256-browser': 3.0.0 '@aws-crypto/sha256-js': 3.0.0 @@ -4451,13 +13214,8 @@ packages: tslib: 2.6.2 transitivePeerDependencies: - aws-crt - dev: false - /@aws-sdk/client-sts@3.556.0(@aws-sdk/credential-provider-node@3.556.0): - resolution: {integrity: sha512-TsK3js7Suh9xEmC886aY+bv0KdLLYtzrcmVt6sJ/W6EnDXYQhBuKYFhp03NrN2+vSvMGpqJwR62DyfKe1G0QzQ==} - engines: {node: '>=14.0.0'} - peerDependencies: - '@aws-sdk/credential-provider-node': ^3.556.0 + '@aws-sdk/client-sts@3.556.0(@aws-sdk/credential-provider-node@3.556.0)': dependencies: '@aws-crypto/sha256-browser': 3.0.0 '@aws-crypto/sha256-js': 3.0.0 @@ -4500,11 +13258,8 @@ packages: tslib: 2.6.2 transitivePeerDependencies: - aws-crt - dev: false - /@aws-sdk/core@3.556.0: - resolution: {integrity: sha512-vJaSaHw2kPQlo11j/Rzuz0gk1tEaKdz+2ser0f0qZ5vwFlANjt08m/frU17ctnVKC1s58bxpctO/1P894fHLrA==} - engines: {node: '>=14.0.0'} + '@aws-sdk/core@3.556.0': dependencies: '@smithy/core': 1.4.2 '@smithy/protocol-http': 3.3.0 @@ -4513,21 +13268,15 @@ packages: '@smithy/types': 2.12.0 fast-xml-parser: 4.2.5 tslib: 2.6.2 - dev: false - /@aws-sdk/credential-provider-env@3.535.0: - resolution: {integrity: sha512-XppwO8c0GCGSAvdzyJOhbtktSEaShg14VJKg8mpMa1XcgqzmcqqHQjtDWbx5rZheY1VdpXZhpEzJkB6LpQejpA==} - engines: {node: '>=14.0.0'} + '@aws-sdk/credential-provider-env@3.535.0': dependencies: '@aws-sdk/types': 3.535.0 '@smithy/property-provider': 2.2.0 '@smithy/types': 2.12.0 tslib: 2.6.2 - dev: false - /@aws-sdk/credential-provider-http@3.552.0: - resolution: {integrity: sha512-vsmu7Cz1i45pFEqzVb4JcFmAmVnWFNLsGheZc8SCptlqCO5voETrZZILHYIl4cjKkSDk3pblBOf0PhyjqWW6WQ==} - engines: {node: '>=14.0.0'} + '@aws-sdk/credential-provider-http@3.552.0': dependencies: '@aws-sdk/types': 3.535.0 '@smithy/fetch-http-handler': 2.5.0 @@ -4538,11 +13287,8 @@ packages: '@smithy/types': 2.12.0 '@smithy/util-stream': 2.2.0 tslib: 2.6.2 - dev: false - /@aws-sdk/credential-provider-ini@3.556.0(@aws-sdk/credential-provider-node@3.556.0): - resolution: {integrity: sha512-0Nz4ErOlXhe3muxWYMbPwRMgfKmVbBp36BAE2uv/z5wTbfdBkcgUwaflEvlKCLUTdHzuZsQk+BFS/gVyaUeOuA==} - engines: {node: '>=14.0.0'} + '@aws-sdk/credential-provider-ini@3.556.0(@aws-sdk/credential-provider-node@3.556.0)': dependencies: '@aws-sdk/client-sts': 3.556.0(@aws-sdk/credential-provider-node@3.556.0) '@aws-sdk/credential-provider-env': 3.535.0 @@ -4558,11 +13304,8 @@ packages: transitivePeerDependencies: - '@aws-sdk/credential-provider-node' - aws-crt - dev: false - /@aws-sdk/credential-provider-node@3.556.0: - resolution: {integrity: sha512-s1xVtKjyGc60O8qcNIzS1X3H+pWEwEfZ7TgNznVDNyuXvLrlNWiAcigPWGl2aAkc8tGcsSG0Qpyw2KYC939LFg==} - engines: {node: '>=14.0.0'} + '@aws-sdk/credential-provider-node@3.556.0': dependencies: '@aws-sdk/credential-provider-env': 3.535.0 '@aws-sdk/credential-provider-http': 3.552.0 @@ -4578,22 +13321,16 @@ packages: tslib: 2.6.2 transitivePeerDependencies: - aws-crt - dev: false - /@aws-sdk/credential-provider-process@3.535.0: - resolution: {integrity: sha512-9O1OaprGCnlb/kYl8RwmH7Mlg8JREZctB8r9sa1KhSsWFq/SWO0AuJTyowxD7zL5PkeS4eTvzFFHWCa3OO5epA==} - engines: {node: '>=14.0.0'} + '@aws-sdk/credential-provider-process@3.535.0': dependencies: '@aws-sdk/types': 3.535.0 '@smithy/property-provider': 2.2.0 '@smithy/shared-ini-file-loader': 2.4.0 '@smithy/types': 2.12.0 tslib: 2.6.2 - dev: false - /@aws-sdk/credential-provider-sso@3.556.0(@aws-sdk/credential-provider-node@3.556.0): - resolution: {integrity: sha512-ETuBgcnpfxqadEAqhQFWpKoV1C/NAgvs5CbBc5EJbelJ8f4prTdErIHjrRtVT8c02MXj92QwczsiNYd5IoOqyw==} - engines: {node: '>=14.0.0'} + '@aws-sdk/credential-provider-sso@3.556.0(@aws-sdk/credential-provider-node@3.556.0)': dependencies: '@aws-sdk/client-sso': 3.556.0 '@aws-sdk/token-providers': 3.556.0(@aws-sdk/credential-provider-node@3.556.0) @@ -4605,11 +13342,8 @@ packages: transitivePeerDependencies: - '@aws-sdk/credential-provider-node' - aws-crt - dev: false - /@aws-sdk/credential-provider-web-identity@3.556.0(@aws-sdk/credential-provider-node@3.556.0): - resolution: {integrity: sha512-R/YAL8Uh8i+dzVjzMnbcWLIGeeRi2mioHVGnVF+minmaIkCiQMZg2HPrdlKm49El+RljT28Nl5YHRuiqzEIwMA==} - engines: {node: '>=14.0.0'} + '@aws-sdk/credential-provider-web-identity@3.556.0(@aws-sdk/credential-provider-node@3.556.0)': dependencies: '@aws-sdk/client-sts': 3.556.0(@aws-sdk/credential-provider-node@3.556.0) '@aws-sdk/types': 3.535.0 @@ -4619,11 +13353,8 @@ packages: transitivePeerDependencies: - '@aws-sdk/credential-provider-node' - aws-crt - dev: false - /@aws-sdk/middleware-bucket-endpoint@3.535.0: - resolution: {integrity: sha512-7sijlfQsc4UO9Fsl11mU26Y5f9E7g6UoNg/iJUBpC5pgvvmdBRO5UEhbB/gnqvOEPsBXyhmfzbstebq23Qdz7A==} - engines: {node: '>=14.0.0'} + '@aws-sdk/middleware-bucket-endpoint@3.535.0': dependencies: '@aws-sdk/types': 3.535.0 '@aws-sdk/util-arn-parser': 3.535.0 @@ -4632,21 +13363,15 @@ packages: '@smithy/types': 2.12.0 '@smithy/util-config-provider': 2.3.0 tslib: 2.6.2 - dev: false - /@aws-sdk/middleware-expect-continue@3.535.0: - resolution: {integrity: sha512-hFKyqUBky0NWCVku8iZ9+PACehx0p6vuMw5YnZf8FVgHP0fode0b/NwQY6UY7oor/GftvRsAlRUAWGNFEGUpwA==} - engines: {node: '>=14.0.0'} + '@aws-sdk/middleware-expect-continue@3.535.0': dependencies: '@aws-sdk/types': 3.535.0 '@smithy/protocol-http': 3.3.0 '@smithy/types': 2.12.0 tslib: 2.6.2 - dev: false - /@aws-sdk/middleware-flexible-checksums@3.535.0: - resolution: {integrity: sha512-rBIzldY9jjRATxICDX7t77aW6ctqmVDgnuAOgbVT5xgHftt4o7PGWKoMvl/45hYqoQgxVFnCBof9bxkqSBebVA==} - engines: {node: '>=14.0.0'} + '@aws-sdk/middleware-flexible-checksums@3.535.0': dependencies: '@aws-crypto/crc32': 3.0.0 '@aws-crypto/crc32c': 3.0.0 @@ -4656,49 +13381,34 @@ packages: '@smithy/types': 2.12.0 '@smithy/util-utf8': 2.3.0 tslib: 2.6.2 - dev: false - /@aws-sdk/middleware-host-header@3.535.0: - resolution: {integrity: sha512-0h6TWjBWtDaYwHMQJI9ulafeS4lLaw1vIxRjbpH0svFRt6Eve+Sy8NlVhECfTU2hNz/fLubvrUxsXoThaLBIew==} - engines: {node: '>=14.0.0'} + '@aws-sdk/middleware-host-header@3.535.0': dependencies: '@aws-sdk/types': 3.535.0 '@smithy/protocol-http': 3.3.0 '@smithy/types': 2.12.0 tslib: 2.6.2 - dev: false - /@aws-sdk/middleware-location-constraint@3.535.0: - resolution: {integrity: sha512-SxfS9wfidUZZ+WnlKRTCRn3h+XTsymXRXPJj8VV6hNRNeOwzNweoG3YhQbTowuuNfXf89m9v6meYkBBtkdacKw==} - engines: {node: '>=14.0.0'} + '@aws-sdk/middleware-location-constraint@3.535.0': dependencies: '@aws-sdk/types': 3.535.0 '@smithy/types': 2.12.0 tslib: 2.6.2 - dev: false - /@aws-sdk/middleware-logger@3.535.0: - resolution: {integrity: sha512-huNHpONOrEDrdRTvSQr1cJiRMNf0S52NDXtaPzdxiubTkP+vni2MohmZANMOai/qT0olmEVX01LhZ0ZAOgmg6A==} - engines: {node: '>=14.0.0'} + '@aws-sdk/middleware-logger@3.535.0': dependencies: '@aws-sdk/types': 3.535.0 '@smithy/types': 2.12.0 tslib: 2.6.2 - dev: false - /@aws-sdk/middleware-recursion-detection@3.535.0: - resolution: {integrity: sha512-am2qgGs+gwqmR4wHLWpzlZ8PWhm4ktj5bYSgDrsOfjhdBlWNxvPoID9/pDAz5RWL48+oH7I6SQzMqxXsFDikrw==} - engines: {node: '>=14.0.0'} + '@aws-sdk/middleware-recursion-detection@3.535.0': dependencies: '@aws-sdk/types': 3.535.0 '@smithy/protocol-http': 3.3.0 '@smithy/types': 2.12.0 tslib: 2.6.2 - dev: false - /@aws-sdk/middleware-sdk-s3@3.556.0: - resolution: {integrity: sha512-4W/dnxqj1B6/uS/5Z+3UHaqDDGjNPgEVlqf5d3ToOFZ31ZfpANwhcCmyX39JklC4aolCEi9renQ5wHnTCC8K8g==} - engines: {node: '>=14.0.0'} + '@aws-sdk/middleware-sdk-s3@3.556.0': dependencies: '@aws-sdk/types': 3.535.0 '@aws-sdk/util-arn-parser': 3.535.0 @@ -4709,11 +13419,8 @@ packages: '@smithy/types': 2.12.0 '@smithy/util-config-provider': 2.3.0 tslib: 2.6.2 - dev: false - /@aws-sdk/middleware-signing@3.556.0: - resolution: {integrity: sha512-kWrPmU8qd3gI5qzpuW9LtWFaH80cOz1ZJDavXx6PRpYZJ5JaKdUHghwfDlVTzzFYAeJmVsWIkPcLT5d5mY5ZTQ==} - engines: {node: '>=14.0.0'} + '@aws-sdk/middleware-signing@3.556.0': dependencies: '@aws-sdk/types': 3.535.0 '@smithy/property-provider': 2.2.0 @@ -4722,31 +13429,22 @@ packages: '@smithy/types': 2.12.0 '@smithy/util-middleware': 2.2.0 tslib: 2.6.2 - dev: false - /@aws-sdk/middleware-ssec@3.537.0: - resolution: {integrity: sha512-2QWMrbwd5eBy5KCYn9a15JEWBgrK2qFEKQN2lqb/6z0bhtevIOxIRfC99tzvRuPt6nixFQ+ynKuBjcfT4ZFrdQ==} - engines: {node: '>=14.0.0'} + '@aws-sdk/middleware-ssec@3.537.0': dependencies: '@aws-sdk/types': 3.535.0 '@smithy/types': 2.12.0 tslib: 2.6.2 - dev: false - /@aws-sdk/middleware-user-agent@3.540.0: - resolution: {integrity: sha512-8Rd6wPeXDnOYzWj1XCmOKcx/Q87L0K1/EHqOBocGjLVbN3gmRxBvpmR1pRTjf7IsWfnnzN5btqtcAkfDPYQUMQ==} - engines: {node: '>=14.0.0'} + '@aws-sdk/middleware-user-agent@3.540.0': dependencies: '@aws-sdk/types': 3.535.0 '@aws-sdk/util-endpoints': 3.540.0 '@smithy/protocol-http': 3.3.0 '@smithy/types': 2.12.0 tslib: 2.6.2 - dev: false - /@aws-sdk/region-config-resolver@3.535.0: - resolution: {integrity: sha512-IXOznDiaItBjsQy4Fil0kzX/J3HxIOknEphqHbOfUf+LpA5ugcsxuQQONrbEQusCBnfJyymrldBvBhFmtlU9Wg==} - engines: {node: '>=14.0.0'} + '@aws-sdk/region-config-resolver@3.535.0': dependencies: '@aws-sdk/types': 3.535.0 '@smithy/node-config-provider': 2.3.0 @@ -4754,11 +13452,8 @@ packages: '@smithy/util-config-provider': 2.3.0 '@smithy/util-middleware': 2.2.0 tslib: 2.6.2 - dev: false - /@aws-sdk/signature-v4-multi-region@3.556.0: - resolution: {integrity: sha512-bWDSK0ggK7QzAOmPZGv29UAIZocL1MNY7XyOvm3P3P1U3tFMoIBilQQBLabXyHoZ9J3Ik0Vv4n95htUhRQ35ow==} - engines: {node: '>=14.0.0'} + '@aws-sdk/signature-v4-multi-region@3.556.0': dependencies: '@aws-sdk/middleware-sdk-s3': 3.556.0 '@aws-sdk/types': 3.535.0 @@ -4766,11 +13461,8 @@ packages: '@smithy/signature-v4': 2.3.0 '@smithy/types': 2.12.0 tslib: 2.6.2 - dev: false - /@aws-sdk/token-providers@3.556.0(@aws-sdk/credential-provider-node@3.556.0): - resolution: {integrity: sha512-tvIiugNF0/+2wfuImMrpKjXMx4nCnFWQjQvouObny+wrif/PGqqQYrybwxPJDvzbd965bu1I+QuSv85/ug7xsg==} - engines: {node: '>=14.0.0'} + '@aws-sdk/token-providers@3.556.0(@aws-sdk/credential-provider-node@3.556.0)': dependencies: '@aws-sdk/client-sso-oidc': 3.556.0(@aws-sdk/credential-provider-node@3.556.0) '@aws-sdk/types': 3.535.0 @@ -4781,104 +13473,65 @@ packages: transitivePeerDependencies: - '@aws-sdk/credential-provider-node' - aws-crt - dev: false - /@aws-sdk/types@3.535.0: - resolution: {integrity: sha512-aY4MYfduNj+sRR37U7XxYR8wemfbKP6lx00ze2M2uubn7mZotuVrWYAafbMSXrdEMSToE5JDhr28vArSOoLcSg==} - engines: {node: '>=14.0.0'} + '@aws-sdk/types@3.535.0': dependencies: '@smithy/types': 2.12.0 tslib: 2.6.2 - dev: false - /@aws-sdk/util-arn-parser@3.535.0: - resolution: {integrity: sha512-smVo29nUPAOprp8Z5Y3GHuhiOtw6c8/EtLCm5AVMtRsTPw4V414ZXL2H66tzmb5kEeSzQlbfBSBEdIFZoxO9kg==} - engines: {node: '>=14.0.0'} + '@aws-sdk/util-arn-parser@3.535.0': dependencies: tslib: 2.6.2 - dev: false - /@aws-sdk/util-endpoints@3.540.0: - resolution: {integrity: sha512-1kMyQFAWx6f8alaI6UT65/5YW/7pDWAKAdNwL6vuJLea03KrZRX3PMoONOSJpAS5m3Ot7HlWZvf3wZDNTLELZw==} - engines: {node: '>=14.0.0'} + '@aws-sdk/util-endpoints@3.540.0': dependencies: '@aws-sdk/types': 3.535.0 '@smithy/types': 2.12.0 '@smithy/util-endpoints': 1.2.0 tslib: 2.6.2 - dev: false - /@aws-sdk/util-locate-window@3.295.0: - resolution: {integrity: sha512-d/s+zhUx5Kh4l/ecMP/TBjzp1GR/g89Q4nWH6+wH5WgdHsK+LG+vmsk6mVNuP/8wsCofYG4NBqp5Ulbztbm9QA==} - engines: {node: '>=14.0.0'} + '@aws-sdk/util-locate-window@3.295.0': dependencies: tslib: 2.6.2 - dev: false - /@aws-sdk/util-user-agent-browser@3.535.0: - resolution: {integrity: sha512-RWMcF/xV5n+nhaA/Ff5P3yNP3Kur/I+VNZngog4TEs92oB/nwOdAg/2JL8bVAhUbMrjTjpwm7PItziYFQoqyig==} + '@aws-sdk/util-user-agent-browser@3.535.0': dependencies: '@aws-sdk/types': 3.535.0 '@smithy/types': 2.12.0 bowser: 2.11.0 tslib: 2.6.2 - dev: false - /@aws-sdk/util-user-agent-node@3.535.0: - resolution: {integrity: sha512-dRek0zUuIT25wOWJlsRm97nTkUlh1NDcLsQZIN2Y8KxhwoXXWtJs5vaDPT+qAg+OpcNj80i1zLR/CirqlFg/TQ==} - engines: {node: '>=14.0.0'} - peerDependencies: - aws-crt: '>=1.0.0' - peerDependenciesMeta: - aws-crt: - optional: true + '@aws-sdk/util-user-agent-node@3.535.0': dependencies: '@aws-sdk/types': 3.535.0 '@smithy/node-config-provider': 2.3.0 '@smithy/types': 2.12.0 tslib: 2.6.2 - dev: false - /@aws-sdk/util-utf8-browser@3.188.0: - resolution: {integrity: sha512-jt627x0+jE+Ydr9NwkFstg3cUvgWh56qdaqAMDsqgRlKD21md/6G226z/Qxl7lb1VEW2LlmCx43ai/37Qwcj2Q==} + '@aws-sdk/util-utf8-browser@3.188.0': dependencies: tslib: 2.6.2 - dev: false - /@aws-sdk/xml-builder@3.535.0: - resolution: {integrity: sha512-VXAq/Jz8KIrU84+HqsOJhIKZqG0PNTdi6n6PFQ4xJf44ZQHD/5C7ouH4qCFX5XgZXcgbRIcMVVYGC6Jye0dRng==} - engines: {node: '>=14.0.0'} + '@aws-sdk/xml-builder@3.535.0': dependencies: '@smithy/types': 2.12.0 tslib: 2.6.2 - dev: false - /@azure/abort-controller@1.1.0: - resolution: {integrity: sha512-TrRLIoSQVzfAJX9H1JeFjzAoDGcoK1IYX1UImfceTZpsyYfWr09Ss1aHW1y5TrrR3iq6RZLBwJ3E24uwPhwahw==} - engines: {node: '>=12.0.0'} + '@azure/abort-controller@1.1.0': dependencies: tslib: 2.5.0 - dev: false - /@azure/abort-controller@2.1.2: - resolution: {integrity: sha512-nBrLsEWm4J2u5LpAPjxADTlq3trDgVZZXHNKabeXZtpq3d3AbN/KGO82R87rdDz5/lYB024rtEf10/q0urNgsA==} - engines: {node: '>=18.0.0'} + '@azure/abort-controller@2.1.2': dependencies: tslib: 2.6.2 - dev: false - /@azure/core-auth@1.7.2: - resolution: {integrity: sha512-Igm/S3fDYmnMq1uKS38Ae1/m37B3zigdlZw+kocwEhh5GjyKjPrXKO2J6rzpC1wAxrNil/jX9BJRqBshyjnF3g==} - engines: {node: '>=18.0.0'} + '@azure/core-auth@1.7.2': dependencies: '@azure/abort-controller': 2.1.2 '@azure/core-util': 1.2.0 tslib: 2.6.2 - dev: false - /@azure/core-http@3.0.4: - resolution: {integrity: sha512-Fok9VVhMdxAFOtqiiAtg74fL0UJkt0z3D+ouUUxcRLzZNBioPRAMJFVxiWoJljYpXsRi4GDQHzQHDc9AiYaIUQ==} - engines: {node: '>=14.0.0'} + '@azure/core-http@3.0.4': dependencies: '@azure/abort-controller': 1.1.0 '@azure/core-auth': 1.7.2 @@ -4896,27 +13549,18 @@ packages: xml2js: 0.5.0 transitivePeerDependencies: - encoding - dev: false - /@azure/core-lro@2.5.1: - resolution: {integrity: sha512-JHQy/bA3NOz2WuzOi5zEk6n/TJdAropupxUT521JIJvW7EXV2YN2SFYZrf/2RHeD28QAClGdynYadZsbmP+nyQ==} - engines: {node: '>=14.0.0'} + '@azure/core-lro@2.5.1': dependencies: '@azure/abort-controller': 1.1.0 '@azure/logger': 1.0.4 tslib: 2.6.2 - dev: false - /@azure/core-paging@1.5.0: - resolution: {integrity: sha512-zqWdVIt+2Z+3wqxEOGzR5hXFZ8MGKK52x4vFLw8n58pR6ZfKRx3EXYTxTaYxYHc/PexPUTyimcTWFJbji9Z6Iw==} - engines: {node: '>=14.0.0'} + '@azure/core-paging@1.5.0': dependencies: tslib: 2.6.2 - dev: false - /@azure/core-rest-pipeline@1.10.1: - resolution: {integrity: sha512-Kji9k6TOFRDB5ZMTw8qUf2IJ+CeJtsuMdAHox9eqpTf1cefiNMpzrfnF6sINEBZJsaVaWgQ0o48B6kcUH68niA==} - engines: {node: '>=14.0.0'} + '@azure/core-rest-pipeline@1.10.1': dependencies: '@azure/abort-controller': 1.1.0 '@azure/core-auth': 1.7.2 @@ -4930,55 +13574,34 @@ packages: uuid: 8.3.2 transitivePeerDependencies: - supports-color - dev: false - /@azure/core-tracing@1.0.0-preview.13: - resolution: {integrity: sha512-KxDlhXyMlh2Jhj2ykX6vNEU0Vou4nHr025KoSEiz7cS3BNiHNaZcdECk/DmLkEB0as5T7b/TpRcehJ5yV6NeXQ==} - engines: {node: '>=12.0.0'} + '@azure/core-tracing@1.0.0-preview.13': dependencies: '@opentelemetry/api': 1.8.0 tslib: 2.6.2 - dev: false - /@azure/core-tracing@1.0.1: - resolution: {integrity: sha512-I5CGMoLtX+pI17ZdiFJZgxMJApsK6jjfm85hpgp3oazCdq5Wxgh4wMr7ge/TTWW1B5WBuvIOI1fMU/FrOAMKrw==} - engines: {node: '>=12.0.0'} + '@azure/core-tracing@1.0.1': dependencies: tslib: 2.6.2 - dev: false - /@azure/core-util@1.2.0: - resolution: {integrity: sha512-ffGIw+Qs8bNKNLxz5UPkz4/VBM/EZY07mPve1ZYFqYUdPwFqRj0RPk0U7LZMOfT7GCck9YjuT1Rfp1PApNl1ng==} - engines: {node: '>=14.0.0'} + '@azure/core-util@1.2.0': dependencies: '@azure/abort-controller': 1.1.0 tslib: 2.6.2 - dev: false - /@azure/logger@1.0.4: - resolution: {integrity: sha512-ustrPY8MryhloQj7OWGe+HrYx+aoiOxzbXTtgblbV3xwCqpzUK36phH3XNHQKj3EPonyFUuDTfR3qFhTEAuZEg==} - engines: {node: '>=14.0.0'} + '@azure/logger@1.0.4': dependencies: tslib: 2.5.0 - dev: false - /@azure/msal-common@14.7.1: - resolution: {integrity: sha512-v96btzjM7KrAu4NSEdOkhQSTGOuNUIIsUdB8wlyB9cdgl5KqEKnTonHUZ8+khvZ6Ap542FCErbnTyDWl8lZ2rA==} - engines: {node: '>=0.8.0'} - dev: false + '@azure/msal-common@14.7.1': {} - /@azure/msal-node@2.6.4: - resolution: {integrity: sha512-nNvEPx009/80UATCToF+29NZYocn01uKrB91xtFr7bSqkqO1PuQGXRyYwryWRztUrYZ1YsSbw9A+LmwOhpVvcg==} - engines: {node: '>=16'} + '@azure/msal-node@2.6.4': dependencies: '@azure/msal-common': 14.7.1 jsonwebtoken: 9.0.2 uuid: 8.3.2 - dev: false - /@azure/opentelemetry-instrumentation-azure-sdk@1.0.0-beta.5: - resolution: {integrity: sha512-fsUarKQDvjhmBO4nIfaZkfNSApm1hZBzcvpNbSrXdcUBxu7lRvKsV5DnwszX7cnhLyVOW9yl1uigtRQ1yDANjA==} - engines: {node: '>=14.0.0'} + '@azure/opentelemetry-instrumentation-azure-sdk@1.0.0-beta.5': dependencies: '@azure/core-tracing': 1.0.1 '@azure/logger': 1.0.4 @@ -4988,11 +13611,8 @@ packages: tslib: 2.6.2 transitivePeerDependencies: - supports-color - dev: false - /@azure/storage-blob@12.17.0: - resolution: {integrity: sha512-sM4vpsCpcCApagRW5UIjQNlNylo02my2opgp0Emi8x888hZUvJ3dN69Oq20cEGXkMUWnoCrBaB0zyS3yeB87sQ==} - engines: {node: '>=14.0.0'} + '@azure/storage-blob@12.17.0': dependencies: '@azure/abort-controller': 1.1.0 '@azure/core-http': 3.0.4 @@ -5004,31 +13624,19 @@ packages: tslib: 2.6.2 transitivePeerDependencies: - encoding - dev: false - /@babel/code-frame@7.22.5: - resolution: {integrity: sha512-Xmwn266vad+6DAqEB2A6V/CcZVp62BbwVmcOJc2RPuwih1kw02TjQvWVWlcKGbBPd+8/0V5DEkOcizRGYsspYQ==} - engines: {node: '>=6.9.0'} + '@babel/code-frame@7.22.5': dependencies: '@babel/highlight': 7.22.5 - dev: true - /@babel/code-frame@7.24.2: - resolution: {integrity: sha512-y5+tLQyV8pg3fsiln67BVLD1P13Eg4lh5RW9mF0zUuvLrv9uIQ4MCL+CRT+FTsBlBjcIan6PGsLcBN0m3ClUyQ==} - engines: {node: '>=6.9.0'} + '@babel/code-frame@7.24.2': dependencies: '@babel/highlight': 7.24.2 picocolors: 1.0.0 - dev: true - /@babel/compat-data@7.24.4: - resolution: {integrity: sha512-vg8Gih2MLK+kOkHJp4gBEIkyaIi00jgWot2D9QOmmfLC8jINSOzmCLta6Bvz/JSBCqnegV0L80jhxkol5GWNfQ==} - engines: {node: '>=6.9.0'} - dev: true + '@babel/compat-data@7.24.4': {} - /@babel/core@7.12.9: - resolution: {integrity: sha512-gTXYh3M5wb7FRXQy+FErKFAv90BnlOuNn1QkCK2lREoPAjrQCO49+HVSrFoe5uakFAF5eenS75KbO2vQiLrTMQ==} - engines: {node: '>=6.9.0'} + '@babel/core@7.12.9': dependencies: '@babel/code-frame': 7.24.2 '@babel/generator': 7.24.4 @@ -5048,11 +13656,8 @@ packages: source-map: 0.5.7 transitivePeerDependencies: - supports-color - dev: true - /@babel/core@7.24.4: - resolution: {integrity: sha512-MBVlMXP+kkl5394RBLSxxk/iLTeVGuXTV3cIDXavPpMMqnSnt6apKgan/U8O3USWZCWZT/TbgfEpKa4uMgN4Dg==} - engines: {node: '>=6.9.0'} + '@babel/core@7.24.4': dependencies: '@ampproject/remapping': 2.3.0 '@babel/code-frame': 7.24.2 @@ -5071,70 +13676,44 @@ packages: semver: 6.3.1 transitivePeerDependencies: - supports-color - dev: true - /@babel/generator@7.20.4: - resolution: {integrity: sha512-luCf7yk/cm7yab6CAW1aiFnmEfBJplb/JojV56MYEK7ziWfGmFlTfmL9Ehwfy4gFhbjBfWO1wj7/TuSbVNEEtA==} - engines: {node: '>=6.9.0'} + '@babel/generator@7.20.4': dependencies: '@babel/types': 7.24.0 '@jridgewell/gen-mapping': 0.3.5 jsesc: 2.5.2 - dev: true - /@babel/generator@7.24.4: - resolution: {integrity: sha512-Xd6+v6SnjWVx/nus+y0l1sxMOTOMBkyL4+BIdbALyatQnAe/SRVjANeDPSCYaX+i1iJmuGSKf3Z+E+V/va1Hvw==} - engines: {node: '>=6.9.0'} + '@babel/generator@7.24.4': dependencies: '@babel/types': 7.24.0 '@jridgewell/gen-mapping': 0.3.5 '@jridgewell/trace-mapping': 0.3.25 jsesc: 2.5.2 - dev: true - /@babel/helper-compilation-targets@7.23.6: - resolution: {integrity: sha512-9JB548GZoQVmzrFgp8o7KxdgkTGm6xs9DW0o/Pim72UDjzr5ObUQ6ZzYPqA+g9OTS2bBQoctLJrky0RDCAWRgQ==} - engines: {node: '>=6.9.0'} + '@babel/helper-compilation-targets@7.23.6': dependencies: '@babel/compat-data': 7.24.4 '@babel/helper-validator-option': 7.23.5 browserslist: 4.23.0 lru-cache: 5.1.1 semver: 6.3.1 - dev: true - /@babel/helper-environment-visitor@7.22.20: - resolution: {integrity: sha512-zfedSIzFhat/gFhWfHtgWvlec0nqB9YEIVrpuwjruLlXfUSnA8cJB0miHKwqDnQ7d32aKo2xt88/xZptwxbfhA==} - engines: {node: '>=6.9.0'} - dev: true + '@babel/helper-environment-visitor@7.22.20': {} - /@babel/helper-function-name@7.23.0: - resolution: {integrity: sha512-OErEqsrxjZTJciZ4Oo+eoZqeW9UIiOcuYKRJA4ZAgV9myA+pOXhhmpfNCKjEH/auVfEYVFJ6y1Tc4r0eIApqiw==} - engines: {node: '>=6.9.0'} + '@babel/helper-function-name@7.23.0': dependencies: '@babel/template': 7.24.0 '@babel/types': 7.24.0 - dev: true - /@babel/helper-hoist-variables@7.22.5: - resolution: {integrity: sha512-wGjk9QZVzvknA6yKIUURb8zY3grXCcOZt+/7Wcy8O2uctxhplmUPkOdlgoNhmdVee2c92JXbf1xpMtVNbfoxRw==} - engines: {node: '>=6.9.0'} + '@babel/helper-hoist-variables@7.22.5': dependencies: '@babel/types': 7.24.0 - dev: true - /@babel/helper-module-imports@7.24.3: - resolution: {integrity: sha512-viKb0F9f2s0BCS22QSF308z/+1YWKV/76mwt61NBzS5izMzDPwdq1pTrzf+Li3npBWX9KdQbkeCt1jSAM7lZqg==} - engines: {node: '>=6.9.0'} + '@babel/helper-module-imports@7.24.3': dependencies: '@babel/types': 7.24.0 - dev: true - /@babel/helper-module-transforms@7.23.3(@babel/core@7.12.9): - resolution: {integrity: sha512-7bBs4ED9OmswdfDzpz4MpWgSrV7FXlc3zIagvLFjS5H+Mk7Snr21vQ6QwrsoCGMfNC4e4LQPdoULEt4ykz0SRQ==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0 + '@babel/helper-module-transforms@7.23.3(@babel/core@7.12.9)': dependencies: '@babel/core': 7.12.9 '@babel/helper-environment-visitor': 7.22.20 @@ -5142,13 +13721,8 @@ packages: '@babel/helper-simple-access': 7.22.5 '@babel/helper-split-export-declaration': 7.22.6 '@babel/helper-validator-identifier': 7.22.20 - dev: true - /@babel/helper-module-transforms@7.23.3(@babel/core@7.24.4): - resolution: {integrity: sha512-7bBs4ED9OmswdfDzpz4MpWgSrV7FXlc3zIagvLFjS5H+Mk7Snr21vQ6QwrsoCGMfNC4e4LQPdoULEt4ykz0SRQ==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0 + '@babel/helper-module-transforms@7.23.3(@babel/core@7.24.4)': dependencies: '@babel/core': 7.24.4 '@babel/helper-environment-visitor': 7.22.20 @@ -5156,318 +13730,179 @@ packages: '@babel/helper-simple-access': 7.22.5 '@babel/helper-split-export-declaration': 7.22.6 '@babel/helper-validator-identifier': 7.22.20 - dev: true - /@babel/helper-plugin-utils@7.10.4: - resolution: {integrity: sha512-O4KCvQA6lLiMU9l2eawBPMf1xPP8xPfB3iEQw150hOVTqj/rfXz0ThTb4HEzqQfs2Bmo5Ay8BzxfzVtBrr9dVg==} - dev: true + '@babel/helper-plugin-utils@7.10.4': {} - /@babel/helper-plugin-utils@7.20.2: - resolution: {integrity: sha512-8RvlJG2mj4huQ4pZ+rU9lqKi9ZKiRmuvGuM2HlWmkmgOhbs6zEAw6IEiJ5cQqGbDzGZOhwuOQNtZMi/ENLjZoQ==} - engines: {node: '>=6.9.0'} - dev: true + '@babel/helper-plugin-utils@7.20.2': {} - /@babel/helper-simple-access@7.22.5: - resolution: {integrity: sha512-n0H99E/K+Bika3++WNL17POvo4rKWZ7lZEp1Q+fStVbUi8nxPQEBOlTmCOxW/0JsS56SKKQ+ojAe2pHKJHN35w==} - engines: {node: '>=6.9.0'} + '@babel/helper-simple-access@7.22.5': dependencies: '@babel/types': 7.24.0 - dev: true - /@babel/helper-split-export-declaration@7.22.6: - resolution: {integrity: sha512-AsUnxuLhRYsisFiaJwvp1QF+I3KjD5FOxut14q/GzovUe6orHLesW2C7d754kRm53h5gqrz6sFl6sxc4BVtE/g==} - engines: {node: '>=6.9.0'} + '@babel/helper-split-export-declaration@7.22.6': dependencies: '@babel/types': 7.24.0 - dev: true - /@babel/helper-string-parser@7.19.4: - resolution: {integrity: sha512-nHtDoQcuqFmwYNYPz3Rah5ph2p8PFeFCsZk9A/48dPc/rGocJ5J3hAAZ7pb76VWX3fZKu+uEr/FhH5jLx7umrw==} - engines: {node: '>=6.9.0'} - dev: true + '@babel/helper-string-parser@7.19.4': {} - /@babel/helper-string-parser@7.23.4: - resolution: {integrity: sha512-803gmbQdqwdf4olxrX4AJyFBV/RTr3rSmOj0rKwesmzlfhYNDEs+/iOcznzpNWlJlIlTJC2QfPFcHB6DlzdVLQ==} - engines: {node: '>=6.9.0'} - dev: true + '@babel/helper-string-parser@7.23.4': {} - /@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.20': {} - /@babel/helper-validator-identifier@7.22.5: - resolution: {integrity: sha512-aJXu+6lErq8ltp+JhkJUfk1MTGyuA4v7f3pA+BJ5HLfNC6nAQ0Cpi9uOquUj8Hehg0aUiHzWQbOVJGao6ztBAQ==} - engines: {node: '>=6.9.0'} - dev: true + '@babel/helper-validator-identifier@7.22.5': {} - /@babel/helper-validator-option@7.23.5: - resolution: {integrity: sha512-85ttAOMLsr53VgXkTbkx8oA6YTfT4q7/HzXSLEYmjcSTJPMPQtvq1BD79Byep5xMUYbGRzEpDsjUf3dyp54IKw==} - engines: {node: '>=6.9.0'} - dev: true + '@babel/helper-validator-option@7.23.5': {} - /@babel/helpers@7.24.4: - resolution: {integrity: sha512-FewdlZbSiwaVGlgT1DPANDuCHaDMiOo+D/IDYRFYjHOuv66xMSJ7fQwwODwRNAPkADIO/z1EoF/l2BCWlWABDw==} - engines: {node: '>=6.9.0'} + '@babel/helpers@7.24.4': dependencies: '@babel/template': 7.24.0 '@babel/traverse': 7.24.1 '@babel/types': 7.24.0 transitivePeerDependencies: - supports-color - dev: true - /@babel/highlight@7.22.5: - resolution: {integrity: sha512-BSKlD1hgnedS5XRnGOljZawtag7H1yPfQp0tdNJCHoH6AZ+Pcm9VvkrK59/Yy593Ypg0zMxH2BxD1VPYUQ7UIw==} - engines: {node: '>=6.9.0'} + '@babel/highlight@7.22.5': dependencies: '@babel/helper-validator-identifier': 7.22.5 chalk: 2.4.2 js-tokens: 4.0.0 - dev: true - /@babel/highlight@7.24.2: - resolution: {integrity: sha512-Yac1ao4flkTxTteCDZLEvdxg2fZfz1v8M4QpaGypq/WPDqg3ijHYbDfs+LG5hvzSoqaSZ9/Z9lKSP3CjZjv+pA==} - engines: {node: '>=6.9.0'} + '@babel/highlight@7.24.2': dependencies: '@babel/helper-validator-identifier': 7.22.20 chalk: 2.4.2 js-tokens: 4.0.0 picocolors: 1.0.0 - dev: true - /@babel/parser@7.24.0: - resolution: {integrity: sha512-QuP/FxEAzMSjXygs8v4N9dvdXzEHN4W1oF3PxuWAtPo08UdM17u89RDMgjLn/mlc56iM0HlLmVkO/wgR+rDgHg==} - engines: {node: '>=6.0.0'} - hasBin: true + '@babel/parser@7.24.0': dependencies: '@babel/types': 7.24.0 - dev: true - /@babel/parser@7.24.4: - resolution: {integrity: sha512-zTvEBcghmeBma9QIGunWevvBAp4/Qu9Bdq+2k0Ot4fVMD6v3dsC9WOcRSKk7tRRyBM/53yKMJko9xOatGQAwSg==} - engines: {node: '>=6.0.0'} - hasBin: true + '@babel/parser@7.24.4': dependencies: '@babel/types': 7.24.0 - dev: true - /@babel/plugin-proposal-object-rest-spread@7.12.1(@babel/core@7.12.9): - resolution: {integrity: sha512-s6SowJIjzlhx8o7lsFx5zmY4At6CTtDvgNQDdPzkBQucle58A6b/TTeEBYtyDgmcXjUTM+vE8YOGHZzzbc/ioA==} - peerDependencies: - '@babel/core': ^7.0.0-0 + '@babel/plugin-proposal-object-rest-spread@7.12.1(@babel/core@7.12.9)': dependencies: '@babel/core': 7.12.9 '@babel/helper-plugin-utils': 7.20.2 '@babel/plugin-syntax-object-rest-spread': 7.8.3(@babel/core@7.12.9) '@babel/plugin-transform-parameters': 7.20.3(@babel/core@7.12.9) - dev: true - /@babel/plugin-syntax-async-generators@7.8.4(@babel/core@7.24.4): - resolution: {integrity: sha512-tycmZxkGfZaxhMRbXlPXuVFpdWlXpir2W4AMhSJgRKzk/eDlIXOhb2LHWoLpDF7TEHylV5zNhykX6KAgHJmTNw==} - peerDependencies: - '@babel/core': ^7.0.0-0 + '@babel/plugin-syntax-async-generators@7.8.4(@babel/core@7.24.4)': dependencies: '@babel/core': 7.24.4 '@babel/helper-plugin-utils': 7.20.2 - dev: true - /@babel/plugin-syntax-bigint@7.8.3(@babel/core@7.24.4): - resolution: {integrity: sha512-wnTnFlG+YxQm3vDxpGE57Pj0srRU4sHE/mDkt1qv2YJJSeUAec2ma4WLUnUPeKjyrfntVwe/N6dCXpU+zL3Npg==} - peerDependencies: - '@babel/core': ^7.0.0-0 + '@babel/plugin-syntax-bigint@7.8.3(@babel/core@7.24.4)': dependencies: '@babel/core': 7.24.4 '@babel/helper-plugin-utils': 7.20.2 - dev: true - /@babel/plugin-syntax-class-properties@7.12.13(@babel/core@7.24.4): - resolution: {integrity: sha512-fm4idjKla0YahUNgFNLCB0qySdsoPiZP3iQE3rky0mBUtMZ23yDJ9SJdg6dXTSDnulOVqiF3Hgr9nbXvXTQZYA==} - peerDependencies: - '@babel/core': ^7.0.0-0 + '@babel/plugin-syntax-class-properties@7.12.13(@babel/core@7.24.4)': dependencies: '@babel/core': 7.24.4 '@babel/helper-plugin-utils': 7.20.2 - dev: true - /@babel/plugin-syntax-import-meta@7.10.4(@babel/core@7.24.4): - resolution: {integrity: sha512-Yqfm+XDx0+Prh3VSeEQCPU81yC+JWZ2pDPFSS4ZdpfZhp4MkFMaDC1UqseovEKwSUpnIL7+vK+Clp7bfh0iD7g==} - peerDependencies: - '@babel/core': ^7.0.0-0 + '@babel/plugin-syntax-import-meta@7.10.4(@babel/core@7.24.4)': dependencies: '@babel/core': 7.24.4 '@babel/helper-plugin-utils': 7.20.2 - dev: true - /@babel/plugin-syntax-json-strings@7.8.3(@babel/core@7.24.4): - resolution: {integrity: sha512-lY6kdGpWHvjoe2vk4WrAapEuBR69EMxZl+RoGRhrFGNYVK8mOPAW8VfbT/ZgrFbXlDNiiaxQnAtgVCZ6jv30EA==} - peerDependencies: - '@babel/core': ^7.0.0-0 + '@babel/plugin-syntax-json-strings@7.8.3(@babel/core@7.24.4)': dependencies: '@babel/core': 7.24.4 '@babel/helper-plugin-utils': 7.20.2 - dev: true - /@babel/plugin-syntax-jsx@7.12.1(@babel/core@7.12.9): - resolution: {integrity: sha512-1yRi7yAtB0ETgxdY9ti/p2TivUxJkTdhu/ZbF9MshVGqOx1TdB3b7xCXs49Fupgg50N45KcAsRP/ZqWjs9SRjg==} - peerDependencies: - '@babel/core': ^7.0.0-0 + '@babel/plugin-syntax-jsx@7.12.1(@babel/core@7.12.9)': dependencies: '@babel/core': 7.12.9 '@babel/helper-plugin-utils': 7.20.2 - dev: true - /@babel/plugin-syntax-jsx@7.18.6(@babel/core@7.24.4): - resolution: {integrity: sha512-6mmljtAedFGTWu2p/8WIORGwy+61PLgOMPOdazc7YoJ9ZCWUyFy3A6CpPkRKLKD1ToAesxX8KGEViAiLo9N+7Q==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 + '@babel/plugin-syntax-jsx@7.18.6(@babel/core@7.24.4)': dependencies: '@babel/core': 7.24.4 '@babel/helper-plugin-utils': 7.20.2 - dev: true - /@babel/plugin-syntax-logical-assignment-operators@7.10.4(@babel/core@7.24.4): - resolution: {integrity: sha512-d8waShlpFDinQ5MtvGU9xDAOzKH47+FFoney2baFIoMr952hKOLp1HR7VszoZvOsV/4+RRszNY7D17ba0te0ig==} - peerDependencies: - '@babel/core': ^7.0.0-0 + '@babel/plugin-syntax-logical-assignment-operators@7.10.4(@babel/core@7.24.4)': dependencies: '@babel/core': 7.24.4 '@babel/helper-plugin-utils': 7.20.2 - dev: true - /@babel/plugin-syntax-nullish-coalescing-operator@7.8.3(@babel/core@7.24.4): - resolution: {integrity: sha512-aSff4zPII1u2QD7y+F8oDsz19ew4IGEJg9SVW+bqwpwtfFleiQDMdzA/R+UlWDzfnHFCxxleFT0PMIrR36XLNQ==} - peerDependencies: - '@babel/core': ^7.0.0-0 + '@babel/plugin-syntax-nullish-coalescing-operator@7.8.3(@babel/core@7.24.4)': dependencies: '@babel/core': 7.24.4 '@babel/helper-plugin-utils': 7.20.2 - dev: true - /@babel/plugin-syntax-numeric-separator@7.10.4(@babel/core@7.24.4): - resolution: {integrity: sha512-9H6YdfkcK/uOnY/K7/aA2xpzaAgkQn37yzWUMRK7OaPOqOpGS1+n0H5hxT9AUw9EsSjPW8SVyMJwYRtWs3X3ug==} - peerDependencies: - '@babel/core': ^7.0.0-0 + '@babel/plugin-syntax-numeric-separator@7.10.4(@babel/core@7.24.4)': dependencies: '@babel/core': 7.24.4 '@babel/helper-plugin-utils': 7.20.2 - dev: true - /@babel/plugin-syntax-object-rest-spread@7.8.3(@babel/core@7.12.9): - resolution: {integrity: sha512-XoqMijGZb9y3y2XskN+P1wUGiVwWZ5JmoDRwx5+3GmEplNyVM2s2Dg8ILFQm8rWM48orGy5YpI5Bl8U1y7ydlA==} - peerDependencies: - '@babel/core': ^7.0.0-0 + '@babel/plugin-syntax-object-rest-spread@7.8.3(@babel/core@7.12.9)': dependencies: '@babel/core': 7.12.9 '@babel/helper-plugin-utils': 7.20.2 - dev: true - /@babel/plugin-syntax-object-rest-spread@7.8.3(@babel/core@7.24.4): - resolution: {integrity: sha512-XoqMijGZb9y3y2XskN+P1wUGiVwWZ5JmoDRwx5+3GmEplNyVM2s2Dg8ILFQm8rWM48orGy5YpI5Bl8U1y7ydlA==} - peerDependencies: - '@babel/core': ^7.0.0-0 + '@babel/plugin-syntax-object-rest-spread@7.8.3(@babel/core@7.24.4)': dependencies: '@babel/core': 7.24.4 '@babel/helper-plugin-utils': 7.20.2 - dev: true - /@babel/plugin-syntax-optional-catch-binding@7.8.3(@babel/core@7.24.4): - resolution: {integrity: sha512-6VPD0Pc1lpTqw0aKoeRTMiB+kWhAoT24PA+ksWSBrFtl5SIRVpZlwN3NNPQjehA2E/91FV3RjLWoVTglWcSV3Q==} - peerDependencies: - '@babel/core': ^7.0.0-0 + '@babel/plugin-syntax-optional-catch-binding@7.8.3(@babel/core@7.24.4)': dependencies: '@babel/core': 7.24.4 '@babel/helper-plugin-utils': 7.20.2 - dev: true - /@babel/plugin-syntax-optional-chaining@7.8.3(@babel/core@7.24.4): - resolution: {integrity: sha512-KoK9ErH1MBlCPxV0VANkXW2/dw4vlbGDrFgz8bmUsBGYkFRcbRwMh6cIJubdPrkxRwuGdtCk0v/wPTKbQgBjkg==} - peerDependencies: - '@babel/core': ^7.0.0-0 + '@babel/plugin-syntax-optional-chaining@7.8.3(@babel/core@7.24.4)': dependencies: '@babel/core': 7.24.4 '@babel/helper-plugin-utils': 7.20.2 - dev: true - /@babel/plugin-syntax-top-level-await@7.14.5(@babel/core@7.24.4): - resolution: {integrity: sha512-hx++upLv5U1rgYfwe1xBQUhRmU41NEvpUvrp8jkrSCdvGSnM5/qdRMtylJ6PG5OFkBaHkbTAKTnd3/YyESRHFw==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 + '@babel/plugin-syntax-top-level-await@7.14.5(@babel/core@7.24.4)': dependencies: '@babel/core': 7.24.4 '@babel/helper-plugin-utils': 7.20.2 - dev: true - /@babel/plugin-syntax-typescript@7.18.6(@babel/core@7.24.4): - resolution: {integrity: sha512-mAWAuq4rvOepWCBid55JuRNvpTNf2UGVgoz4JV0fXEKolsVZDzsa4NqCef758WZJj/GDu0gVGItjKFiClTAmZA==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 + '@babel/plugin-syntax-typescript@7.18.6(@babel/core@7.24.4)': dependencies: '@babel/core': 7.24.4 '@babel/helper-plugin-utils': 7.20.2 - dev: true - /@babel/plugin-transform-parameters@7.20.3(@babel/core@7.12.9): - resolution: {integrity: sha512-oZg/Fpx0YDrj13KsLyO8I/CX3Zdw7z0O9qOd95SqcoIzuqy/WTGWvePeHAnZCN54SfdyjHcb1S30gc8zlzlHcA==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 + '@babel/plugin-transform-parameters@7.20.3(@babel/core@7.12.9)': dependencies: '@babel/core': 7.12.9 '@babel/helper-plugin-utils': 7.20.2 - dev: true - /@babel/runtime@7.17.9: - resolution: {integrity: sha512-lSiBBvodq29uShpWGNbgFdKYNiFDo5/HIYsaCEY9ff4sb10x9jizo2+pRrSyF4jKZCXqgzuqBOQKbUm90gQwJg==} - engines: {node: '>=6.9.0'} + '@babel/runtime@7.17.9': dependencies: regenerator-runtime: 0.13.11 - dev: true - /@babel/runtime@7.19.4: - resolution: {integrity: sha512-EXpLCrk55f+cYqmHsSR+yD/0gAIMxxA9QK9lnQWzhMCvt+YmoBN7Zx94s++Kv0+unHk39vxNO8t+CMA2WSS3wA==} - engines: {node: '>=6.9.0'} + '@babel/runtime@7.19.4': dependencies: regenerator-runtime: 0.13.11 - dev: true - /@babel/runtime@7.21.0: - resolution: {integrity: sha512-xwII0//EObnq89Ji5AKYQaRYiW/nZ3llSv29d49IuxPhKbtJoLP+9QUUZ4nVragQVtaVGeZrpB+ZtG/Pdy/POw==} - engines: {node: '>=6.9.0'} + '@babel/runtime@7.21.0': dependencies: regenerator-runtime: 0.13.11 - /@babel/runtime@7.24.4: - resolution: {integrity: sha512-dkxf7+hn8mFBwKjs9bvBlArzLVxVbS8usaPUDd5p2a9JCL9tB8OaOVN1isD4+Xyk4ns89/xeOmbQvgdK7IIVdA==} - engines: {node: '>=6.9.0'} + '@babel/runtime@7.24.4': dependencies: regenerator-runtime: 0.14.1 - dev: true - /@babel/template@7.18.10: - resolution: {integrity: sha512-TI+rCtooWHr3QJ27kJxfjutghu44DLnasDMwpDqCXVTal9RLp3RSYNh4NdBrRP2cQAoG9A8juOQl6P6oZG4JxA==} - engines: {node: '>=6.9.0'} + '@babel/template@7.18.10': dependencies: '@babel/code-frame': 7.22.5 '@babel/parser': 7.24.4 '@babel/types': 7.24.0 - dev: true - /@babel/template@7.24.0: - resolution: {integrity: sha512-Bkf2q8lMB0AFpX0NFEqSbx1OkTHf0f+0j82mkw+ZpzBnkk7e9Ql0891vlfgi+kHwOk8tQjiQHpqh4LaSa0fKEA==} - engines: {node: '>=6.9.0'} + '@babel/template@7.24.0': dependencies: '@babel/code-frame': 7.24.2 '@babel/parser': 7.24.4 '@babel/types': 7.24.0 - dev: true - /@babel/traverse@7.24.1: - resolution: {integrity: sha512-xuU6o9m68KeqZbQuDt2TcKSxUw/mrsvavlEqQ1leZ/B+C9tk6E4sRWy97WaXgvq5E+nU3cXMxv3WKOCanVMCmQ==} - engines: {node: '>=6.9.0'} + '@babel/traverse@7.24.1': dependencies: '@babel/code-frame': 7.24.2 '@babel/generator': 7.24.4 @@ -5481,80 +13916,40 @@ packages: globals: 11.12.0 transitivePeerDependencies: - supports-color - dev: true - /@babel/types@7.20.2: - resolution: {integrity: sha512-FnnvsNWgZCr232sqtXggapvlkk/tuwR/qhGzcmxI0GXLCjmPYQPzio2FbdlWuY6y1sHFfQKk+rRbUZ9VStQMog==} - engines: {node: '>=6.9.0'} + '@babel/types@7.20.2': dependencies: '@babel/helper-string-parser': 7.19.4 '@babel/helper-validator-identifier': 7.22.5 to-fast-properties: 2.0.0 - dev: true - /@babel/types@7.24.0: - resolution: {integrity: sha512-+j7a5c253RfKh8iABBhywc8NSfP5LURe7Uh4qpsh6jc+aLJguvmIUBdjSdEMQv2bENrCR5MfRdjGo7vzS/ob7w==} - engines: {node: '>=6.9.0'} + '@babel/types@7.24.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: - resolution: {integrity: sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==} - dev: true + '@bcoe/v8-coverage@0.2.3': {} - /@cbor-extract/cbor-extract-darwin-arm64@2.2.0: - resolution: {integrity: sha512-P7swiOAdF7aSi0H+tHtHtr6zrpF3aAq/W9FXx5HektRvLTM2O89xCyXF3pk7pLc7QpaY7AoaE8UowVf9QBdh3w==} - cpu: [arm64] - os: [darwin] - requiresBuild: true - dev: false + '@cbor-extract/cbor-extract-darwin-arm64@2.2.0': optional: true - /@cbor-extract/cbor-extract-darwin-x64@2.2.0: - resolution: {integrity: sha512-1liF6fgowph0JxBbYnAS7ZlqNYLf000Qnj4KjqPNW4GViKrEql2MgZnAsExhY9LSy8dnvA4C0qHEBgPrll0z0w==} - cpu: [x64] - os: [darwin] - requiresBuild: true - dev: false + '@cbor-extract/cbor-extract-darwin-x64@2.2.0': optional: true - /@cbor-extract/cbor-extract-linux-arm64@2.2.0: - resolution: {integrity: sha512-rQvhNmDuhjTVXSPFLolmQ47/ydGOFXtbR7+wgkSY0bdOxCFept1hvg59uiLPT2fVDuJFuEy16EImo5tE2x3RsQ==} - cpu: [arm64] - os: [linux] - requiresBuild: true - dev: false + '@cbor-extract/cbor-extract-linux-arm64@2.2.0': optional: true - /@cbor-extract/cbor-extract-linux-arm@2.2.0: - resolution: {integrity: sha512-QeBcBXk964zOytiedMPQNZr7sg0TNavZeuUCD6ON4vEOU/25+pLhNN6EDIKJ9VLTKaZ7K7EaAriyYQ1NQ05s/Q==} - cpu: [arm] - os: [linux] - requiresBuild: true - dev: false + '@cbor-extract/cbor-extract-linux-arm@2.2.0': optional: true - /@cbor-extract/cbor-extract-linux-x64@2.2.0: - resolution: {integrity: sha512-cWLAWtT3kNLHSvP4RKDzSTX9o0wvQEEAj4SKvhWuOVZxiDAeQazr9A+PSiRILK1VYMLeDml89ohxCnUNQNQNCw==} - cpu: [x64] - os: [linux] - requiresBuild: true - dev: false + '@cbor-extract/cbor-extract-linux-x64@2.2.0': optional: true - /@cbor-extract/cbor-extract-win32-x64@2.2.0: - resolution: {integrity: sha512-l2M+Z8DO2vbvADOBNLbbh9y5ST1RY5sqkWOg/58GkUPBYou/cuNZ68SGQ644f1CvZ8kcOxyZtw06+dxWHIoN/w==} - cpu: [x64] - os: [win32] - requiresBuild: true - dev: false + '@cbor-extract/cbor-extract-win32-x64@2.2.0': optional: true - /@changesets/apply-release-plan@6.1.4: - resolution: {integrity: sha512-FMpKF1fRlJyCZVYHr3CbinpZZ+6MwvOtWUuO8uo+svcATEoc1zRDcj23pAurJ2TZ/uVz1wFHH6K3NlACy0PLew==} + '@changesets/apply-release-plan@6.1.4': dependencies: '@babel/runtime': 7.21.0 '@changesets/config': 2.3.1 @@ -5569,10 +13964,8 @@ packages: prettier: 2.8.4 resolve-from: 5.0.0 semver: 7.6.0 - dev: true - /@changesets/assemble-release-plan@5.2.4: - resolution: {integrity: sha512-xJkWX+1/CUaOUWTguXEbCDTyWJFECEhmdtbkjhn5GVBGxdP/JwaHBIU9sW3FR6gD07UwZ7ovpiPclQZs+j+mvg==} + '@changesets/assemble-release-plan@5.2.4': dependencies: '@babel/runtime': 7.21.0 '@changesets/errors': 0.1.4 @@ -5580,17 +13973,12 @@ packages: '@changesets/types': 5.2.1 '@manypkg/get-packages': 1.1.3 semver: 7.6.0 - dev: true - /@changesets/changelog-git@0.1.14: - resolution: {integrity: sha512-+vRfnKtXVWsDDxGctOfzJsPhaCdXRYoe+KyWYoq5X/GqoISREiat0l3L8B0a453B2B4dfHGcZaGyowHbp9BSaA==} + '@changesets/changelog-git@0.1.14': dependencies: '@changesets/types': 5.2.1 - dev: true - /@changesets/cli@2.26.2: - resolution: {integrity: sha512-dnWrJTmRR8bCHikJHl9b9HW3gXACCehz4OasrXpMp7sx97ECuBGGNjJhjPhdZNCvMy9mn4BWdplI323IbqsRig==} - hasBin: true + '@changesets/cli@2.26.2': dependencies: '@babel/runtime': 7.21.0 '@changesets/apply-release-plan': 6.1.4 @@ -5625,10 +14013,8 @@ packages: spawndamnit: 2.0.0 term-size: 2.2.1 tty-table: 4.1.6 - dev: true - /@changesets/config@2.3.1: - resolution: {integrity: sha512-PQXaJl82CfIXddUOppj4zWu+987GCw2M+eQcOepxN5s+kvnsZOwjEJO3DH9eVy+OP6Pg/KFEWdsECFEYTtbg6w==} + '@changesets/config@2.3.1': dependencies: '@changesets/errors': 0.1.4 '@changesets/get-dependents-graph': 1.3.6 @@ -5637,26 +14023,20 @@ packages: '@manypkg/get-packages': 1.1.3 fs-extra: 7.0.1 micromatch: 4.0.5 - dev: true - /@changesets/errors@0.1.4: - resolution: {integrity: sha512-HAcqPF7snsUJ/QzkWoKfRfXushHTu+K5KZLJWPb34s4eCZShIf8BFO3fwq6KU8+G7L5KdtN2BzQAXOSXEyiY9Q==} + '@changesets/errors@0.1.4': dependencies: extendable-error: 0.1.7 - dev: true - /@changesets/get-dependents-graph@1.3.6: - resolution: {integrity: sha512-Q/sLgBANmkvUm09GgRsAvEtY3p1/5OCzgBE5vX3vgb5CvW0j7CEljocx5oPXeQSNph6FXulJlXV3Re/v3K3P3Q==} + '@changesets/get-dependents-graph@1.3.6': dependencies: '@changesets/types': 5.2.1 '@manypkg/get-packages': 1.1.3 chalk: 2.4.2 fs-extra: 7.0.1 semver: 7.6.0 - dev: true - /@changesets/get-release-plan@3.0.17: - resolution: {integrity: sha512-6IwKTubNEgoOZwDontYc2x2cWXfr6IKxP3IhKeK+WjyD6y3M4Gl/jdQvBw+m/5zWILSOCAaGLu2ZF6Q+WiPniw==} + '@changesets/get-release-plan@3.0.17': dependencies: '@babel/runtime': 7.21.0 '@changesets/assemble-release-plan': 5.2.4 @@ -5665,14 +14045,10 @@ packages: '@changesets/read': 0.5.9 '@changesets/types': 5.2.1 '@manypkg/get-packages': 1.1.3 - dev: true - /@changesets/get-version-range-type@0.3.2: - resolution: {integrity: sha512-SVqwYs5pULYjYT4op21F2pVbcrca4qA/bAA3FmFXKMN7Y+HcO8sbZUTx3TAy2VXulP2FACd1aC7f2nTuqSPbqg==} - dev: true + '@changesets/get-version-range-type@0.3.2': {} - /@changesets/git@2.0.0: - resolution: {integrity: sha512-enUVEWbiqUTxqSnmesyJGWfzd51PY4H7mH9yUw0hPVpZBJ6tQZFMU3F3mT/t9OJ/GjyiM4770i+sehAn6ymx6A==} + '@changesets/git@2.0.0': dependencies: '@babel/runtime': 7.21.0 '@changesets/errors': 0.1.4 @@ -5681,33 +14057,25 @@ packages: is-subdir: 1.2.0 micromatch: 4.0.5 spawndamnit: 2.0.0 - dev: true - /@changesets/logger@0.0.5: - resolution: {integrity: sha512-gJyZHomu8nASHpaANzc6bkQMO9gU/ib20lqew1rVx753FOxffnCrJlGIeQVxNWCqM+o6OOleCo/ivL8UAO5iFw==} + '@changesets/logger@0.0.5': dependencies: chalk: 2.4.2 - dev: true - /@changesets/parse@0.3.16: - resolution: {integrity: sha512-127JKNd167ayAuBjUggZBkmDS5fIKsthnr9jr6bdnuUljroiERW7FBTDNnNVyJ4l69PzR57pk6mXQdtJyBCJKg==} + '@changesets/parse@0.3.16': dependencies: '@changesets/types': 5.2.1 js-yaml: 3.14.1 - dev: true - /@changesets/pre@1.0.14: - resolution: {integrity: sha512-dTsHmxQWEQekHYHbg+M1mDVYFvegDh9j/kySNuDKdylwfMEevTeDouR7IfHNyVodxZXu17sXoJuf2D0vi55FHQ==} + '@changesets/pre@1.0.14': dependencies: '@babel/runtime': 7.21.0 '@changesets/errors': 0.1.4 '@changesets/types': 5.2.1 '@manypkg/get-packages': 1.1.3 fs-extra: 7.0.1 - dev: true - /@changesets/read@0.5.9: - resolution: {integrity: sha512-T8BJ6JS6j1gfO1HFq50kU3qawYxa4NTbI/ASNVVCBTsKquy2HYwM9r7ZnzkiMe8IEObAJtUVGSrePCOxAK2haQ==} + '@changesets/read@0.5.9': dependencies: '@babel/runtime': 7.21.0 '@changesets/git': 2.0.0 @@ -5717,30 +14085,20 @@ packages: chalk: 2.4.2 fs-extra: 7.0.1 p-filter: 2.1.0 - dev: true - /@changesets/types@4.1.0: - resolution: {integrity: sha512-LDQvVDv5Kb50ny2s25Fhm3d9QSZimsoUGBsUioj6MC3qbMUCuC8GPIvk/M6IvXx3lYhAs0lwWUQLb+VIEUCECw==} - dev: true + '@changesets/types@4.1.0': {} - /@changesets/types@5.2.1: - resolution: {integrity: sha512-myLfHbVOqaq9UtUKqR/nZA/OY7xFjQMdfgfqeZIBK4d0hA6pgxArvdv8M+6NUzzBsjWLOtvApv8YHr4qM+Kpfg==} - dev: true + '@changesets/types@5.2.1': {} - /@changesets/write@0.2.3: - resolution: {integrity: sha512-Dbamr7AIMvslKnNYsLFafaVORx4H0pvCA2MHqgtNCySMe1blImEyAEOzDmcgKAkgz4+uwoLz7demIrX+JBr/Xw==} + '@changesets/write@0.2.3': dependencies: '@babel/runtime': 7.21.0 '@changesets/types': 5.2.1 fs-extra: 7.0.1 human-id: 1.0.2 prettier: 2.8.4 - dev: true - /@commitlint/cli@19.0.3(@types/node@20.12.7)(typescript@5.0.2): - resolution: {integrity: sha512-mGhh/aYPib4Vy4h+AGRloMY+CqkmtdeKPV9poMcZeImF5e3knQ5VYaSeAM0mEzps1dbKsHvABwaDpafLUuM96g==} - engines: {node: '>=v18'} - hasBin: true + '@commitlint/cli@19.0.3(@types/node@20.12.7)(typescript@5.0.2)': dependencies: '@commitlint/format': 19.0.3 '@commitlint/lint': 19.0.3 @@ -5752,27 +14110,18 @@ packages: transitivePeerDependencies: - '@types/node' - typescript - dev: true - /@commitlint/config-conventional@19.0.3: - resolution: {integrity: sha512-vh0L8XeLaEzTe8VCxSd0gAFvfTK0RFolrzw4o431bIuWJfi/yRCHJlsDwus7wW2eJaFFDR0VFXJyjGyDQhi4vA==} - engines: {node: '>=v18'} + '@commitlint/config-conventional@19.0.3': dependencies: '@commitlint/types': 19.0.3 conventional-changelog-conventionalcommits: 7.0.2 - dev: true - /@commitlint/config-validator@19.0.3: - resolution: {integrity: sha512-2D3r4PKjoo59zBc2auodrSCaUnCSALCx54yveOFwwP/i2kfEAQrygwOleFWswLqK0UL/F9r07MFi5ev2ohyM4Q==} - engines: {node: '>=v18'} + '@commitlint/config-validator@19.0.3': dependencies: '@commitlint/types': 19.0.3 ajv: 8.12.0 - dev: true - /@commitlint/ensure@19.0.3: - resolution: {integrity: sha512-SZEpa/VvBLoT+EFZVb91YWbmaZ/9rPH3ESrINOl0HD2kMYsjvl0tF7nMHh0EpTcv4+gTtZBAe1y/SS6/OhfZzQ==} - engines: {node: '>=v18'} + '@commitlint/ensure@19.0.3': dependencies: '@commitlint/types': 19.0.3 lodash.camelcase: 4.3.0 @@ -5780,42 +14129,27 @@ packages: lodash.snakecase: 4.1.1 lodash.startcase: 4.4.0 lodash.upperfirst: 4.3.1 - dev: true - /@commitlint/execute-rule@19.0.0: - resolution: {integrity: sha512-mtsdpY1qyWgAO/iOK0L6gSGeR7GFcdW7tIjcNFxcWkfLDF5qVbPHKuGATFqRMsxcO8OUKNj0+3WOHB7EHm4Jdw==} - engines: {node: '>=v18'} - dev: true + '@commitlint/execute-rule@19.0.0': {} - /@commitlint/format@19.0.3: - resolution: {integrity: sha512-QjjyGyoiVWzx1f5xOteKHNLFyhyweVifMgopozSgx1fGNrGV8+wp7k6n1t6StHdJ6maQJ+UUtO2TcEiBFRyR6Q==} - engines: {node: '>=v18'} + '@commitlint/format@19.0.3': dependencies: '@commitlint/types': 19.0.3 chalk: 5.3.0 - dev: true - /@commitlint/is-ignored@19.0.3: - resolution: {integrity: sha512-MqDrxJaRSVSzCbPsV6iOKG/Lt52Y+PVwFVexqImmYYFhe51iVJjK2hRhOG2jUAGiUHk4jpdFr0cZPzcBkSzXDQ==} - engines: {node: '>=v18'} + '@commitlint/is-ignored@19.0.3': dependencies: '@commitlint/types': 19.0.3 semver: 7.6.0 - dev: true - /@commitlint/lint@19.0.3: - resolution: {integrity: sha512-uHPyRqIn57iIplYa5xBr6oNu5aPXKGC4WLeuHfqQHclwIqbJ33g3yA5fIA+/NYnp5ZM2EFiujqHFaVUYj6HlKA==} - engines: {node: '>=v18'} + '@commitlint/lint@19.0.3': dependencies: '@commitlint/is-ignored': 19.0.3 '@commitlint/parse': 19.0.3 '@commitlint/rules': 19.0.3 '@commitlint/types': 19.0.3 - dev: true - /@commitlint/load@19.0.3(@types/node@20.12.7)(typescript@5.0.2): - resolution: {integrity: sha512-18Tk/ZcDFRKIoKfEcl7kC+bYkEQ055iyKmGsYDoYWpKf6FUvBrP9bIWapuy/MB+kYiltmP9ITiUx6UXtqC9IRw==} - engines: {node: '>=v18'} + '@commitlint/load@19.0.3(@types/node@20.12.7)(typescript@5.0.2)': dependencies: '@commitlint/config-validator': 19.0.3 '@commitlint/execute-rule': 19.0.0 @@ -5830,35 +14164,23 @@ packages: transitivePeerDependencies: - '@types/node' - typescript - dev: true - /@commitlint/message@19.0.0: - resolution: {integrity: sha512-c9czf6lU+9oF9gVVa2lmKaOARJvt4soRsVmbR7Njwp9FpbBgste5i7l/2l5o8MmbwGh4yE1snfnsy2qyA2r/Fw==} - engines: {node: '>=v18'} - dev: true + '@commitlint/message@19.0.0': {} - /@commitlint/parse@19.0.3: - resolution: {integrity: sha512-Il+tNyOb8VDxN3P6XoBBwWJtKKGzHlitEuXA5BP6ir/3loWlsSqDr5aecl6hZcC/spjq4pHqNh0qPlfeWu38QA==} - engines: {node: '>=v18'} + '@commitlint/parse@19.0.3': dependencies: '@commitlint/types': 19.0.3 conventional-changelog-angular: 7.0.0 conventional-commits-parser: 5.0.0 - dev: true - /@commitlint/read@19.0.3: - resolution: {integrity: sha512-b5AflTyAXkUx5qKw4TkjjcOccXZHql3JqMi522knTQktq2AubKXFz60Sws+K4FsefwPws6fGz9mqiI/NvsvxFA==} - engines: {node: '>=v18'} + '@commitlint/read@19.0.3': dependencies: '@commitlint/top-level': 19.0.0 '@commitlint/types': 19.0.3 git-raw-commits: 4.0.0 minimist: 1.2.8 - dev: true - /@commitlint/resolve-extends@19.0.3: - resolution: {integrity: sha512-18BKmta8OC8+Ub+Q3QGM9l27VjQaXobloVXOrMvu8CpEwJYv62vC/t7Ka5kJnsW0tU9q1eMqJFZ/nN9T/cOaIA==} - engines: {node: '>=v18'} + '@commitlint/resolve-extends@19.0.3': dependencies: '@commitlint/config-validator': 19.0.3 '@commitlint/types': 19.0.3 @@ -5866,305 +14188,122 @@ packages: import-meta-resolve: 4.0.0 lodash.mergewith: 4.6.2 resolve-from: 5.0.0 - dev: true - /@commitlint/rules@19.0.3: - resolution: {integrity: sha512-TspKb9VB6svklxNCKKwxhELn7qhtY1rFF8ls58DcFd0F97XoG07xugPjjbVnLqmMkRjZDbDIwBKt9bddOfLaPw==} - engines: {node: '>=v18'} + '@commitlint/rules@19.0.3': dependencies: '@commitlint/ensure': 19.0.3 '@commitlint/message': 19.0.0 '@commitlint/to-lines': 19.0.0 '@commitlint/types': 19.0.3 execa: 8.0.1 - dev: true - /@commitlint/to-lines@19.0.0: - resolution: {integrity: sha512-vkxWo+VQU5wFhiP9Ub9Sre0FYe019JxFikrALVoD5UGa8/t3yOJEpEhxC5xKiENKKhUkTpEItMTRAjHw2SCpZw==} - engines: {node: '>=v18'} - dev: true + '@commitlint/to-lines@19.0.0': {} - /@commitlint/top-level@19.0.0: - resolution: {integrity: sha512-KKjShd6u1aMGNkCkaX4aG1jOGdn7f8ZI8TR1VEuNqUOjWTOdcDSsmglinglJ18JTjuBX5I1PtjrhQCRcixRVFQ==} - engines: {node: '>=v18'} + '@commitlint/top-level@19.0.0': dependencies: find-up: 7.0.0 - dev: true - /@commitlint/types@19.0.3: - resolution: {integrity: sha512-tpyc+7i6bPG9mvaBbtKUeghfyZSDgWquIDfMgqYtTbmZ9Y9VzEm2je9EYcQ0aoz5o7NvGS+rcDec93yO08MHYA==} - engines: {node: '>=v18'} + '@commitlint/types@19.0.3': dependencies: '@types/conventional-commits-parser': 5.0.0 chalk: 5.3.0 - dev: true - /@cspotcode/source-map-support@0.8.1: - resolution: {integrity: sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==} - engines: {node: '>=12'} + '@cspotcode/source-map-support@0.8.1': dependencies: '@jridgewell/trace-mapping': 0.3.9 - dev: true - /@csstools/css-parser-algorithms@2.6.1(@csstools/css-tokenizer@2.2.4): - resolution: {integrity: sha512-ubEkAaTfVZa+WwGhs5jbo5Xfqpeaybr/RvWzvFxRs4jfq16wH8l8Ty/QEEpINxll4xhuGfdMbipRyz5QZh9+FA==} - engines: {node: ^14 || ^16 || >=18} - peerDependencies: - '@csstools/css-tokenizer': ^2.2.4 + '@csstools/css-parser-algorithms@2.6.1(@csstools/css-tokenizer@2.2.4)': dependencies: '@csstools/css-tokenizer': 2.2.4 - dev: true - /@csstools/css-tokenizer@2.2.4: - resolution: {integrity: sha512-PuWRAewQLbDhGeTvFuq2oClaSCKPIBmHyIobCV39JHRYN0byDcUWJl5baPeNUcqrjtdMNqFooE0FGl31I3JOqw==} - engines: {node: ^14 || ^16 || >=18} - dev: true + '@csstools/css-tokenizer@2.2.4': {} - /@csstools/media-query-list-parser@2.1.9(@csstools/css-parser-algorithms@2.6.1)(@csstools/css-tokenizer@2.2.4): - resolution: {integrity: sha512-qqGuFfbn4rUmyOB0u8CVISIp5FfJ5GAR3mBrZ9/TKndHakdnm6pY0L/fbLcpPnrzwCyyTEZl1nUcXAYHEWneTA==} - engines: {node: ^14 || ^16 || >=18} - peerDependencies: - '@csstools/css-parser-algorithms': ^2.6.1 - '@csstools/css-tokenizer': ^2.2.4 + '@csstools/media-query-list-parser@2.1.9(@csstools/css-parser-algorithms@2.6.1)(@csstools/css-tokenizer@2.2.4)': dependencies: '@csstools/css-parser-algorithms': 2.6.1(@csstools/css-tokenizer@2.2.4) '@csstools/css-tokenizer': 2.2.4 - dev: true - /@csstools/selector-specificity@3.0.3(postcss-selector-parser@6.0.16): - resolution: {integrity: sha512-KEPNw4+WW5AVEIyzC80rTbWEUatTW2lXpN8+8ILC8PiPeWPjwUzrPZDIOZ2wwqDmeqOYTdSGyL3+vE5GC3FB3Q==} - engines: {node: ^14 || ^16 || >=18} - peerDependencies: - postcss-selector-parser: ^6.0.13 + '@csstools/selector-specificity@3.0.3(postcss-selector-parser@6.0.16)': dependencies: postcss-selector-parser: 6.0.16 - dev: true - /@esbuild/aix-ppc64@0.20.2: - resolution: {integrity: sha512-D+EBOJHXdNZcLJRBkhENNG8Wji2kgc9AZ9KiPr1JuZjsNtyHzrsfLRrY0tk2H2aoFu6RANO1y1iPPUCDYWkb5g==} - engines: {node: '>=12'} - cpu: [ppc64] - os: [aix] - requiresBuild: true - dev: true + '@esbuild/aix-ppc64@0.20.2': optional: true - /@esbuild/android-arm64@0.20.2: - resolution: {integrity: sha512-mRzjLacRtl/tWU0SvD8lUEwb61yP9cqQo6noDZP/O8VkwafSYwZ4yWy24kan8jE/IMERpYncRt2dw438LP3Xmg==} - engines: {node: '>=12'} - cpu: [arm64] - os: [android] - requiresBuild: true - dev: true + '@esbuild/android-arm64@0.20.2': optional: true - /@esbuild/android-arm@0.20.2: - resolution: {integrity: sha512-t98Ra6pw2VaDhqNWO2Oph2LXbz/EJcnLmKLGBJwEwXX/JAN83Fym1rU8l0JUWK6HkIbWONCSSatf4sf2NBRx/w==} - engines: {node: '>=12'} - cpu: [arm] - os: [android] - requiresBuild: true - dev: true + '@esbuild/android-arm@0.20.2': optional: true - /@esbuild/android-x64@0.20.2: - resolution: {integrity: sha512-btzExgV+/lMGDDa194CcUQm53ncxzeBrWJcncOBxuC6ndBkKxnHdFJn86mCIgTELsooUmwUm9FkhSp5HYu00Rg==} - engines: {node: '>=12'} - cpu: [x64] - os: [android] - requiresBuild: true - dev: true + '@esbuild/android-x64@0.20.2': optional: true - /@esbuild/darwin-arm64@0.20.2: - resolution: {integrity: sha512-4J6IRT+10J3aJH3l1yzEg9y3wkTDgDk7TSDFX+wKFiWjqWp/iCfLIYzGyasx9l0SAFPT1HwSCR+0w/h1ES/MjA==} - engines: {node: '>=12'} - cpu: [arm64] - os: [darwin] - requiresBuild: true - dev: true + '@esbuild/darwin-arm64@0.20.2': optional: true - /@esbuild/darwin-x64@0.20.2: - resolution: {integrity: sha512-tBcXp9KNphnNH0dfhv8KYkZhjc+H3XBkF5DKtswJblV7KlT9EI2+jeA8DgBjp908WEuYll6pF+UStUCfEpdysA==} - engines: {node: '>=12'} - cpu: [x64] - os: [darwin] - requiresBuild: true - dev: true + '@esbuild/darwin-x64@0.20.2': optional: true - /@esbuild/freebsd-arm64@0.20.2: - resolution: {integrity: sha512-d3qI41G4SuLiCGCFGUrKsSeTXyWG6yem1KcGZVS+3FYlYhtNoNgYrWcvkOoaqMhwXSMrZRl69ArHsGJ9mYdbbw==} - engines: {node: '>=12'} - cpu: [arm64] - os: [freebsd] - requiresBuild: true - dev: true + '@esbuild/freebsd-arm64@0.20.2': optional: true - /@esbuild/freebsd-x64@0.20.2: - resolution: {integrity: sha512-d+DipyvHRuqEeM5zDivKV1KuXn9WeRX6vqSqIDgwIfPQtwMP4jaDsQsDncjTDDsExT4lR/91OLjRo8bmC1e+Cw==} - engines: {node: '>=12'} - cpu: [x64] - os: [freebsd] - requiresBuild: true - dev: true + '@esbuild/freebsd-x64@0.20.2': optional: true - /@esbuild/linux-arm64@0.20.2: - resolution: {integrity: sha512-9pb6rBjGvTFNira2FLIWqDk/uaf42sSyLE8j1rnUpuzsODBq7FvpwHYZxQ/It/8b+QOS1RYfqgGFNLRI+qlq2A==} - engines: {node: '>=12'} - cpu: [arm64] - os: [linux] - requiresBuild: true - dev: true + '@esbuild/linux-arm64@0.20.2': optional: true - /@esbuild/linux-arm@0.20.2: - resolution: {integrity: sha512-VhLPeR8HTMPccbuWWcEUD1Az68TqaTYyj6nfE4QByZIQEQVWBB8vup8PpR7y1QHL3CpcF6xd5WVBU/+SBEvGTg==} - engines: {node: '>=12'} - cpu: [arm] - os: [linux] - requiresBuild: true - dev: true + '@esbuild/linux-arm@0.20.2': optional: true - /@esbuild/linux-ia32@0.20.2: - resolution: {integrity: sha512-o10utieEkNPFDZFQm9CoP7Tvb33UutoJqg3qKf1PWVeeJhJw0Q347PxMvBgVVFgouYLGIhFYG0UGdBumROyiig==} - engines: {node: '>=12'} - cpu: [ia32] - os: [linux] - requiresBuild: true - dev: true + '@esbuild/linux-ia32@0.20.2': optional: true - /@esbuild/linux-loong64@0.20.2: - resolution: {integrity: sha512-PR7sp6R/UC4CFVomVINKJ80pMFlfDfMQMYynX7t1tNTeivQ6XdX5r2XovMmha/VjR1YN/HgHWsVcTRIMkymrgQ==} - engines: {node: '>=12'} - cpu: [loong64] - os: [linux] - requiresBuild: true - dev: true + '@esbuild/linux-loong64@0.20.2': optional: true - /@esbuild/linux-mips64el@0.20.2: - resolution: {integrity: sha512-4BlTqeutE/KnOiTG5Y6Sb/Hw6hsBOZapOVF6njAESHInhlQAghVVZL1ZpIctBOoTFbQyGW+LsVYZ8lSSB3wkjA==} - engines: {node: '>=12'} - cpu: [mips64el] - os: [linux] - requiresBuild: true - dev: true + '@esbuild/linux-mips64el@0.20.2': optional: true - /@esbuild/linux-ppc64@0.20.2: - resolution: {integrity: sha512-rD3KsaDprDcfajSKdn25ooz5J5/fWBylaaXkuotBDGnMnDP1Uv5DLAN/45qfnf3JDYyJv/ytGHQaziHUdyzaAg==} - engines: {node: '>=12'} - cpu: [ppc64] - os: [linux] - requiresBuild: true - dev: true + '@esbuild/linux-ppc64@0.20.2': optional: true - /@esbuild/linux-riscv64@0.20.2: - resolution: {integrity: sha512-snwmBKacKmwTMmhLlz/3aH1Q9T8v45bKYGE3j26TsaOVtjIag4wLfWSiZykXzXuE1kbCE+zJRmwp+ZbIHinnVg==} - engines: {node: '>=12'} - cpu: [riscv64] - os: [linux] - requiresBuild: true - dev: true + '@esbuild/linux-riscv64@0.20.2': optional: true - /@esbuild/linux-s390x@0.20.2: - resolution: {integrity: sha512-wcWISOobRWNm3cezm5HOZcYz1sKoHLd8VL1dl309DiixxVFoFe/o8HnwuIwn6sXre88Nwj+VwZUvJf4AFxkyrQ==} - engines: {node: '>=12'} - cpu: [s390x] - os: [linux] - requiresBuild: true - dev: true + '@esbuild/linux-s390x@0.20.2': optional: true - /@esbuild/linux-x64@0.20.2: - resolution: {integrity: sha512-1MdwI6OOTsfQfek8sLwgyjOXAu+wKhLEoaOLTjbijk6E2WONYpH9ZU2mNtR+lZ2B4uwr+usqGuVfFT9tMtGvGw==} - engines: {node: '>=12'} - cpu: [x64] - os: [linux] - requiresBuild: true - dev: true + '@esbuild/linux-x64@0.20.2': optional: true - /@esbuild/netbsd-x64@0.20.2: - resolution: {integrity: sha512-K8/DhBxcVQkzYc43yJXDSyjlFeHQJBiowJ0uVL6Tor3jGQfSGHNNJcWxNbOI8v5k82prYqzPuwkzHt3J1T1iZQ==} - engines: {node: '>=12'} - cpu: [x64] - os: [netbsd] - requiresBuild: true - dev: true + '@esbuild/netbsd-x64@0.20.2': optional: true - /@esbuild/openbsd-x64@0.20.2: - resolution: {integrity: sha512-eMpKlV0SThJmmJgiVyN9jTPJ2VBPquf6Kt/nAoo6DgHAoN57K15ZghiHaMvqjCye/uU4X5u3YSMgVBI1h3vKrQ==} - engines: {node: '>=12'} - cpu: [x64] - os: [openbsd] - requiresBuild: true - dev: true + '@esbuild/openbsd-x64@0.20.2': optional: true - /@esbuild/sunos-x64@0.20.2: - resolution: {integrity: sha512-2UyFtRC6cXLyejf/YEld4Hajo7UHILetzE1vsRcGL3earZEW77JxrFjH4Ez2qaTiEfMgAXxfAZCm1fvM/G/o8w==} - engines: {node: '>=12'} - cpu: [x64] - os: [sunos] - requiresBuild: true - dev: true + '@esbuild/sunos-x64@0.20.2': optional: true - /@esbuild/win32-arm64@0.20.2: - resolution: {integrity: sha512-GRibxoawM9ZCnDxnP3usoUDO9vUkpAxIIZ6GQI+IlVmr5kP3zUq+l17xELTHMWTWzjxa2guPNyrpq1GWmPvcGQ==} - engines: {node: '>=12'} - cpu: [arm64] - os: [win32] - requiresBuild: true - dev: true + '@esbuild/win32-arm64@0.20.2': optional: true - /@esbuild/win32-ia32@0.20.2: - resolution: {integrity: sha512-HfLOfn9YWmkSKRQqovpnITazdtquEW8/SoHW7pWpuEeguaZI4QnCRW6b+oZTztdBnZOS2hqJ6im/D5cPzBTTlQ==} - engines: {node: '>=12'} - cpu: [ia32] - os: [win32] - requiresBuild: true - dev: true + '@esbuild/win32-ia32@0.20.2': optional: true - /@esbuild/win32-x64@0.20.2: - resolution: {integrity: sha512-N49X4lJX27+l9jbLKSqZ6bKNjzQvHaT8IIFUy+YIqmXQdjYCToGWwOItDrfby14c78aDd5NHQl29xingXfCdLQ==} - engines: {node: '>=12'} - cpu: [x64] - os: [win32] - requiresBuild: true - dev: true + '@esbuild/win32-x64@0.20.2': optional: true - /@eslint-community/eslint-utils@4.4.0(eslint@8.57.0): - resolution: {integrity: sha512-1/sA4dwrzBAyeUoQ6oxahHKmrZvsnLCg4RfxW3ZFGGmQkSNQPFNLV9CUEFQP1x9EYXHTo5p6xdhZM1Ne9p/AfA==} - engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} - peerDependencies: - eslint: ^6.0.0 || ^7.0.0 || >=8.0.0 + '@eslint-community/eslint-utils@4.4.0(eslint@8.57.0)': dependencies: eslint: 8.57.0 eslint-visitor-keys: 3.4.3 - dev: true - /@eslint-community/regexpp@4.10.0: - resolution: {integrity: sha512-Cu96Sd2By9mCNTx2iyKOmq10v22jUVQv0lQnlGNy16oE9589yE+QADPbrMGCkA51cKZSg3Pu/aTJVTGfL/qjUA==} - engines: {node: ^12.0.0 || ^14.0.0 || >=16.0.0} - dev: true + '@eslint-community/regexpp@4.10.0': {} - /@eslint/eslintrc@2.1.4: - resolution: {integrity: sha512-269Z39MS6wVJtsoUl10L60WdkhJVdPG24Q4eZTH3nnF6lpvSShEK3wQjDX9JRWAUPvPh7COouPpU9IrqaZFvtQ==} - engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + '@eslint/eslintrc@2.1.4': dependencies: ajv: 6.12.6 debug: 4.3.4 @@ -6177,38 +14316,21 @@ packages: strip-json-comments: 3.1.1 transitivePeerDependencies: - supports-color - dev: true - /@eslint/js@8.57.0: - resolution: {integrity: sha512-Ys+3g2TaW7gADOJzPt83SJtCDhMjndcDMFVQ/Tj9iA1BfJzFKD9mAUXT3OenpuPHbI6P/myECxRJrofUsDx/5g==} - engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} - dev: true + '@eslint/js@8.57.0': {} - /@fontsource/roboto-mono@5.0.0: - resolution: {integrity: sha512-PNxomCUy0blr1gNkc2TXfm8zMqnTVAtYfVYKBss6pgjex7lHENhqdDslCPNLwJDDqqPsWgpQ6TrMWEh4OTAVxQ==} - dev: true + '@fontsource/roboto-mono@5.0.0': {} - /@google-cloud/paginator@5.0.0: - resolution: {integrity: sha512-87aeg6QQcEPxGCOthnpUjvw4xAZ57G7pL8FS0C4e/81fr3FjkpUpibf1s2v5XGyGhUVGF4Jfg7yEcxqn2iUw1w==} - engines: {node: '>=14.0.0'} + '@google-cloud/paginator@5.0.0': dependencies: arrify: 2.0.1 extend: 3.0.2 - dev: false - /@google-cloud/projectify@4.0.0: - resolution: {integrity: sha512-MmaX6HeSvyPbWGwFq7mXdo0uQZLGBYCwziiLIGq5JVX+/bdI3SAq6bP98trV5eTWfLuvsMcIC1YJOF2vfteLFA==} - engines: {node: '>=14.0.0'} - dev: false + '@google-cloud/projectify@4.0.0': {} - /@google-cloud/promisify@4.0.0: - resolution: {integrity: sha512-Orxzlfb9c67A15cq2JQEyVc7wEsmFBmHjZWZYQMUyJ1qivXyMwdyNOs9odi79hze+2zqdTtu1E19IM/FtqZ10g==} - engines: {node: '>=14'} - dev: false + '@google-cloud/promisify@4.0.0': {} - /@google-cloud/storage@7.10.0: - resolution: {integrity: sha512-aBNejLVzHpI7C8eJSMpBpfdq1lxvYuHqG+zy/xvs032RyPRxuu45DLMeXuAbgwyx1VBsxWGYifrPDx+O7hJrmw==} - engines: {node: '>=14'} + '@google-cloud/storage@7.10.0': dependencies: '@google-cloud/paginator': 5.0.0 '@google-cloud/projectify': 4.0.0 @@ -6228,88 +14350,55 @@ packages: transitivePeerDependencies: - encoding - supports-color - dev: false - /@hapi/hoek@9.3.0: - resolution: {integrity: sha512-/c6rf4UJlmHlC9b5BaNvzAcFv7HZ2QHaV0D4/HNlBdvFnvQq8RI4kYdhyPCl7Xj+oWvTWQ8ujhqS53LIgAe6KQ==} - dev: true + '@hapi/hoek@9.3.0': {} - /@hapi/topo@5.1.0: - resolution: {integrity: sha512-foQZKJig7Ob0BMAYBfcJk8d77QtOe7Wo4ox7ff1lQYoNNAb6jwcY1ncdoy2e9wQZzvNy7ODZCYJkK8kzmcAnAg==} + '@hapi/topo@5.1.0': dependencies: '@hapi/hoek': 9.3.0 - dev: true - /@hexagon/base64@1.1.28: - resolution: {integrity: sha512-lhqDEAvWixy3bZ+UOYbPwUbBkwBq5C1LAJ/xPC8Oi+lL54oyakv/npbA0aU2hgCsx/1NUd4IBvV03+aUBWxerw==} - dev: false + '@hexagon/base64@1.1.28': {} - /@humanwhocodes/config-array@0.11.14: - resolution: {integrity: sha512-3T8LkOmg45BV5FICb15QQMsyUSWrQ8AygVfC7ZG32zOalnqrilm018ZVCw0eapXux8FtA33q8PSRSstjee3jSg==} - engines: {node: '>=10.10.0'} + '@humanwhocodes/config-array@0.11.14': dependencies: '@humanwhocodes/object-schema': 2.0.3 debug: 4.3.4 minimatch: 3.1.2 transitivePeerDependencies: - supports-color - dev: true - /@humanwhocodes/module-importer@1.0.1: - resolution: {integrity: sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==} - engines: {node: '>=12.22'} - dev: true + '@humanwhocodes/module-importer@1.0.1': {} - /@humanwhocodes/object-schema@2.0.3: - resolution: {integrity: sha512-93zYdMES/c1D69yZiKDBj0V24vqNzB/koF26KPaagAfd3P/4gUlh3Dys5ogAK+Exi9QyzlD8x/08Zt7wIKcDcA==} - dev: true + '@humanwhocodes/object-schema@2.0.3': {} - /@icons/material@0.2.4(react@18.2.0): - resolution: {integrity: sha512-QPcGmICAPbGLGb6F/yNf/KzKqvFx8z5qx3D1yFqVAjoFmXK35EgyW+cJ57Te3CNsmzblwtzakLGFqHPqrfb4Tw==} - peerDependencies: - react: '*' + '@icons/material@0.2.4(react@18.2.0)': dependencies: react: 18.2.0 - dev: true - /@isaacs/cliui@8.0.2: - resolution: {integrity: sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==} - engines: {node: '>=12'} + '@isaacs/cliui@8.0.2': dependencies: string-width: 5.1.2 - string-width-cjs: /string-width@4.2.3 + string-width-cjs: string-width@4.2.3 strip-ansi: 7.1.0 - strip-ansi-cjs: /strip-ansi@6.0.1 + strip-ansi-cjs: strip-ansi@6.0.1 wrap-ansi: 8.1.0 - wrap-ansi-cjs: /wrap-ansi@7.0.0 - dev: false + wrap-ansi-cjs: wrap-ansi@7.0.0 - /@isaacs/fs-minipass@4.0.1: - resolution: {integrity: sha512-wgm9Ehl2jpeqP3zw/7mo3kRHFp5MEDhqAdwy1fTGkHAwnkGOVsgpvQhL8B5n1qlb01jV3n/bI0ZfZp5lWA1k4w==} - engines: {node: '>=18.0.0'} + '@isaacs/fs-minipass@4.0.1': dependencies: minipass: 7.0.4 - dev: false - /@istanbuljs/load-nyc-config@1.1.0: - resolution: {integrity: sha512-VjeHSlIzpv/NyD3N0YuHfXOPDIixcA1q2ZV98wsMqcYlPmv2n3Yb2lYP9XMElnaFVXg5A7YLTeLu6V84uQDjmQ==} - engines: {node: '>=8'} + '@istanbuljs/load-nyc-config@1.1.0': dependencies: camelcase: 5.3.1 find-up: 4.1.0 get-package-type: 0.1.0 js-yaml: 3.14.1 resolve-from: 5.0.0 - dev: true - /@istanbuljs/schema@0.1.3: - resolution: {integrity: sha512-ZXRY4jNvVgSVQ8DL3LTcakaAtXwTVUxE81hslsyD2AtoXW/wVob10HkOJ1X/pAlcI7D+2YoZKg5do8G/w6RYgA==} - engines: {node: '>=8'} - dev: true + '@istanbuljs/schema@0.1.3': {} - /@jest/console@29.5.0: - resolution: {integrity: sha512-NEpkObxPwyw/XxZVLPmAGKE89IQRp4puc6IQRPru6JKd1M3fW9v1xM1AnzIJE65hbCkzQAdnL8P47e9hzhiYLQ==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + '@jest/console@29.5.0': dependencies: '@jest/types': 29.6.3 '@types/node': 20.12.7 @@ -6317,11 +14406,8 @@ packages: jest-message-util: 29.7.0 jest-util: 29.7.0 slash: 3.0.0 - dev: true - /@jest/console@29.7.0: - resolution: {integrity: sha512-5Ni4CU7XHQi32IJ398EEP4RrB8eV09sXP2ROqD4bksHrnTree52PsxvX8tpL8LvTZ3pFzXyPbNQReSN41CAhOg==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + '@jest/console@29.7.0': dependencies: '@jest/types': 29.6.3 '@types/node': 20.12.7 @@ -6329,16 +14415,8 @@ packages: jest-message-util: 29.7.0 jest-util: 29.7.0 slash: 3.0.0 - dev: true - /@jest/core@29.7.0(ts-node@10.9.2): - resolution: {integrity: sha512-n7aeXWKMnGtDA48y8TLWJPJmLmmZ642Ceo78cYWEpiD7FzDgmNDV/GCVRorPABdXLJZ/9wzzgZAlHjXjxDHGsg==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - peerDependencies: - node-notifier: ^8.0.1 || ^9.0.0 || ^10.0.0 - peerDependenciesMeta: - node-notifier: - optional: true + '@jest/core@29.7.0(ts-node@10.9.2)': dependencies: '@jest/console': 29.7.0 '@jest/reporters': 29.7.0 @@ -6372,55 +14450,37 @@ packages: - babel-plugin-macros - supports-color - ts-node - dev: true - /@jest/create-cache-key-function@27.5.1: - resolution: {integrity: sha512-dmH1yW+makpTSURTy8VzdUwFnfQh1G8R+DxO2Ho2FFmBbKFEVm+3jWdvFhE2VqB/LATCTokkP0dotjyQyw5/AQ==} - engines: {node: ^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0} + '@jest/create-cache-key-function@27.5.1': dependencies: '@jest/types': 27.5.1 - dev: true - /@jest/environment@29.5.0: - resolution: {integrity: sha512-5FXw2+wD29YU1d4I2htpRX7jYnAyTRjP2CsXQdo9SAM8g3ifxWPSV0HnClSn71xwctr0U3oZIIH+dtbfmnbXVQ==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + '@jest/environment@29.5.0': dependencies: '@jest/fake-timers': 29.5.0 '@jest/types': 29.6.3 '@types/node': 20.12.7 jest-mock: 29.5.0 - dev: true - /@jest/environment@29.7.0: - resolution: {integrity: sha512-aQIfHDq33ExsN4jP1NWGXhxgQ/wixs60gDiKO+XVMd8Mn0NWPWgc34ZQDTb2jKaUWQ7MuwoitXAsN2XVXNMpAw==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + '@jest/environment@29.7.0': dependencies: '@jest/fake-timers': 29.7.0 '@jest/types': 29.6.3 '@types/node': 20.12.7 jest-mock: 29.7.0 - dev: true - /@jest/expect-utils@29.7.0: - resolution: {integrity: sha512-GlsNBWiFQFCVi9QVSx7f5AgMeLxe9YCCs5PuP2O2LdjDAA8Jh9eX7lA1Jq/xdXw3Wb3hyvlFNfZIfcRetSzYcA==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + '@jest/expect-utils@29.7.0': dependencies: jest-get-type: 29.6.3 - dev: true - /@jest/expect@29.7.0: - resolution: {integrity: sha512-8uMeAMycttpva3P1lBHB8VciS9V0XAr3GymPpipdyQXbBcuhkLQOSe8E/p92RyAdToS6ZD1tFkX+CkhoECE0dQ==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + '@jest/expect@29.7.0': dependencies: expect: 29.7.0 jest-snapshot: 29.7.0 transitivePeerDependencies: - supports-color - dev: true - /@jest/fake-timers@29.5.0: - resolution: {integrity: sha512-9ARvuAAQcBwDAqOnglWq2zwNIRUDtk/SCkp/ToGEhFv5r86K21l+VEs0qNTaXtyiY0lEePl3kylijSYJQqdbDg==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + '@jest/fake-timers@29.5.0': dependencies: '@jest/types': 29.6.3 '@sinonjs/fake-timers': 10.3.0 @@ -6428,11 +14488,8 @@ packages: jest-message-util: 29.5.0 jest-mock: 29.5.0 jest-util: 29.5.0 - dev: true - /@jest/fake-timers@29.7.0: - resolution: {integrity: sha512-q4DH1Ha4TTFPdxLsqDXK1d3+ioSL7yL5oCMJZgDYm6i+6CygW5E5xVr/D1HdsGxjt1ZWSfUAs9OxSB/BNelWrQ==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + '@jest/fake-timers@29.7.0': dependencies: '@jest/types': 29.6.3 '@sinonjs/fake-timers': 10.3.0 @@ -6440,11 +14497,8 @@ packages: jest-message-util: 29.7.0 jest-mock: 29.7.0 jest-util: 29.7.0 - dev: true - /@jest/globals@29.7.0: - resolution: {integrity: sha512-mpiz3dutLbkW2MNFubUGUEVLkTGiqW6yLVTA+JbP6fI6J5iL9Y0Nlg8k95pcF8ctKwCS7WVxteBs29hhfAotzQ==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + '@jest/globals@29.7.0': dependencies: '@jest/environment': 29.7.0 '@jest/expect': 29.7.0 @@ -6452,16 +14506,8 @@ packages: jest-mock: 29.7.0 transitivePeerDependencies: - supports-color - dev: true - /@jest/reporters@29.7.0: - resolution: {integrity: sha512-DApq0KJbJOEzAFYjHADNNxAE3KbhxQB1y5Kplb5Waqw6zVbuWatSnMjE5gs8FUgEPmNsnZA3NCWl9NG0ia04Pg==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - peerDependencies: - node-notifier: ^8.0.1 || ^9.0.0 || ^10.0.0 - peerDependenciesMeta: - node-notifier: - optional: true + '@jest/reporters@29.7.0': dependencies: '@bcoe/v8-coverage': 0.2.3 '@jest/console': 29.7.0 @@ -6489,81 +14535,54 @@ packages: v8-to-istanbul: 9.2.0 transitivePeerDependencies: - supports-color - dev: true - /@jest/schemas@29.0.0: - resolution: {integrity: sha512-3Ab5HgYIIAnS0HjqJHQYZS+zXc4tUmTmBH3z83ajI6afXp8X3ZtdLX+nXx+I7LNkJD7uN9LAVhgnjDgZa2z0kA==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + '@jest/schemas@29.0.0': dependencies: '@sinclair/typebox': 0.24.46 - dev: true - /@jest/schemas@29.4.3: - resolution: {integrity: sha512-VLYKXQmtmuEz6IxJsrZwzG9NvtkQsWNnWMsKxqWNu3+CnfzJQhp0WDDKWLVV9hLKr0l3SLLFRqcYHjhtyuDVxg==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + '@jest/schemas@29.4.3': dependencies: '@sinclair/typebox': 0.25.21 - dev: true - /@jest/schemas@29.6.3: - resolution: {integrity: sha512-mo5j5X+jIZmJQveBKeS/clAueipV7KgiX1vMgCxam1RNYiqE1w62n0/tJJnHtjW8ZHcQco5gY85jA3mi0L+nSA==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + '@jest/schemas@29.6.3': dependencies: '@sinclair/typebox': 0.27.8 - dev: true - /@jest/source-map@29.6.3: - resolution: {integrity: sha512-MHjT95QuipcPrpLM+8JMSzFx6eHp5Bm+4XeFDJlwsvVBjmKNiIAvasGK2fxz2WbGRlnvqehFbh07MMa7n3YJnw==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + '@jest/source-map@29.6.3': dependencies: '@jridgewell/trace-mapping': 0.3.25 callsites: 3.1.0 graceful-fs: 4.2.11 - dev: true - /@jest/test-result@29.5.0: - resolution: {integrity: sha512-fGl4rfitnbfLsrfx1uUpDEESS7zM8JdgZgOCQuxQvL1Sn/I6ijeAVQWGfXI9zb1i9Mzo495cIpVZhA0yr60PkQ==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + '@jest/test-result@29.5.0': dependencies: '@jest/console': 29.5.0 '@jest/types': 29.6.3 '@types/istanbul-lib-coverage': 2.0.4 collect-v8-coverage: 1.0.1 - dev: true - /@jest/test-result@29.7.0: - resolution: {integrity: sha512-Fdx+tv6x1zlkJPcWXmMDAG2HBnaR9XPSd5aDWQVsfrZmLVT3lU1cwyxLgRmXR9yrq4NBoEm9BMsfgFzTQAbJYA==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + '@jest/test-result@29.7.0': dependencies: '@jest/console': 29.7.0 '@jest/types': 29.6.3 '@types/istanbul-lib-coverage': 2.0.4 collect-v8-coverage: 1.0.1 - dev: true - /@jest/test-sequencer@29.5.0: - resolution: {integrity: sha512-yPafQEcKjkSfDXyvtgiV4pevSeyuA6MQr6ZIdVkWJly9vkqjnFfcfhRQqpD5whjoU8EORki752xQmjaqoFjzMQ==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + '@jest/test-sequencer@29.5.0': dependencies: '@jest/test-result': 29.5.0 graceful-fs: 4.2.10 jest-haste-map: 29.5.0 slash: 3.0.0 - dev: true - /@jest/test-sequencer@29.7.0: - resolution: {integrity: sha512-GQwJ5WZVrKnOJuiYiAF52UNUJXgTZx1NHjFSEB0qEMmSZKAkdMoIzw/Cj6x6NF4AvV23AUqDpFzQkN/eYCYTxw==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + '@jest/test-sequencer@29.7.0': dependencies: '@jest/test-result': 29.7.0 graceful-fs: 4.2.11 jest-haste-map: 29.7.0 slash: 3.0.0 - dev: true - /@jest/transform@29.7.0: - resolution: {integrity: sha512-ok/BTPFzFKVMwO5eOHRrvnBVHdRy9IrsrW1GpMaQ9MCnilNLXQKmAX8s1YXDFaai9xJpac2ySzV0YeRRECr2Vw==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + '@jest/transform@29.7.0': dependencies: '@babel/core': 7.24.4 '@jest/types': 29.6.3 @@ -6582,22 +14601,16 @@ packages: write-file-atomic: 4.0.2 transitivePeerDependencies: - supports-color - dev: true - /@jest/types@27.5.1: - resolution: {integrity: sha512-Cx46iJ9QpwQTjIdq5VJu2QTMMs3QlEjI0x1QbBP5W1+nMzyc2XmimiRR/CbX9TO0cPTeUlxWMOu8mslYsJ8DEw==} - engines: {node: ^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0} + '@jest/types@27.5.1': dependencies: '@types/istanbul-lib-coverage': 2.0.4 '@types/istanbul-reports': 3.0.1 '@types/node': 20.12.7 '@types/yargs': 16.0.4 chalk: 4.1.2 - dev: true - /@jest/types@29.1.2: - resolution: {integrity: sha512-DcXGtoTykQB5jiwCmVr8H4vdg2OJhQex3qPkG+ISyDO7xQXbt/4R6dowcRyPemRnkH7JoHvZuxPBdlq+9JxFCg==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + '@jest/types@29.1.2': dependencies: '@jest/schemas': 29.0.0 '@types/istanbul-lib-coverage': 2.0.4 @@ -6605,11 +14618,8 @@ packages: '@types/node': 20.12.7 '@types/yargs': 17.0.13 chalk: 4.1.2 - dev: true - - /@jest/types@29.5.0: - resolution: {integrity: sha512-qbu7kN6czmVRc3xWFQcAN03RAUamgppVUdXrvl1Wr3jlNF93o9mJbGcDWrwGB6ht44u7efB1qCFgVQmca24Uog==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + '@jest/types@29.5.0': dependencies: '@jest/schemas': 29.4.3 '@types/istanbul-lib-coverage': 2.0.4 @@ -6617,11 +14627,8 @@ packages: '@types/node': 20.12.7 '@types/yargs': 17.0.13 chalk: 4.1.2 - dev: true - /@jest/types@29.6.3: - resolution: {integrity: sha512-u3UPsIilWKOM3F9CXtrG8LEJmNxwoCQC/XVj4IKYXvvpx7QIi/Kg1LI5uDmDpKlac62NUtX7eLjRh+jVZcLOzw==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + '@jest/types@29.6.3': dependencies: '@jest/schemas': 29.6.3 '@types/istanbul-lib-coverage': 2.0.4 @@ -6629,70 +14636,43 @@ packages: '@types/node': 20.12.7 '@types/yargs': 17.0.13 chalk: 4.1.2 - dev: true - /@jridgewell/gen-mapping@0.3.5: - resolution: {integrity: sha512-IzL8ZoEDIBRWEzlCcRhOaCupYyN5gdIK+Q6fbFdPDg6HqX6jpkItn7DFIpW9LQzXG6Df9sA7+OKnq0qlz/GaQg==} - engines: {node: '>=6.0.0'} + '@jridgewell/gen-mapping@0.3.5': 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: - resolution: {integrity: sha512-F2msla3tad+Mfht5cJq7LSXcdudKTWCVYUgw6pLFOOHSTtZlj6SWNYAp+AhuqLmWdBO2X5hPrLcu8cVP8fy28w==} - engines: {node: '>=6.0.0'} - dev: true + '@jridgewell/resolve-uri@3.1.0': {} - /@jridgewell/set-array@1.2.1: - resolution: {integrity: sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A==} - engines: {node: '>=6.0.0'} - dev: true + '@jridgewell/set-array@1.2.1': {} - /@jridgewell/sourcemap-codec@1.4.14: - resolution: {integrity: sha512-XPSJHWmi394fuUuzDnGz1wiKqWfo1yXecHQMRf2l6hztTO+nPru658AyDngaBe7isIxEkRsPR3FZh+s7iVa4Uw==} - dev: true + '@jridgewell/sourcemap-codec@1.4.14': {} - /@jridgewell/sourcemap-codec@1.4.15: - resolution: {integrity: sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==} - dev: true + '@jridgewell/sourcemap-codec@1.4.15': {} - /@jridgewell/trace-mapping@0.3.18: - resolution: {integrity: sha512-w+niJYzMHdd7USdiH2U6869nqhD2nbfZXND5Yp93qIbEmnDNk7PD48o+YchRVpzMU7M6jVCbenTR7PA1FLQ9pA==} + '@jridgewell/trace-mapping@0.3.18': dependencies: '@jridgewell/resolve-uri': 3.1.0 '@jridgewell/sourcemap-codec': 1.4.14 - dev: true - /@jridgewell/trace-mapping@0.3.25: - resolution: {integrity: sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==} + '@jridgewell/trace-mapping@0.3.25': dependencies: '@jridgewell/resolve-uri': 3.1.0 '@jridgewell/sourcemap-codec': 1.4.15 - dev: true - /@jridgewell/trace-mapping@0.3.9: - resolution: {integrity: sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==} + '@jridgewell/trace-mapping@0.3.9': dependencies: '@jridgewell/resolve-uri': 3.1.0 '@jridgewell/sourcemap-codec': 1.4.15 - dev: true - /@jsdevtools/ono@7.1.3: - resolution: {integrity: sha512-4JQNk+3mVzK3xh2rqd6RB4J46qUR19azEHBneZyTZM+c456qOrbbM/5xcR8huNCCcbVt7+UmizG6GuUvPvKUYg==} - dev: true + '@jsdevtools/ono@7.1.3': {} - /@koa/cors@5.0.0: - resolution: {integrity: sha512-x/iUDjcS90W69PryLDIMgFyV21YLTnG9zOpPXS7Bkt2b8AsY3zZsIpOLBkYr9fBcF3HbkKaER5hOBZLfpLgYNw==} - engines: {node: '>= 14.0.0'} + '@koa/cors@5.0.0': dependencies: vary: 1.1.2 - dev: false - /@koa/router@12.0.1: - resolution: {integrity: sha512-ribfPYfHb+Uw3b27Eiw6NPqjhIhTpVFzEWLwyc/1Xp+DCdwRRyIlAUODX+9bPARF6aQtUu1+/PHzdNvRzcs/+Q==} - engines: {node: '>= 12'} + '@koa/router@12.0.1': dependencies: debug: 4.3.4 http-errors: 2.0.0 @@ -6701,137 +14681,81 @@ packages: path-to-regexp: 6.2.1 transitivePeerDependencies: - supports-color - dev: false - /@lezer/common@0.15.12: - resolution: {integrity: sha512-edfwCxNLnzq5pBA/yaIhwJ3U3Kz8VAUOTRg0hhxaizaI1N+qxV7EXDv/kLCkLeq2RzSFvxexlaj5Mzfn2kY0Ig==} - dev: true + '@lezer/common@0.15.12': {} - /@lezer/lr@0.15.8: - resolution: {integrity: sha512-bM6oE6VQZ6hIFxDNKk8bKPa14hqFrV07J/vHGOeiAbJReIaQXmkVb6xQu4MR+JBTLa5arGRyAAjJe1qaQt3Uvg==} + '@lezer/lr@0.15.8': dependencies: '@lezer/common': 0.15.12 - dev: true - /@lmdb/lmdb-darwin-arm64@2.7.11: - resolution: {integrity: sha512-r6+vYq2vKzE+vgj/rNVRMwAevq0+ZR9IeMFIqcSga+wMtMdXQ27KqQ7uS99/yXASg29bos7yHP3yk4x6Iio0lw==} - cpu: [arm64] - os: [darwin] - requiresBuild: true - dev: true + '@lmdb/lmdb-darwin-arm64@2.7.11': optional: true - /@lmdb/lmdb-darwin-x64@2.7.11: - resolution: {integrity: sha512-jhj1aB4K8ycRL1HOQT5OtzlqOq70jxUQEWRN9Gqh3TIDN30dxXtiHi6EWF516tzw6v2+3QqhDMJh8O6DtTGG8Q==} - cpu: [x64] - os: [darwin] - requiresBuild: true - dev: true + '@lmdb/lmdb-darwin-x64@2.7.11': optional: true - /@lmdb/lmdb-linux-arm64@2.7.11: - resolution: {integrity: sha512-7xGEfPPbmVJWcY2Nzqo11B9Nfxs+BAsiiaY/OcT4aaTDdykKeCjvKMQJA3KXCtZ1AtiC9ljyGLi+BfUwdulY5A==} - cpu: [arm64] - os: [linux] - requiresBuild: true - dev: true + '@lmdb/lmdb-linux-arm64@2.7.11': optional: true - /@lmdb/lmdb-linux-arm@2.7.11: - resolution: {integrity: sha512-dHfLFVSrw/v5X5lkwp0Vl7+NFpEeEYKfMG2DpdFJnnG1RgHQZngZxCaBagFoaJGykRpd2DYF1AeuXBFrAUAXfw==} - cpu: [arm] - os: [linux] - requiresBuild: true - dev: true + '@lmdb/lmdb-linux-arm@2.7.11': optional: true - /@lmdb/lmdb-linux-x64@2.7.11: - resolution: {integrity: sha512-vUKI3JrREMQsXX8q0Eq5zX2FlYCKWMmLiCyyJNfZK0Uyf14RBg9VtB3ObQ41b4swYh2EWaltasWVe93Y8+KDng==} - cpu: [x64] - os: [linux] - requiresBuild: true - dev: true + '@lmdb/lmdb-linux-x64@2.7.11': optional: true - /@lmdb/lmdb-win32-x64@2.7.11: - resolution: {integrity: sha512-BJwkHlSUgtB+Ei52Ai32M1AOMerSlzyIGA/KC4dAGL+GGwVMdwG8HGCOA2TxP3KjhbgDPMYkv7bt/NmOmRIFng==} - cpu: [x64] - os: [win32] - requiresBuild: true - dev: true + '@lmdb/lmdb-win32-x64@2.7.11': optional: true - /@logto/affiliate@0.1.0: - resolution: {integrity: sha512-yDWSZMI2Qo/xoYU92tnwSP/gnSvq8+CLK5DqD/4brO42QJa7xjt7eA+HSyuMmSUrKffY2nP3riU81gs+nR8DkA==} - engines: {node: ^18.12.0} + '@logto/affiliate@0.1.0': dependencies: '@silverhand/essentials': 2.9.0 tiny-cookie: 2.4.1 - dev: false - /@logto/browser@2.2.10: - resolution: {integrity: sha512-y6NauaxctqpfApccP6uFVmpg/vG1OhsDVLD4Pdpzbmj3whl63Nb17yxSTQHt4eYNKmSZJ2SzudAnMnVEYD91iQ==} + '@logto/browser@2.2.10': dependencies: '@logto/client': 2.6.6 '@silverhand/essentials': 2.9.0 js-base64: 3.7.5 - dev: true - /@logto/client@2.6.6: - resolution: {integrity: sha512-QT7jMnzEIWHBNrf9/M8p1OErRBbbNZjoekXGji5aZCyUh975hh8+GEBL21HV71FT3H/5Cq4Gf1GzUbAIW3izMA==} + '@logto/client@2.6.6': dependencies: '@logto/js': 4.1.1 '@silverhand/essentials': 2.9.0 camelcase-keys: 7.0.2 jose: 5.2.2 - dev: true - /@logto/cloud@0.2.5-e5d8200(zod@3.22.4): - resolution: {integrity: sha512-/ZPaiIU7ORfKtNqsopVg4jxDt/sM6CGAGny06ppv/2FNsL7h8rX6JXOUyyKmT6ffCh/K/5s2HZe7v86zx5gENQ==} - engines: {node: ^20.9.0} + '@logto/cloud@0.2.5-e5d8200(zod@3.22.4)': dependencies: '@silverhand/essentials': 2.9.0 '@withtyped/server': 0.13.6(zod@3.22.4) transitivePeerDependencies: - zod - dev: true - /@logto/js@4.1.1: - resolution: {integrity: sha512-+RgthBvDw30UojirtAjZeHNfOwDQVURmpjcIBYTIf6afx5F5jJq8b1D/eaFbrCFrmXmatkT2iN7X8kYHui86WQ==} + '@logto/js@4.1.1': dependencies: '@silverhand/essentials': 2.9.0 camelcase-keys: 7.0.2 - dev: true - /@logto/node@2.4.7: - resolution: {integrity: sha512-AlANeqY1NIt93EBcRzrTmyAVHXOHpszTJK+qe1ok50rmZlTmX2p7yQvrg0/Ehwf/+4Rla5vooAR+HIFMaOmPpQ==} + '@logto/node@2.4.7': dependencies: '@logto/client': 2.6.6 '@silverhand/essentials': 2.9.0 js-base64: 3.7.5 - dev: true - /@logto/react@3.0.8(react@18.2.0): - resolution: {integrity: sha512-p3pV4rX4g8ZwHQ159mxI+pP3Bwome47dNEmP1hI8/10WqdIPXGYTnfYn5c2l4Y2DyslYyK3ur2Sy4i4K6ept9A==} - peerDependencies: - react: '>=16.8.0 || ^18.0.0' + '@logto/react@3.0.8(react@18.2.0)': dependencies: '@logto/browser': 2.2.10 '@silverhand/essentials': 2.9.0 react: 18.2.0 - dev: true - /@manypkg/find-root@1.1.0: - resolution: {integrity: sha512-mki5uBvhHzO8kYYix/WRy2WX8S3B5wdVSc9D6KcU5lQNglP2yt58/VfLuAK49glRXChosY8ap2oJ1qgma3GUVA==} + '@manypkg/find-root@1.1.0': dependencies: '@babel/runtime': 7.21.0 '@types/node': 12.20.55 find-up: 4.1.0 fs-extra: 8.1.0 - dev: true - /@manypkg/get-packages@1.1.3: - resolution: {integrity: sha512-fo+QhuU3qE/2TQMQmbVMqaQ6EWbMhi4ABWP+O4AM1NqPBuy0OrApV5LO6BrrgnhtAHS2NH6RrVk9OL181tTi8A==} + '@manypkg/get-packages@1.1.3': dependencies: '@babel/runtime': 7.21.0 '@changesets/types': 4.1.0 @@ -6839,10 +14763,8 @@ packages: fs-extra: 8.1.0 globby: 11.1.0 read-yaml-file: 1.1.0 - dev: true - /@mdx-js/mdx@1.6.22: - resolution: {integrity: sha512-AMxuLxPz2j5/6TpF/XSdKpQP1NlG0z11dFOlq+2IP/lSgl11GY8ji6S/rgsViN/L0BDvHvUMruRb7ub+24LUYA==} + '@mdx-js/mdx@1.6.22': dependencies: '@babel/core': 7.12.9 '@babel/plugin-syntax-jsx': 7.12.1(@babel/core@7.12.9) @@ -6865,144 +14787,71 @@ packages: unist-util-visit: 2.0.3 transitivePeerDependencies: - supports-color - dev: true - /@mdx-js/react@1.6.22(react@18.2.0): - resolution: {integrity: sha512-TDoPum4SHdfPiGSAaRBw7ECyI8VaHpK8GJugbJIJuqyh6kzw9ZLJZW3HGL3NNrJGxcAixUvqROm+YuQOo5eXtg==} - peerDependencies: - react: ^16.13.1 || ^17.0.0 || ^18.0.0 + '@mdx-js/react@1.6.22(react@18.2.0)': dependencies: react: 18.2.0 - dev: true - /@mdx-js/util@1.6.22: - resolution: {integrity: sha512-H1rQc1ZOHANWBvPcW+JpGwr+juXSxM8Q8YCkm3GhZd8REu1fHR3z99CErO1p9pkcfcxZnMdIZdIsXkOHY0NilA==} - dev: true + '@mdx-js/util@1.6.22': {} - /@microsoft/applicationinsights-web-snippet@1.0.1: - resolution: {integrity: sha512-2IHAOaLauc8qaAitvWS+U931T+ze+7MNWrDHY47IENP5y2UA0vqJDu67kWZDdpCN1fFC77sfgfB+HV7SrKshnQ==} - dev: false + '@microsoft/applicationinsights-web-snippet@1.0.1': {} - /@mischnic/json-sourcemap@0.1.0: - resolution: {integrity: sha512-dQb3QnfNqmQNYA4nFSN/uLaByIic58gOXq4Y4XqLOWmOrw73KmJPt/HLyG0wvn1bnR6mBKs/Uwvkh+Hns1T0XA==} - engines: {node: '>=12.0.0'} + '@mischnic/json-sourcemap@0.1.0': dependencies: '@lezer/common': 0.15.12 '@lezer/lr': 0.15.8 json5: 2.2.3 - dev: true - /@monaco-editor/loader@1.4.0(monaco-editor@0.47.0): - resolution: {integrity: sha512-00ioBig0x642hytVspPl7DbQyaSWRaolYie/UFNjoTdvoKPzo6xrXLhTk9ixgIKcLH5b5vDOjVNiGyY+uDCUlg==} - peerDependencies: - monaco-editor: '>= 0.21.0 < 1' + '@monaco-editor/loader@1.4.0(monaco-editor@0.47.0)': dependencies: monaco-editor: 0.47.0 state-local: 1.0.7 - dev: true - /@monaco-editor/react@4.6.0(monaco-editor@0.47.0)(react-dom@18.2.0)(react@18.2.0): - resolution: {integrity: sha512-RFkU9/i7cN2bsq/iTkurMWOEErmYcY6JiQI3Jn+WeR/FGISH8JbHERjpS9oRuSOPvDMJI0Z8nJeKkbOs9sBYQw==} - peerDependencies: - monaco-editor: '>= 0.25.0 < 1' - react: ^16.8.0 || ^17.0.0 || ^18.0.0 - react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0 + '@monaco-editor/react@4.6.0(monaco-editor@0.47.0)(react-dom@18.2.0)(react@18.2.0)': dependencies: '@monaco-editor/loader': 1.4.0(monaco-editor@0.47.0) monaco-editor: 0.47.0 react: 18.2.0 react-dom: 18.2.0(react@18.2.0) - dev: true - /@msgpackr-extract/msgpackr-extract-darwin-arm64@3.0.2: - resolution: {integrity: sha512-9bfjwDxIDWmmOKusUcqdS4Rw+SETlp9Dy39Xui9BEGEk19dDwH0jhipwFzEff/pFg95NKymc6TOTbRKcWeRqyQ==} - cpu: [arm64] - os: [darwin] - requiresBuild: true - dev: true + '@msgpackr-extract/msgpackr-extract-darwin-arm64@3.0.2': optional: true - /@msgpackr-extract/msgpackr-extract-darwin-x64@3.0.2: - resolution: {integrity: sha512-lwriRAHm1Yg4iDf23Oxm9n/t5Zpw1lVnxYU3HnJPTi2lJRkKTrps1KVgvL6m7WvmhYVt/FIsssWay+k45QHeuw==} - cpu: [x64] - os: [darwin] - requiresBuild: true - dev: true + '@msgpackr-extract/msgpackr-extract-darwin-x64@3.0.2': optional: true - /@msgpackr-extract/msgpackr-extract-linux-arm64@3.0.2: - resolution: {integrity: sha512-FU20Bo66/f7He9Fp9sP2zaJ1Q8L9uLPZQDub/WlUip78JlPeMbVL8546HbZfcW9LNciEXc8d+tThSJjSC+tmsg==} - cpu: [arm64] - os: [linux] - requiresBuild: true - dev: true + '@msgpackr-extract/msgpackr-extract-linux-arm64@3.0.2': optional: true - /@msgpackr-extract/msgpackr-extract-linux-arm@3.0.2: - resolution: {integrity: sha512-MOI9Dlfrpi2Cuc7i5dXdxPbFIgbDBGgKR5F2yWEa6FVEtSWncfVNKW5AKjImAQ6CZlBK9tympdsZJ2xThBiWWA==} - cpu: [arm] - os: [linux] - requiresBuild: true - dev: true + '@msgpackr-extract/msgpackr-extract-linux-arm@3.0.2': optional: true - /@msgpackr-extract/msgpackr-extract-linux-x64@3.0.2: - resolution: {integrity: sha512-gsWNDCklNy7Ajk0vBBf9jEx04RUxuDQfBse918Ww+Qb9HCPoGzS+XJTLe96iN3BVK7grnLiYghP/M4L8VsaHeA==} - cpu: [x64] - os: [linux] - requiresBuild: true - dev: true + '@msgpackr-extract/msgpackr-extract-linux-x64@3.0.2': optional: true - /@msgpackr-extract/msgpackr-extract-win32-x64@3.0.2: - resolution: {integrity: sha512-O+6Gs8UeDbyFpbSh2CPEz/UOrrdWPTBYNblZK5CxxLisYt4kGX3Sc+czffFonyjiGSq3jWLwJS/CCJc7tBr4sQ==} - cpu: [x64] - os: [win32] - requiresBuild: true - dev: true + '@msgpackr-extract/msgpackr-extract-win32-x64@3.0.2': optional: true - /@nodelib/fs.scandir@2.1.5: - resolution: {integrity: sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==} - engines: {node: '>= 8'} + '@nodelib/fs.scandir@2.1.5': dependencies: '@nodelib/fs.stat': 2.0.5 run-parallel: 1.2.0 - dev: true - /@nodelib/fs.stat@2.0.5: - resolution: {integrity: sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==} - engines: {node: '>= 8'} - dev: true + '@nodelib/fs.stat@2.0.5': {} - /@nodelib/fs.walk@1.2.8: - resolution: {integrity: sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==} - engines: {node: '>= 8'} + '@nodelib/fs.walk@1.2.8': dependencies: '@nodelib/fs.scandir': 2.1.5 fastq: 1.13.0 - dev: true - /@opentelemetry/api@1.8.0: - resolution: {integrity: sha512-I/s6F7yKUDdtMsoBWXJe8Qz40Tui5vsuKCWJEWVL+5q9sSWRzzx6v2KeNsOBEwd94j0eWkpWCH4yB6rZg9Mf0w==} - engines: {node: '>=8.0.0'} - dev: false + '@opentelemetry/api@1.8.0': {} - /@opentelemetry/core@1.23.0(@opentelemetry/api@1.8.0): - resolution: {integrity: sha512-hdQ/a9TMzMQF/BO8Cz1juA43/L5YGtCSiKoOHmrTEf7VMDAZgy8ucpWx3eQTnQ3gBloRcWtzvcrMZABC3PTSKQ==} - engines: {node: '>=14'} - peerDependencies: - '@opentelemetry/api': '>=1.0.0 <1.9.0' + '@opentelemetry/core@1.23.0(@opentelemetry/api@1.8.0)': dependencies: '@opentelemetry/api': 1.8.0 '@opentelemetry/semantic-conventions': 1.23.0 - dev: false - /@opentelemetry/instrumentation@0.41.2(@opentelemetry/api@1.8.0): - resolution: {integrity: sha512-rxU72E0pKNH6ae2w5+xgVYZLzc5mlxAbGzF4shxMVK8YC2QQsfN38B2GPbj0jvrKWWNUElfclQ+YTykkNg/grw==} - engines: {node: '>=14'} - peerDependencies: - '@opentelemetry/api': ^1.3.0 + '@opentelemetry/instrumentation@0.41.2(@opentelemetry/api@1.8.0)': dependencies: '@opentelemetry/api': 1.8.0 '@types/shimmer': 1.0.2 @@ -7012,72 +14861,46 @@ packages: shimmer: 1.2.1 transitivePeerDependencies: - supports-color - dev: false - /@opentelemetry/resources@1.23.0(@opentelemetry/api@1.8.0): - resolution: {integrity: sha512-iPRLfVfcEQynYGo7e4Di+ti+YQTAY0h5mQEUJcHlU9JOqpb4x965O6PZ+wMcwYVY63G96KtdS86YCM1BF1vQZg==} - engines: {node: '>=14'} - peerDependencies: - '@opentelemetry/api': '>=1.0.0 <1.9.0' + '@opentelemetry/resources@1.23.0(@opentelemetry/api@1.8.0)': dependencies: '@opentelemetry/api': 1.8.0 '@opentelemetry/core': 1.23.0(@opentelemetry/api@1.8.0) '@opentelemetry/semantic-conventions': 1.23.0 - dev: false - /@opentelemetry/sdk-trace-base@1.23.0(@opentelemetry/api@1.8.0): - resolution: {integrity: sha512-PzBmZM8hBomUqvCddF/5Olyyviayka44O5nDWq673np3ctnvwMOvNrsUORZjKja1zJbwEuD9niAGbnVrz3jwRQ==} - engines: {node: '>=14'} - peerDependencies: - '@opentelemetry/api': '>=1.0.0 <1.9.0' + '@opentelemetry/sdk-trace-base@1.23.0(@opentelemetry/api@1.8.0)': dependencies: '@opentelemetry/api': 1.8.0 '@opentelemetry/core': 1.23.0(@opentelemetry/api@1.8.0) '@opentelemetry/resources': 1.23.0(@opentelemetry/api@1.8.0) '@opentelemetry/semantic-conventions': 1.23.0 - dev: false - /@opentelemetry/semantic-conventions@1.23.0: - resolution: {integrity: sha512-MiqFvfOzfR31t8cc74CTP1OZfz7MbqpAnLCra8NqQoaHJX6ncIRTdYOQYBDQ2uFISDq0WY8Y9dDTWvsgzzBYRg==} - engines: {node: '>=14'} - dev: false + '@opentelemetry/semantic-conventions@1.23.0': {} - /@otplib/core@12.0.1: - resolution: {integrity: sha512-4sGntwbA/AC+SbPhbsziRiD+jNDdIzsZ3JUyfZwjtKyc/wufl1pnSIaG4Uqx8ymPagujub0o92kgBnB89cuAMA==} - dev: false + '@otplib/core@12.0.1': {} - /@otplib/plugin-crypto@12.0.1: - resolution: {integrity: sha512-qPuhN3QrT7ZZLcLCyKOSNhuijUi9G5guMRVrxq63r9YNOxxQjPm59gVxLM+7xGnHnM6cimY57tuKsjK7y9LM1g==} + '@otplib/plugin-crypto@12.0.1': dependencies: '@otplib/core': 12.0.1 - dev: false - /@otplib/plugin-thirty-two@12.0.1: - resolution: {integrity: sha512-MtT+uqRso909UkbrrYpJ6XFjj9D+x2Py7KjTO9JDPhL0bJUYVu5kFP4TFZW4NFAywrAtFRxOVY261u0qwb93gA==} + '@otplib/plugin-thirty-two@12.0.1': dependencies: '@otplib/core': 12.0.1 thirty-two: 1.0.2 - dev: false - /@otplib/preset-default@12.0.1: - resolution: {integrity: sha512-xf1v9oOJRyXfluBhMdpOkr+bsE+Irt+0D5uHtvg6x1eosfmHCsCC6ej/m7FXiWqdo0+ZUI6xSKDhJwc8yfiOPQ==} + '@otplib/preset-default@12.0.1': dependencies: '@otplib/core': 12.0.1 '@otplib/plugin-crypto': 12.0.1 '@otplib/plugin-thirty-two': 12.0.1 - dev: false - /@otplib/preset-v11@12.0.1: - resolution: {integrity: sha512-9hSetMI7ECqbFiKICrNa4w70deTUfArtwXykPUvSHWOdzOlfa9ajglu7mNCntlvxycTiOAXkQGwjQCzzDEMRMg==} + '@otplib/preset-v11@12.0.1': dependencies: '@otplib/core': 12.0.1 '@otplib/plugin-crypto': 12.0.1 '@otplib/plugin-thirty-two': 12.0.1 - dev: false - /@parcel/bundler-default@2.9.3(@parcel/core@2.9.3): - resolution: {integrity: sha512-JjJK8dq39/UO/MWI/4SCbB1t/qgpQRFnFDetAAAezQ8oN++b24u1fkMDa/xqQGjbuPmGeTds5zxGgYs7id7PYg==} - engines: {node: '>= 12.0.0', parcel: ^2.9.3} + '@parcel/bundler-default@2.9.3(@parcel/core@2.9.3)': dependencies: '@parcel/diagnostic': 2.9.3 '@parcel/graph': 2.9.3 @@ -7087,59 +14910,38 @@ packages: nullthrows: 1.1.1 transitivePeerDependencies: - '@parcel/core' - dev: true - /@parcel/cache@2.9.3(@parcel/core@2.9.3): - resolution: {integrity: sha512-Bj/H2uAJJSXtysG7E/x4EgTrE2hXmm7td/bc97K8M9N7+vQjxf7xb0ebgqe84ePVMkj4MVQSMEJkEucXVx4b0Q==} - engines: {node: '>= 12.0.0'} - peerDependencies: - '@parcel/core': ^2.9.3 + '@parcel/cache@2.9.3(@parcel/core@2.9.3)': dependencies: '@parcel/core': 2.9.3 '@parcel/fs': 2.9.3(@parcel/core@2.9.3) '@parcel/logger': 2.9.3 '@parcel/utils': 2.9.3 lmdb: 2.7.11 - dev: true - /@parcel/codeframe@2.9.3: - resolution: {integrity: sha512-z7yTyD6h3dvduaFoHpNqur74/2yDWL++33rjQjIjCaXREBN6dKHoMGMizzo/i4vbiI1p9dDox2FIDEHCMQxqdA==} - engines: {node: '>= 12.0.0'} + '@parcel/codeframe@2.9.3': dependencies: chalk: 4.1.2 - dev: true - /@parcel/compressor-brotli@2.9.3(@parcel/core@2.9.3): - resolution: {integrity: sha512-yLxTous+fPIaw8v8kR5UdWLzJTL7e3ISThNWsu9w9L4vqK0DUUIUePvwZjSNiYQcxFu9L/1X3vlKSzHv3TvS0Q==} - engines: {node: '>= 12.0.0', parcel: ^2.9.3} + '@parcel/compressor-brotli@2.9.3(@parcel/core@2.9.3)': dependencies: '@parcel/plugin': 2.9.3(@parcel/core@2.9.3) transitivePeerDependencies: - '@parcel/core' - dev: true - /@parcel/compressor-gzip@2.9.3(@parcel/core@2.9.3): - resolution: {integrity: sha512-ffQDpPlr3XzqDa/Gwgj7kFPMKYPHnpTZCYnoFW0zzHJTI0umDUULb2XHRke804yiHplKA6fcj2TQjC5FU1beYw==} - engines: {node: '>= 12.0.0', parcel: ^2.9.3} + '@parcel/compressor-gzip@2.9.3(@parcel/core@2.9.3)': dependencies: '@parcel/plugin': 2.9.3(@parcel/core@2.9.3) transitivePeerDependencies: - '@parcel/core' - dev: true - /@parcel/compressor-raw@2.9.3(@parcel/core@2.9.3): - resolution: {integrity: sha512-jz3t4/ICMsHEqgiTmv5i1DJva2k5QRpZlBELVxfY+QElJTVe8edKJ0TiKcBxh2hx7sm4aUigGmp7JiqqHRRYmA==} - engines: {node: '>= 12.0.0', parcel: ^2.9.3} + '@parcel/compressor-raw@2.9.3(@parcel/core@2.9.3)': dependencies: '@parcel/plugin': 2.9.3(@parcel/core@2.9.3) transitivePeerDependencies: - '@parcel/core' - dev: true - /@parcel/config-default@2.9.3(@parcel/core@2.9.3)(postcss@8.4.31): - resolution: {integrity: sha512-tqN5tF7QnVABDZAu76co5E6N8mA9n8bxiWdK4xYyINYFIEHgX172oRTqXTnhEMjlMrdmASxvnGlbaPBaVnrCTw==} - peerDependencies: - '@parcel/core': ^2.9.3 + '@parcel/config-default@2.9.3(@parcel/core@2.9.3)(postcss@8.4.31)': dependencies: '@parcel/bundler-default': 2.9.3(@parcel/core@2.9.3) '@parcel/compressor-raw': 2.9.3(@parcel/core@2.9.3) @@ -7181,11 +14983,8 @@ packages: - srcset - terser - uncss - dev: true - /@parcel/core@2.9.3: - resolution: {integrity: sha512-4KlM1Zr/jpsqWuMXr2zmGsaOUs1zMMFh9vfCNKRZkptf+uk8I3sugHbNdo+F5B+4e2yMuOEb1zgAmvJLeuH6ww==} - engines: {node: '>= 12.0.0'} + '@parcel/core@2.9.3': dependencies: '@mischnic/json-sourcemap': 0.1.0 '@parcel/cache': 2.9.3(@parcel/core@2.9.3) @@ -7212,31 +15011,17 @@ packages: msgpackr: 1.8.5 nullthrows: 1.1.1 semver: 7.6.0 - dev: true - /@parcel/diagnostic@2.9.3: - resolution: {integrity: sha512-6jxBdyB3D7gP4iE66ghUGntWt2v64E6EbD4AetZk+hNJpgudOOPsKTovcMi/i7I4V0qD7WXSF4tvkZUoac0jwA==} - engines: {node: '>= 12.0.0'} + '@parcel/diagnostic@2.9.3': dependencies: '@mischnic/json-sourcemap': 0.1.0 nullthrows: 1.1.1 - dev: true - /@parcel/events@2.9.3: - resolution: {integrity: sha512-K0Scx+Bx9f9p1vuShMzNwIgiaZUkxEnexaKYHYemJrM7pMAqxIuIqhnvwurRCsZOVLUJPDDNJ626cWTc5vIq+A==} - engines: {node: '>= 12.0.0'} - dev: true + '@parcel/events@2.9.3': {} - /@parcel/fs-search@2.9.3: - resolution: {integrity: sha512-nsNz3bsOpwS+jphcd+XjZL3F3PDq9lik0O8HPm5f6LYkqKWT+u/kgQzA8OkAHCR3q96LGiHxUywHPEBc27vI4Q==} - engines: {node: '>= 12.0.0'} - dev: true + '@parcel/fs-search@2.9.3': {} - /@parcel/fs@2.9.3(@parcel/core@2.9.3): - resolution: {integrity: sha512-/PrRKgCRw22G7rNPSpgN3Q+i2nIkZWuvIOAdMG4KWXC4XLp8C9jarNaWd5QEQ75amjhQSl3oUzABzkdCtkKrgg==} - engines: {node: '>= 12.0.0'} - peerDependencies: - '@parcel/core': ^2.9.3 + '@parcel/fs@2.9.3(@parcel/core@2.9.3)': dependencies: '@parcel/core': 2.9.3 '@parcel/fs-search': 2.9.3 @@ -7244,51 +15029,33 @@ packages: '@parcel/utils': 2.9.3 '@parcel/watcher': 2.0.7 '@parcel/workers': 2.9.3(@parcel/core@2.9.3) - dev: true - /@parcel/graph@2.9.3: - resolution: {integrity: sha512-3LmRJmF8+OprAr6zJT3X2s8WAhLKkrhi6RsFlMWHifGU5ED1PFcJWFbOwJvSjcAhMQJP0fErcFIK1Ludv3Vm3g==} - engines: {node: '>= 12.0.0'} + '@parcel/graph@2.9.3': dependencies: nullthrows: 1.1.1 - dev: true - /@parcel/hash@2.9.3: - resolution: {integrity: sha512-qlH5B85XLzVAeijgKPjm1gQu35LoRYX/8igsjnN8vOlbc3O8BYAUIutU58fbHbtE8MJPbxQQUw7tkTjeoujcQQ==} - engines: {node: '>= 12.0.0'} + '@parcel/hash@2.9.3': dependencies: xxhash-wasm: 0.4.2 - dev: true - /@parcel/logger@2.9.3: - resolution: {integrity: sha512-5FNBszcV6ilGFcijEOvoNVG6IUJGsnMiaEnGQs7Fvc1dktTjEddnoQbIYhcSZL63wEmzBZOgkT5yDMajJ/41jw==} - engines: {node: '>= 12.0.0'} + '@parcel/logger@2.9.3': dependencies: '@parcel/diagnostic': 2.9.3 '@parcel/events': 2.9.3 - dev: true - /@parcel/markdown-ansi@2.9.3: - resolution: {integrity: sha512-/Q4X8F2aN8UNjAJrQ5NfK2OmZf6shry9DqetUSEndQ0fHonk78WKt6LT0zSKEBEW/bB/bXk6mNMsCup6L8ibjQ==} - engines: {node: '>= 12.0.0'} + '@parcel/markdown-ansi@2.9.3': dependencies: chalk: 4.1.2 - dev: true - /@parcel/namer-default@2.9.3(@parcel/core@2.9.3): - resolution: {integrity: sha512-1ynFEcap48/Ngzwwn318eLYpLUwijuuZoXQPCsEQ21OOIOtfhFQJaPwXTsw6kRitshKq76P2aafE0BioGSqxcA==} - engines: {node: '>= 12.0.0', parcel: ^2.9.3} + '@parcel/namer-default@2.9.3(@parcel/core@2.9.3)': dependencies: '@parcel/diagnostic': 2.9.3 '@parcel/plugin': 2.9.3(@parcel/core@2.9.3) nullthrows: 1.1.1 transitivePeerDependencies: - '@parcel/core' - dev: true - /@parcel/node-resolver-core@3.0.3(@parcel/core@2.9.3): - resolution: {integrity: sha512-AjxNcZVHHJoNT/A99PKIdFtwvoze8PAiC3yz8E/dRggrDIOboUEodeQYV5Aq++aK76uz/iOP0tST2T8A5rhb1A==} - engines: {node: '>= 12.0.0'} + '@parcel/node-resolver-core@3.0.3(@parcel/core@2.9.3)': dependencies: '@mischnic/json-sourcemap': 0.1.0 '@parcel/diagnostic': 2.9.3 @@ -7298,11 +15065,8 @@ packages: semver: 7.6.0 transitivePeerDependencies: - '@parcel/core' - dev: true - /@parcel/optimizer-css@2.9.3(@parcel/core@2.9.3): - resolution: {integrity: sha512-RK1QwcSdWDNUsFvuLy0hgnYKtPQebzCb0vPPzqs6LhL+vqUu9utOyRycGaQffHCkHVQP6zGlN+KFssd7YtFGhA==} - engines: {node: '>= 12.0.0', parcel: ^2.9.3} + '@parcel/optimizer-css@2.9.3(@parcel/core@2.9.3)': dependencies: '@parcel/diagnostic': 2.9.3 '@parcel/plugin': 2.9.3(@parcel/core@2.9.3) @@ -7313,11 +15077,8 @@ packages: nullthrows: 1.1.1 transitivePeerDependencies: - '@parcel/core' - dev: true - /@parcel/optimizer-htmlnano@2.9.3(@parcel/core@2.9.3)(postcss@8.4.31): - resolution: {integrity: sha512-9g/KBck3c6DokmJfvJ5zpHFBiCSolaGrcsTGx8C3YPdCTVTI9P1TDCwUxvAr4LjpcIRSa82wlLCI+nF6sSgxKA==} - engines: {node: '>= 12.0.0', parcel: ^2.9.3} + '@parcel/optimizer-htmlnano@2.9.3(@parcel/core@2.9.3)(postcss@8.4.31)': dependencies: '@parcel/plugin': 2.9.3(@parcel/core@2.9.3) htmlnano: 2.0.3(postcss@8.4.31)(svgo@2.8.0) @@ -7333,24 +15094,16 @@ packages: - srcset - terser - uncss - dev: true - /@parcel/optimizer-image@2.9.3(@parcel/core@2.9.3): - resolution: {integrity: sha512-530YzthE7kmecnNhPbkAK+26yQNt69pfJrgE0Ev0BZaM1Wu2+33nki7o8qvkTkikhPrurEJLGIXt1qKmbKvCbA==} - engines: {node: '>= 12.0.0', parcel: ^2.9.3} - peerDependencies: - '@parcel/core': ^2.9.3 + '@parcel/optimizer-image@2.9.3(@parcel/core@2.9.3)': dependencies: '@parcel/core': 2.9.3 '@parcel/diagnostic': 2.9.3 '@parcel/plugin': 2.9.3(@parcel/core@2.9.3) '@parcel/utils': 2.9.3 '@parcel/workers': 2.9.3(@parcel/core@2.9.3) - dev: true - /@parcel/optimizer-svgo@2.9.3(@parcel/core@2.9.3): - resolution: {integrity: sha512-ytQS0wY5JJhWU4mL0wfhYDUuHcfuw+Gy2+JcnTm1t1AZXHlOTbU6EzRWNqBShsgXjvdrQQXizAe3B6GFFlFJVQ==} - engines: {node: '>= 12.0.0', parcel: ^2.9.3} + '@parcel/optimizer-svgo@2.9.3(@parcel/core@2.9.3)': dependencies: '@parcel/diagnostic': 2.9.3 '@parcel/plugin': 2.9.3(@parcel/core@2.9.3) @@ -7358,11 +15111,8 @@ packages: svgo: 2.8.0 transitivePeerDependencies: - '@parcel/core' - dev: true - /@parcel/optimizer-swc@2.9.3(@parcel/core@2.9.3): - resolution: {integrity: sha512-GQINNeqtdpL1ombq/Cpwi6IBk02wKJ/JJbYbyfHtk8lxlq13soenpwOlzJ5T9D2fdG+FUhai9NxpN5Ss4lNoAg==} - engines: {node: '>= 12.0.0', parcel: ^2.9.3} + '@parcel/optimizer-swc@2.9.3(@parcel/core@2.9.3)': dependencies: '@parcel/diagnostic': 2.9.3 '@parcel/plugin': 2.9.3(@parcel/core@2.9.3) @@ -7373,13 +15123,8 @@ packages: transitivePeerDependencies: - '@parcel/core' - '@swc/helpers' - dev: true - /@parcel/package-manager@2.9.3(@parcel/core@2.9.3): - resolution: {integrity: sha512-NH6omcNTEupDmW4Lm1e4NUYBjdqkURxgZ4CNESESInHJe6tblVhNB8Rpr1ar7zDar7cly9ILr8P6N3Ei7bTEjg==} - engines: {node: '>= 12.0.0'} - peerDependencies: - '@parcel/core': ^2.9.3 + '@parcel/package-manager@2.9.3(@parcel/core@2.9.3)': dependencies: '@parcel/core': 2.9.3 '@parcel/diagnostic': 2.9.3 @@ -7390,11 +15135,8 @@ packages: '@parcel/utils': 2.9.3 '@parcel/workers': 2.9.3(@parcel/core@2.9.3) semver: 7.6.0 - dev: true - /@parcel/packager-css@2.9.3(@parcel/core@2.9.3): - resolution: {integrity: sha512-mePiWiYZOULY6e1RdAIJyRoYqXqGci0srOaVZYaP7mnrzvJgA63kaZFFsDiEWghunQpMUuUjM2x/vQVHzxmhKQ==} - engines: {node: '>= 12.0.0', parcel: ^2.9.3} + '@parcel/packager-css@2.9.3(@parcel/core@2.9.3)': dependencies: '@parcel/diagnostic': 2.9.3 '@parcel/plugin': 2.9.3(@parcel/core@2.9.3) @@ -7403,11 +15145,8 @@ packages: nullthrows: 1.1.1 transitivePeerDependencies: - '@parcel/core' - dev: true - /@parcel/packager-html@2.9.3(@parcel/core@2.9.3): - resolution: {integrity: sha512-0Ex+O0EaZf9APNERRNGgGto02hFJ6f5RQEvRWBK55WAV1rXeU+kpjC0c0qZvnUaUtXfpWMsEBkevJCwDkUMeMg==} - engines: {node: '>= 12.0.0', parcel: ^2.9.3} + '@parcel/packager-html@2.9.3(@parcel/core@2.9.3)': dependencies: '@parcel/plugin': 2.9.3(@parcel/core@2.9.3) '@parcel/types': 2.9.3(@parcel/core@2.9.3) @@ -7416,11 +15155,8 @@ packages: posthtml: 0.16.6 transitivePeerDependencies: - '@parcel/core' - dev: true - /@parcel/packager-js@2.9.3(@parcel/core@2.9.3): - resolution: {integrity: sha512-V5xwkoE3zQ3R+WqAWhA1KGQ791FvJeW6KonOlMI1q76Djjgox68hhObqcLu66AmYNhR2R/wUpkP18hP2z8dSFw==} - engines: {node: '>= 12.0.0', parcel: ^2.9.3} + '@parcel/packager-js@2.9.3(@parcel/core@2.9.3)': dependencies: '@parcel/diagnostic': 2.9.3 '@parcel/hash': 2.9.3 @@ -7431,20 +15167,14 @@ packages: nullthrows: 1.1.1 transitivePeerDependencies: - '@parcel/core' - dev: true - /@parcel/packager-raw@2.9.3(@parcel/core@2.9.3): - resolution: {integrity: sha512-oPQTNoYanQ2DdJyL61uPYK2py83rKOT8YVh2QWAx0zsSli6Kiy64U3+xOCYWgDVCrHw9+9NpQMuAdSiFg4cq8g==} - engines: {node: '>= 12.0.0', parcel: ^2.9.3} + '@parcel/packager-raw@2.9.3(@parcel/core@2.9.3)': dependencies: '@parcel/plugin': 2.9.3(@parcel/core@2.9.3) transitivePeerDependencies: - '@parcel/core' - dev: true - /@parcel/packager-svg@2.9.3(@parcel/core@2.9.3): - resolution: {integrity: sha512-p/Ya6UO9DAkaCUFxfFGyeHZDp9YPAlpdnh1OChuwqSFOXFjjeXuoK4KLT+ZRalVBo2Jo8xF70oKMZw4MVvaL7Q==} - engines: {node: '>= 12.0.0', parcel: ^2.9.3} + '@parcel/packager-svg@2.9.3(@parcel/core@2.9.3)': dependencies: '@parcel/plugin': 2.9.3(@parcel/core@2.9.3) '@parcel/types': 2.9.3(@parcel/core@2.9.3) @@ -7452,29 +15182,20 @@ packages: posthtml: 0.16.6 transitivePeerDependencies: - '@parcel/core' - dev: true - /@parcel/plugin@2.9.3(@parcel/core@2.9.3): - resolution: {integrity: sha512-qN85Gqr2GMuxX1dT1mnuO9hOcvlEv1lrYrCxn7CJN2nUhbwcfG+LEvcrCzCOJ6XtIHm+ZBV9h9p7FfoPLvpw+g==} - engines: {node: '>= 12.0.0'} + '@parcel/plugin@2.9.3(@parcel/core@2.9.3)': dependencies: '@parcel/types': 2.9.3(@parcel/core@2.9.3) transitivePeerDependencies: - '@parcel/core' - dev: true - /@parcel/profiler@2.9.3: - resolution: {integrity: sha512-pyHc9lw8VZDfgZoeZWZU9J0CVEv1Zw9O5+e0DJPDPHuXJYr72ZAOhbljtU3owWKAeW+++Q2AZWkbUGEOjI/e6g==} - engines: {node: '>= 12.0.0'} + '@parcel/profiler@2.9.3': dependencies: '@parcel/diagnostic': 2.9.3 '@parcel/events': 2.9.3 chrome-trace-event: 1.0.3 - dev: true - /@parcel/reporter-cli@2.9.3(@parcel/core@2.9.3): - resolution: {integrity: sha512-pZiEvQpuXFuQBafMHxkDmwH8CnnK9sWHwa3bSbsnt385aUahtE8dpY0LKt+K1zfB6degKoczN6aWVj9WycQuZQ==} - engines: {node: '>= 12.0.0', parcel: ^2.9.3} + '@parcel/reporter-cli@2.9.3(@parcel/core@2.9.3)': dependencies: '@parcel/plugin': 2.9.3(@parcel/core@2.9.3) '@parcel/types': 2.9.3(@parcel/core@2.9.3) @@ -7483,21 +15204,15 @@ packages: term-size: 2.2.1 transitivePeerDependencies: - '@parcel/core' - dev: true - /@parcel/reporter-dev-server@2.9.3(@parcel/core@2.9.3): - resolution: {integrity: sha512-s6eboxdLEtRSvG52xi9IiNbcPKC0XMVmvTckieue2EqGDbDcaHQoHmmwkk0rNq0/Z/UxelGcQXoIYC/0xq3ykQ==} - engines: {node: '>= 12.0.0', parcel: ^2.9.3} + '@parcel/reporter-dev-server@2.9.3(@parcel/core@2.9.3)': dependencies: '@parcel/plugin': 2.9.3(@parcel/core@2.9.3) '@parcel/utils': 2.9.3 transitivePeerDependencies: - '@parcel/core' - dev: true - /@parcel/reporter-tracer@2.9.3(@parcel/core@2.9.3): - resolution: {integrity: sha512-9cXpKWk0m6d6d+4+TlAdOe8XIPaFEIKGWMWG+5SFAQE08u3olet4PSvd49F4+ZZo5ftRE7YI3j6xNbXvJT8KGw==} - engines: {node: '>= 12.0.0', parcel: ^2.9.3} + '@parcel/reporter-tracer@2.9.3(@parcel/core@2.9.3)': dependencies: '@parcel/plugin': 2.9.3(@parcel/core@2.9.3) '@parcel/utils': 2.9.3 @@ -7505,31 +15220,22 @@ packages: nullthrows: 1.1.1 transitivePeerDependencies: - '@parcel/core' - dev: true - /@parcel/resolver-default@2.9.3(@parcel/core@2.9.3): - resolution: {integrity: sha512-8ESJk1COKvDzkmOnppNXoDamNMlYVIvrKc2RuFPmp8nKVj47R6NwMgvwxEaatyPzvkmyTpq5RvG9I3HFc+r4Cw==} - engines: {node: '>= 12.0.0', parcel: ^2.9.3} + '@parcel/resolver-default@2.9.3(@parcel/core@2.9.3)': dependencies: '@parcel/node-resolver-core': 3.0.3(@parcel/core@2.9.3) '@parcel/plugin': 2.9.3(@parcel/core@2.9.3) transitivePeerDependencies: - '@parcel/core' - dev: true - /@parcel/runtime-browser-hmr@2.9.3(@parcel/core@2.9.3): - resolution: {integrity: sha512-EgiDIDrVAWpz7bOzWXqVinQkaFjLwT34wsonpXAbuI7f7r00d52vNAQC9AMu+pTijA3gyKoJ+Q4NWPMZf7ACDA==} - engines: {node: '>= 12.0.0', parcel: ^2.9.3} + '@parcel/runtime-browser-hmr@2.9.3(@parcel/core@2.9.3)': dependencies: '@parcel/plugin': 2.9.3(@parcel/core@2.9.3) '@parcel/utils': 2.9.3 transitivePeerDependencies: - '@parcel/core' - dev: true - /@parcel/runtime-js@2.9.3(@parcel/core@2.9.3): - resolution: {integrity: sha512-EvIy+qXcKnB5qxHhe96zmJpSAViNVXHfQI5RSdZ2a7CPwORwhTI+zPNT9sb7xb/WwFw/WuTTgzT40b41DceU6Q==} - engines: {node: '>= 12.0.0', parcel: ^2.9.3} + '@parcel/runtime-js@2.9.3(@parcel/core@2.9.3)': dependencies: '@parcel/diagnostic': 2.9.3 '@parcel/plugin': 2.9.3(@parcel/core@2.9.3) @@ -7537,11 +15243,8 @@ packages: nullthrows: 1.1.1 transitivePeerDependencies: - '@parcel/core' - dev: true - /@parcel/runtime-react-refresh@2.9.3(@parcel/core@2.9.3): - resolution: {integrity: sha512-XBgryZQIyCmi6JwEfMUCmINB3l1TpTp9a2iFxmYNpzHlqj4Ve0saKaqWOVRLvC945ZovWIBzcSW2IYqWKGtbAA==} - engines: {node: '>= 12.0.0', parcel: ^2.9.3} + '@parcel/runtime-react-refresh@2.9.3(@parcel/core@2.9.3)': dependencies: '@parcel/plugin': 2.9.3(@parcel/core@2.9.3) '@parcel/utils': 2.9.3 @@ -7549,29 +15252,20 @@ packages: react-refresh: 0.9.0 transitivePeerDependencies: - '@parcel/core' - dev: true - /@parcel/runtime-service-worker@2.9.3(@parcel/core@2.9.3): - resolution: {integrity: sha512-qLJLqv1mMdWL7gyh8aKBFFAuEiJkhUUgLKpdn6eSfH/R7kTtb76WnOwqUrhvEI9bZFUM/8Pa1bzJnPpqSOM+Sw==} - engines: {node: '>= 12.0.0', parcel: ^2.9.3} + '@parcel/runtime-service-worker@2.9.3(@parcel/core@2.9.3)': dependencies: '@parcel/plugin': 2.9.3(@parcel/core@2.9.3) '@parcel/utils': 2.9.3 nullthrows: 1.1.1 transitivePeerDependencies: - '@parcel/core' - dev: true - /@parcel/source-map@2.1.1: - resolution: {integrity: sha512-Ejx1P/mj+kMjQb8/y5XxDUn4reGdr+WyKYloBljpppUy8gs42T+BNoEOuRYqDVdgPc6NxduzIDoJS9pOFfV5Ew==} - engines: {node: ^12.18.3 || >=14} + '@parcel/source-map@2.1.1': dependencies: detect-libc: 1.0.3 - dev: true - /@parcel/transformer-babel@2.9.3(@parcel/core@2.9.3): - resolution: {integrity: sha512-pURtEsnsp3h6tOBDuzh9wRvVtw4PgIlqwAArIWdrG7iwqOUYv9D8ME4+ePWEu7MQWAp58hv9pTJtqWv4T+Sq8A==} - engines: {node: '>= 12.0.0', parcel: ^2.9.3} + '@parcel/transformer-babel@2.9.3(@parcel/core@2.9.3)': dependencies: '@parcel/diagnostic': 2.9.3 '@parcel/plugin': 2.9.3(@parcel/core@2.9.3) @@ -7583,11 +15277,8 @@ packages: semver: 7.6.0 transitivePeerDependencies: - '@parcel/core' - dev: true - /@parcel/transformer-css@2.9.3(@parcel/core@2.9.3): - resolution: {integrity: sha512-duWMdbEBBPjg3fQdXF16iWIdThetDZvCs2TpUD7xOlXH6kR0V5BJy8ONFT15u1RCqIV9hSNGaS3v3I9YRNY5zQ==} - engines: {node: '>= 12.0.0', parcel: ^2.9.3} + '@parcel/transformer-css@2.9.3(@parcel/core@2.9.3)': dependencies: '@parcel/diagnostic': 2.9.3 '@parcel/plugin': 2.9.3(@parcel/core@2.9.3) @@ -7598,11 +15289,8 @@ packages: nullthrows: 1.1.1 transitivePeerDependencies: - '@parcel/core' - dev: true - /@parcel/transformer-html@2.9.3(@parcel/core@2.9.3): - resolution: {integrity: sha512-0NU4omcHzFXA1seqftAXA2KNZaMByoKaNdXnLgBgtCGDiYvOcL+6xGHgY6pw9LvOh5um10KI5TxSIMILoI7VtA==} - engines: {node: '>= 12.0.0', parcel: ^2.9.3} + '@parcel/transformer-html@2.9.3(@parcel/core@2.9.3)': dependencies: '@parcel/diagnostic': 2.9.3 '@parcel/hash': 2.9.3 @@ -7615,26 +15303,16 @@ packages: srcset: 4.0.0 transitivePeerDependencies: - '@parcel/core' - dev: true - /@parcel/transformer-image@2.9.3(@parcel/core@2.9.3): - resolution: {integrity: sha512-7CEe35RaPadQzLIuxzTtIxnItvOoy46hcbXtOdDt6lmVa4omuOygZYRIya2lsGIP4JHvAaALMb5nt99a1uTwJg==} - engines: {node: '>= 12.0.0', parcel: ^2.9.3} - peerDependencies: - '@parcel/core': ^2.9.3 + '@parcel/transformer-image@2.9.3(@parcel/core@2.9.3)': dependencies: '@parcel/core': 2.9.3 '@parcel/plugin': 2.9.3(@parcel/core@2.9.3) '@parcel/utils': 2.9.3 '@parcel/workers': 2.9.3(@parcel/core@2.9.3) nullthrows: 1.1.1 - dev: true - /@parcel/transformer-js@2.9.3(@parcel/core@2.9.3): - resolution: {integrity: sha512-Z2MVVg5FYcPOfxlUwxqb5l9yjTMEqE3KI3zq2MBRUme6AV07KxLmCDF23b6glzZlHWQUE8MXzYCTAkOPCcPz+Q==} - engines: {node: '>= 12.0.0', parcel: ^2.9.3} - peerDependencies: - '@parcel/core': ^2.9.3 + '@parcel/transformer-js@2.9.3(@parcel/core@2.9.3)': dependencies: '@parcel/core': 2.9.3 '@parcel/diagnostic': 2.9.3 @@ -7647,23 +15325,15 @@ packages: nullthrows: 1.1.1 regenerator-runtime: 0.13.11 semver: 7.6.0 - dev: true - /@parcel/transformer-json@2.9.3(@parcel/core@2.9.3): - resolution: {integrity: sha512-yNL27dbOLhkkrjaQjiQ7Im9VOxmkfuuSNSmS0rA3gEjVcm07SLKRzWkAaPnyx44Lb6bzyOTWwVrb9aMmxgADpA==} - engines: {node: '>= 12.0.0', parcel: ^2.9.3} + '@parcel/transformer-json@2.9.3(@parcel/core@2.9.3)': dependencies: '@parcel/plugin': 2.9.3(@parcel/core@2.9.3) json5: 2.2.3 transitivePeerDependencies: - '@parcel/core' - dev: true - /@parcel/transformer-mdx@2.9.3(@mdx-js/react@1.6.22)(@parcel/core@2.9.3): - resolution: {integrity: sha512-SE3mnCPefhS3p3pWLMUvQmMf4tHfVLqTxVLikrKR1WRwhIBzuYEm9UbayDadZPmGB9JYE4QIQKGCeDa97geyAg==} - engines: {node: '>= 12.0.0', parcel: ^2.9.3} - peerDependencies: - '@mdx-js/react': ^1.6.22 + '@parcel/transformer-mdx@2.9.3(@mdx-js/react@1.6.22)(@parcel/core@2.9.3)': dependencies: '@mdx-js/mdx': 1.6.22 '@mdx-js/react': 1.6.22(react@18.2.0) @@ -7671,11 +15341,8 @@ packages: transitivePeerDependencies: - '@parcel/core' - supports-color - dev: true - /@parcel/transformer-postcss@2.9.3(@parcel/core@2.9.3): - resolution: {integrity: sha512-HoDvPqKzhpmvMmHqQhDnt8F1vH61m6plpGiYaYnYv2Om4HHi5ZIq9bO+9QLBnTKfaZ7ndYSefTKOxTYElg7wyw==} - engines: {node: '>= 12.0.0', parcel: ^2.9.3} + '@parcel/transformer-postcss@2.9.3(@parcel/core@2.9.3)': dependencies: '@parcel/diagnostic': 2.9.3 '@parcel/hash': 2.9.3 @@ -7687,11 +15354,8 @@ packages: semver: 7.6.0 transitivePeerDependencies: - '@parcel/core' - dev: true - /@parcel/transformer-posthtml@2.9.3(@parcel/core@2.9.3): - resolution: {integrity: sha512-2fQGgrzRmaqbWf3y2/T6xhqrNjzqMMKksqJzvc8TMfK6f2kg3Ddjv158eaSW2JdkV39aY7tvAOn5f1uzo74BMA==} - engines: {node: '>= 12.0.0', parcel: ^2.9.3} + '@parcel/transformer-posthtml@2.9.3(@parcel/core@2.9.3)': dependencies: '@parcel/plugin': 2.9.3(@parcel/core@2.9.3) '@parcel/utils': 2.9.3 @@ -7702,42 +15366,30 @@ packages: semver: 7.6.0 transitivePeerDependencies: - '@parcel/core' - dev: true - /@parcel/transformer-raw@2.9.3(@parcel/core@2.9.3): - resolution: {integrity: sha512-oqdPzMC9QzWRbY9J6TZEqltknjno+dY24QWqf8ondmdF2+W+/2mRDu59hhCzQrqUHgTq4FewowRZmSfpzHxwaQ==} - engines: {node: '>= 12.0.0', parcel: ^2.9.3} + '@parcel/transformer-raw@2.9.3(@parcel/core@2.9.3)': dependencies: '@parcel/plugin': 2.9.3(@parcel/core@2.9.3) transitivePeerDependencies: - '@parcel/core' - dev: true - /@parcel/transformer-react-refresh-wrap@2.9.3(@parcel/core@2.9.3): - resolution: {integrity: sha512-cb9NyU6oJlDblFIlzqIE8AkvRQVGl2IwJNKwD4PdE7Y6sq2okGEPG4hOw3k/Y9JVjM4/2pUORqvjSRhWwd9oVQ==} - engines: {node: '>= 12.0.0', parcel: ^2.9.3} + '@parcel/transformer-react-refresh-wrap@2.9.3(@parcel/core@2.9.3)': dependencies: '@parcel/plugin': 2.9.3(@parcel/core@2.9.3) '@parcel/utils': 2.9.3 react-refresh: 0.9.0 transitivePeerDependencies: - '@parcel/core' - dev: true - /@parcel/transformer-sass@2.9.3(@parcel/core@2.9.3): - resolution: {integrity: sha512-i9abj9bKg3xCHghJyTM3rUVxIEn9n1Rl+DFdpyNAD8VZ52COfOshFDQOWNuhU1hEnJOFYCjnfcO0HRTsg3dWmg==} - engines: {node: '>= 12.0.0', parcel: ^2.9.3} + '@parcel/transformer-sass@2.9.3(@parcel/core@2.9.3)': dependencies: '@parcel/plugin': 2.9.3(@parcel/core@2.9.3) '@parcel/source-map': 2.1.1 sass: 1.56.1 transitivePeerDependencies: - '@parcel/core' - dev: true - /@parcel/transformer-svg-react@2.9.3(@parcel/core@2.9.3): - resolution: {integrity: sha512-RXmCn58CkCBhpsS1AaRBrSRla0U5JN3r3hb7kQvEb+d7chGnsxCCWsBxtlrxPUjoUFLdQli9rhpCTkiyOBXY2A==} - engines: {node: '>= 12.0.0', parcel: ^2.9.3} + '@parcel/transformer-svg-react@2.9.3(@parcel/core@2.9.3)': dependencies: '@parcel/plugin': 2.9.3(@parcel/core@2.9.3) '@svgr/core': 6.5.1 @@ -7746,11 +15398,8 @@ packages: transitivePeerDependencies: - '@parcel/core' - supports-color - dev: true - /@parcel/transformer-svg@2.9.3(@parcel/core@2.9.3): - resolution: {integrity: sha512-ypmE+dzB09IMCdEAkOsSxq1dEIm2A3h67nAFz4qbfHbwNgXBUuy/jB3ZMwXN/cO0f7SBh/Ap8Jhq6vmGqB5tWw==} - engines: {node: '>= 12.0.0', parcel: ^2.9.3} + '@parcel/transformer-svg@2.9.3(@parcel/core@2.9.3)': dependencies: '@parcel/diagnostic': 2.9.3 '@parcel/hash': 2.9.3 @@ -7762,10 +15411,8 @@ packages: semver: 7.6.0 transitivePeerDependencies: - '@parcel/core' - dev: true - /@parcel/types@2.9.3(@parcel/core@2.9.3): - resolution: {integrity: sha512-NSNY8sYtRhvF1SqhnIGgGvJocyWt1K8Tnw5cVepm0g38ywtX6mwkBvMkmeehXkII4mSUn+frD9wGsydTunezvA==} + '@parcel/types@2.9.3(@parcel/core@2.9.3)': dependencies: '@parcel/cache': 2.9.3(@parcel/core@2.9.3) '@parcel/diagnostic': 2.9.3 @@ -7776,11 +15423,8 @@ packages: utility-types: 3.10.0 transitivePeerDependencies: - '@parcel/core' - dev: true - /@parcel/utils@2.9.3: - resolution: {integrity: sha512-cesanjtj/oLehW8Waq9JFPmAImhoiHX03ihc3JTWkrvJYSbD7wYKCDgPAM3JiRAqvh1LZ6P699uITrYWNoRLUg==} - engines: {node: '>= 12.0.0'} + '@parcel/utils@2.9.3': dependencies: '@parcel/codeframe': 2.9.3 '@parcel/diagnostic': 2.9.3 @@ -7790,22 +15434,13 @@ packages: '@parcel/source-map': 2.1.1 chalk: 4.1.2 nullthrows: 1.1.1 - dev: true - /@parcel/watcher@2.0.7: - resolution: {integrity: sha512-gc3hoS6e+2XdIQ4HHljDB1l0Yx2EWh/sBBtCEFNKGSMlwASWeAQsOY/fPbxOBcZ/pg0jBh4Ga+4xHlZc4faAEQ==} - engines: {node: '>= 10.0.0'} - requiresBuild: true + '@parcel/watcher@2.0.7': dependencies: node-addon-api: 3.2.1 node-gyp-build: 4.5.0 - dev: true - /@parcel/workers@2.9.3(@parcel/core@2.9.3): - resolution: {integrity: sha512-zRrDuZJzTevrrwElYosFztgldhqW6G9q5zOeQXfVQFkkEJCNfg36ixeiofKRU8uu2x+j+T6216mhMNB6HiuY+w==} - engines: {node: '>= 12.0.0'} - peerDependencies: - '@parcel/core': ^2.9.3 + '@parcel/workers@2.9.3(@parcel/core@2.9.3)': dependencies: '@parcel/core': 2.9.3 '@parcel/diagnostic': 2.9.3 @@ -7814,68 +15449,47 @@ packages: '@parcel/types': 2.9.3(@parcel/core@2.9.3) '@parcel/utils': 2.9.3 nullthrows: 1.1.1 - dev: true - /@peculiar/asn1-android@2.3.10: - resolution: {integrity: sha512-z9Rx9cFJv7UUablZISe7uksNbFJCq13hO0yEAOoIpAymALTLlvUOSLnGiQS7okPaM5dP42oTLhezH6XDXRXjGw==} + '@peculiar/asn1-android@2.3.10': dependencies: '@peculiar/asn1-schema': 2.3.8 asn1js: 3.0.5 tslib: 2.6.2 - dev: false - /@peculiar/asn1-ecc@2.3.8: - resolution: {integrity: sha512-Ah/Q15y3A/CtxbPibiLM/LKcMbnLTdUdLHUgdpB5f60sSvGkXzxJCu5ezGTFHogZXWNX3KSmYqilCrfdmBc6pQ==} + '@peculiar/asn1-ecc@2.3.8': dependencies: '@peculiar/asn1-schema': 2.3.8 '@peculiar/asn1-x509': 2.3.8 asn1js: 3.0.5 tslib: 2.6.2 - dev: false - /@peculiar/asn1-rsa@2.3.8: - resolution: {integrity: sha512-ES/RVEHu8VMYXgrg3gjb1m/XG0KJWnV4qyZZ7mAg7rrF3VTmRbLxO8mk+uy0Hme7geSMebp+Wvi2U6RLLEs12Q==} + '@peculiar/asn1-rsa@2.3.8': dependencies: '@peculiar/asn1-schema': 2.3.8 '@peculiar/asn1-x509': 2.3.8 asn1js: 3.0.5 tslib: 2.6.2 - dev: false - /@peculiar/asn1-schema@2.3.8: - resolution: {integrity: sha512-ULB1XqHKx1WBU/tTFIA+uARuRoBVZ4pNdOA878RDrRbBfBGcSzi5HBkdScC6ZbHn8z7L8gmKCgPC1LHRrP46tA==} + '@peculiar/asn1-schema@2.3.8': dependencies: asn1js: 3.0.5 pvtsutils: 1.3.5 tslib: 2.6.2 - dev: false - /@peculiar/asn1-x509@2.3.8: - resolution: {integrity: sha512-voKxGfDU1c6r9mKiN5ZUsZWh3Dy1BABvTM3cimf0tztNwyMJPhiXY94eRTgsMQe6ViLfT6EoXxkWVzcm3mFAFw==} + '@peculiar/asn1-x509@2.3.8': dependencies: '@peculiar/asn1-schema': 2.3.8 asn1js: 3.0.5 ipaddr.js: 2.1.0 pvtsutils: 1.3.5 tslib: 2.6.2 - dev: false - /@pkgjs/parseargs@0.11.0: - resolution: {integrity: sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==} - engines: {node: '>=14'} - requiresBuild: true - dev: false + '@pkgjs/parseargs@0.11.0': optional: true - /@pkgr/core@0.1.1: - resolution: {integrity: sha512-cq8o4cWH0ibXh9VGi5P20Tu9XF/0fFXl9EUinr9QfTM7a7p0oTA4iJRCQWppXR1Pg8dSM0UCItCkPwsk9qWWYA==} - engines: {node: ^12.20.0 || ^14.18.0 || >=16.0.0} - dev: true + '@pkgr/core@0.1.1': {} - /@puppeteer/browsers@2.2.2: - resolution: {integrity: sha512-hZ/JhxPIceWaGSEzUZp83/8M49CoxlkuThfTR7t4AoCu5+ZvJ3vktLm60Otww2TXeROB5igiZ8D9oPQh6ckBVg==} - engines: {node: '>=18'} - hasBin: true + '@puppeteer/browsers@2.2.2': dependencies: debug: 4.3.4 extract-zip: 2.0.1 @@ -7887,65 +15501,38 @@ packages: yargs: 17.7.2 transitivePeerDependencies: - supports-color - dev: true - /@react-dnd/asap@5.0.0: - resolution: {integrity: sha512-czNGSkNPZgxapKz1a8zj/C5me5MpVpN4wlXDQIMF4wDUuFJ37x7beakc4S7C1xKilHA4tgT9zZb4U64BdT/E5g==} - dev: true + '@react-dnd/asap@5.0.0': {} - /@react-dnd/invariant@4.0.0: - resolution: {integrity: sha512-tjPrh294NbH6Gj1YP1of6JYEe3+sm0Wy7YA1ImG6YghlZe3n8F+fBx1yIrA5dVJCuUh6pBp4XO7/lcSq7oLL0A==} - dev: true + '@react-dnd/invariant@4.0.0': {} - /@react-dnd/shallowequal@4.0.0: - resolution: {integrity: sha512-Yykovind6xzqAqd0t5umrdAGPlGLTE80cy80UkEnbt8Zv5zEYTFzJSNPQ81TY8BSpRreubu1oE54iHBv2UVnTQ==} - dev: true + '@react-dnd/shallowequal@4.0.0': {} - /@react-spring/animated@9.6.1(react@18.2.0): - resolution: {integrity: sha512-ls/rJBrAqiAYozjLo5EPPLLOb1LM0lNVQcXODTC1SMtS6DbuBCPaKco5svFUQFMP2dso3O+qcC4k9FsKc0KxMQ==} - peerDependencies: - react: ^16.8.0 || ^17.0.0 || ^18.0.0 + '@react-spring/animated@9.6.1(react@18.2.0)': dependencies: '@react-spring/shared': 9.6.1(react@18.2.0) '@react-spring/types': 9.6.1 react: 18.2.0 - dev: true - /@react-spring/core@9.6.1(react@18.2.0): - resolution: {integrity: sha512-3HAAinAyCPessyQNNXe5W0OHzRfa8Yo5P748paPcmMowZ/4sMfaZ2ZB6e5x5khQI8NusOHj8nquoutd6FRY5WQ==} - peerDependencies: - react: ^16.8.0 || ^17.0.0 || ^18.0.0 + '@react-spring/core@9.6.1(react@18.2.0)': dependencies: '@react-spring/animated': 9.6.1(react@18.2.0) '@react-spring/rafz': 9.6.1 '@react-spring/shared': 9.6.1(react@18.2.0) '@react-spring/types': 9.6.1 react: 18.2.0 - dev: true - /@react-spring/rafz@9.6.1: - resolution: {integrity: sha512-v6qbgNRpztJFFfSE3e2W1Uz+g8KnIBs6SmzCzcVVF61GdGfGOuBrbjIcp+nUz301awVmREKi4eMQb2Ab2gGgyQ==} - dev: true + '@react-spring/rafz@9.6.1': {} - /@react-spring/shared@9.6.1(react@18.2.0): - resolution: {integrity: sha512-PBFBXabxFEuF8enNLkVqMC9h5uLRBo6GQhRMQT/nRTnemVENimgRd+0ZT4yFnAQ0AxWNiJfX3qux+bW2LbG6Bw==} - peerDependencies: - react: ^16.8.0 || ^17.0.0 || ^18.0.0 + '@react-spring/shared@9.6.1(react@18.2.0)': dependencies: '@react-spring/rafz': 9.6.1 '@react-spring/types': 9.6.1 react: 18.2.0 - dev: true - /@react-spring/types@9.6.1: - resolution: {integrity: sha512-POu8Mk0hIU3lRXB3bGIGe4VHIwwDsQyoD1F394OK7STTiX9w4dG3cTLljjYswkQN+hDSHRrj4O36kuVa7KPU8Q==} - dev: true + '@react-spring/types@9.6.1': {} - /@react-spring/web@9.6.1(react-dom@18.2.0)(react@18.2.0): - resolution: {integrity: sha512-X2zR6q2Z+FjsWfGAmAXlQaoUHbPmfuCaXpuM6TcwXPpLE1ZD4A1eys/wpXboFQmDkjnrlTmKvpVna1MjWpZ5Hw==} - peerDependencies: - react: ^16.8.0 || ^17.0.0 || ^18.0.0 - react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0 + '@react-spring/web@9.6.1(react-dom@18.2.0)(react@18.2.0)': dependencies: '@react-spring/animated': 9.6.1(react@18.2.0) '@react-spring/core': 9.6.1(react@18.2.0) @@ -7953,70 +15540,36 @@ packages: '@react-spring/types': 9.6.1 react: 18.2.0 react-dom: 18.2.0(react@18.2.0) - dev: true - /@redis/bloom@1.2.0(@redis/client@1.5.6): - resolution: {integrity: sha512-HG2DFjYKbpNmVXsa0keLHp/3leGJz1mjh09f2RLGGLQZzSHpkmZWuwJbAvo3QcRY8p80m5+ZdXZdYOSBLlp7Cg==} - peerDependencies: - '@redis/client': ^1.0.0 + '@redis/bloom@1.2.0(@redis/client@1.5.6)': dependencies: '@redis/client': 1.5.6 - dev: false - /@redis/client@1.5.6: - resolution: {integrity: sha512-dFD1S6je+A47Lj22jN/upVU2fj4huR7S9APd7/ziUXsIXDL+11GPYti4Suv5y8FuXaN+0ZG4JF+y1houEJ7ToA==} - engines: {node: '>=14'} + '@redis/client@1.5.6': dependencies: cluster-key-slot: 1.1.2 generic-pool: 3.9.0 yallist: 4.0.0 - dev: false - /@redis/graph@1.1.0(@redis/client@1.5.6): - resolution: {integrity: sha512-16yZWngxyXPd+MJxeSr0dqh2AIOi8j9yXKcKCwVaKDbH3HTuETpDVPcLujhFYVPtYrngSco31BUcSa9TH31Gqg==} - peerDependencies: - '@redis/client': ^1.0.0 + '@redis/graph@1.1.0(@redis/client@1.5.6)': dependencies: '@redis/client': 1.5.6 - dev: false - /@redis/json@1.0.4(@redis/client@1.5.6): - resolution: {integrity: sha512-LUZE2Gdrhg0Rx7AN+cZkb1e6HjoSKaeeW8rYnt89Tly13GBI5eP4CwDVr+MY8BAYfCg4/N15OUrtLoona9uSgw==} - peerDependencies: - '@redis/client': ^1.0.0 + '@redis/json@1.0.4(@redis/client@1.5.6)': dependencies: '@redis/client': 1.5.6 - dev: false - /@redis/search@1.1.2(@redis/client@1.5.6): - resolution: {integrity: sha512-/cMfstG/fOh/SsE+4/BQGeuH/JJloeWuH+qJzM8dbxuWvdWibWAOAHHCZTMPhV3xIlH4/cUEIA8OV5QnYpaVoA==} - peerDependencies: - '@redis/client': ^1.0.0 + '@redis/search@1.1.2(@redis/client@1.5.6)': dependencies: '@redis/client': 1.5.6 - dev: false - /@redis/time-series@1.0.4(@redis/client@1.5.6): - resolution: {integrity: sha512-ThUIgo2U/g7cCuZavucQTQzA9g9JbDDY2f64u3AbAoz/8vE2lt2U37LamDUVChhaDA3IRT9R6VvJwqnUfTJzng==} - peerDependencies: - '@redis/client': ^1.0.0 + '@redis/time-series@1.0.4(@redis/client@1.5.6)': dependencies: '@redis/client': 1.5.6 - dev: false - /@remix-run/router@1.5.0: - resolution: {integrity: sha512-bkUDCp8o1MvFO+qxkODcbhSqRa6P2GXgrGZVpt0dCXNW2HCSCqYI0ZoAqEOSAjRWmmlKcYgFvN4B4S+zo/f8kg==} - engines: {node: '>=14'} - dev: true + '@remix-run/router@1.5.0': {} - /@rollup/plugin-commonjs@25.0.7(rollup@4.12.0): - resolution: {integrity: sha512-nEvcR+LRjEjsaSsc4x3XZfCCvZIaSMenZu/OiwOKGN2UhQpAYI7ru7czFvyWbErlpoGjnSX3D5Ch5FcMA3kRWQ==} - engines: {node: '>=14.0.0'} - peerDependencies: - rollup: ^2.68.0||^3.0.0||^4.0.0 - peerDependenciesMeta: - rollup: - optional: true + '@rollup/plugin-commonjs@25.0.7(rollup@4.12.0)': dependencies: '@rollup/pluginutils': 5.1.0(rollup@4.12.0) commondir: 1.0.1 @@ -8025,16 +15578,8 @@ packages: is-reference: 1.2.1 magic-string: 0.30.7 rollup: 4.12.0 - dev: true - /@rollup/plugin-commonjs@25.0.7(rollup@4.14.3): - resolution: {integrity: sha512-nEvcR+LRjEjsaSsc4x3XZfCCvZIaSMenZu/OiwOKGN2UhQpAYI7ru7czFvyWbErlpoGjnSX3D5Ch5FcMA3kRWQ==} - engines: {node: '>=14.0.0'} - peerDependencies: - rollup: ^2.68.0||^3.0.0||^4.0.0 - peerDependenciesMeta: - rollup: - optional: true + '@rollup/plugin-commonjs@25.0.7(rollup@4.14.3)': dependencies: '@rollup/pluginutils': 5.1.0(rollup@4.14.3) commondir: 1.0.1 @@ -8043,42 +15588,18 @@ packages: is-reference: 1.2.1 magic-string: 0.30.7 rollup: 4.14.3 - dev: true - /@rollup/plugin-json@6.1.0(rollup@4.12.0): - resolution: {integrity: sha512-EGI2te5ENk1coGeADSIwZ7G2Q8CJS2sF120T7jLw4xFw9n7wIOXHo+kIYRAoVpJAN+kmqZSoO3Fp4JtoNF4ReA==} - engines: {node: '>=14.0.0'} - peerDependencies: - rollup: ^1.20.0||^2.0.0||^3.0.0||^4.0.0 - peerDependenciesMeta: - rollup: - optional: true + '@rollup/plugin-json@6.1.0(rollup@4.12.0)': dependencies: '@rollup/pluginutils': 5.1.0(rollup@4.12.0) rollup: 4.12.0 - dev: true - /@rollup/plugin-json@6.1.0(rollup@4.14.3): - resolution: {integrity: sha512-EGI2te5ENk1coGeADSIwZ7G2Q8CJS2sF120T7jLw4xFw9n7wIOXHo+kIYRAoVpJAN+kmqZSoO3Fp4JtoNF4ReA==} - engines: {node: '>=14.0.0'} - peerDependencies: - rollup: ^1.20.0||^2.0.0||^3.0.0||^4.0.0 - peerDependenciesMeta: - rollup: - optional: true + '@rollup/plugin-json@6.1.0(rollup@4.14.3)': dependencies: '@rollup/pluginutils': 5.1.0(rollup@4.14.3) rollup: 4.14.3 - dev: true - /@rollup/plugin-node-resolve@15.2.3(rollup@4.12.0): - resolution: {integrity: sha512-j/lym8nf5E21LwBT4Df1VD6hRO2L2iwUeUmP7litikRsVp1H6NWx20NEp0Y7su+7XGc476GnXXc4kFeZNGmaSQ==} - engines: {node: '>=14.0.0'} - peerDependencies: - rollup: ^2.78.0||^3.0.0||^4.0.0 - peerDependenciesMeta: - rollup: - optional: true + '@rollup/plugin-node-resolve@15.2.3(rollup@4.12.0)': dependencies: '@rollup/pluginutils': 5.1.0(rollup@4.12.0) '@types/resolve': 1.20.2 @@ -8087,16 +15608,8 @@ packages: is-module: 1.0.0 resolve: 1.22.2 rollup: 4.12.0 - dev: true - /@rollup/plugin-node-resolve@15.2.3(rollup@4.14.3): - resolution: {integrity: sha512-j/lym8nf5E21LwBT4Df1VD6hRO2L2iwUeUmP7litikRsVp1H6NWx20NEp0Y7su+7XGc476GnXXc4kFeZNGmaSQ==} - engines: {node: '>=14.0.0'} - peerDependencies: - rollup: ^2.78.0||^3.0.0||^4.0.0 - peerDependenciesMeta: - rollup: - optional: true + '@rollup/plugin-node-resolve@15.2.3(rollup@4.14.3)': dependencies: '@rollup/pluginutils': 5.1.0(rollup@4.14.3) '@types/resolve': 1.20.2 @@ -8105,337 +15618,138 @@ packages: is-module: 1.0.0 resolve: 1.22.2 rollup: 4.14.3 - dev: true - /@rollup/plugin-typescript@11.1.6(rollup@4.12.0)(typescript@5.3.3): - resolution: {integrity: sha512-R92yOmIACgYdJ7dJ97p4K69I8gg6IEHt8M7dUBxN3W6nrO8uUxX5ixl0yU/N3aZTi8WhPuICvOHXQvF6FaykAA==} - engines: {node: '>=14.0.0'} - peerDependencies: - rollup: ^2.14.0||^3.0.0||^4.0.0 - tslib: '*' - typescript: '>=3.7.0' - peerDependenciesMeta: - rollup: - optional: true - tslib: - optional: true + '@rollup/plugin-typescript@11.1.6(rollup@4.12.0)(typescript@5.3.3)': dependencies: '@rollup/pluginutils': 5.1.0(rollup@4.12.0) resolve: 1.22.8 rollup: 4.12.0 typescript: 5.3.3 - dev: true - /@rollup/plugin-typescript@11.1.6(rollup@4.14.3)(typescript@5.3.3): - resolution: {integrity: sha512-R92yOmIACgYdJ7dJ97p4K69I8gg6IEHt8M7dUBxN3W6nrO8uUxX5ixl0yU/N3aZTi8WhPuICvOHXQvF6FaykAA==} - engines: {node: '>=14.0.0'} - peerDependencies: - rollup: ^2.14.0||^3.0.0||^4.0.0 - tslib: '*' - typescript: '>=3.7.0' - peerDependenciesMeta: - rollup: - optional: true - tslib: - optional: true + '@rollup/plugin-typescript@11.1.6(rollup@4.14.3)(typescript@5.3.3)': dependencies: '@rollup/pluginutils': 5.1.0(rollup@4.14.3) resolve: 1.22.8 rollup: 4.14.3 typescript: 5.3.3 - dev: true - /@rollup/pluginutils@5.1.0(rollup@4.12.0): - resolution: {integrity: sha512-XTIWOPPcpvyKI6L1NHo0lFlCyznUEyPmPY1mc3KpPVDYulHSTvyeLNVW00QTLIAFNhR3kYnJTQHeGqU4M3n09g==} - engines: {node: '>=14.0.0'} - peerDependencies: - rollup: ^1.20.0||^2.0.0||^3.0.0||^4.0.0 - peerDependenciesMeta: - rollup: - optional: true + '@rollup/pluginutils@5.1.0(rollup@4.12.0)': dependencies: '@types/estree': 1.0.5 estree-walker: 2.0.2 picomatch: 2.3.1 rollup: 4.12.0 - dev: true - /@rollup/pluginutils@5.1.0(rollup@4.14.3): - resolution: {integrity: sha512-XTIWOPPcpvyKI6L1NHo0lFlCyznUEyPmPY1mc3KpPVDYulHSTvyeLNVW00QTLIAFNhR3kYnJTQHeGqU4M3n09g==} - engines: {node: '>=14.0.0'} - peerDependencies: - rollup: ^1.20.0||^2.0.0||^3.0.0||^4.0.0 - peerDependenciesMeta: - rollup: - optional: true + '@rollup/pluginutils@5.1.0(rollup@4.14.3)': dependencies: '@types/estree': 1.0.5 estree-walker: 2.0.2 picomatch: 2.3.1 rollup: 4.14.3 - dev: true - /@rollup/rollup-android-arm-eabi@4.12.0: - resolution: {integrity: sha512-+ac02NL/2TCKRrJu2wffk1kZ+RyqxVUlbjSagNgPm94frxtr+XDL12E5Ll1enWskLrtrZ2r8L3wED1orIibV/w==} - cpu: [arm] - os: [android] - requiresBuild: true - dev: true + '@rollup/rollup-android-arm-eabi@4.12.0': optional: true - /@rollup/rollup-android-arm-eabi@4.14.3: - resolution: {integrity: sha512-X9alQ3XM6I9IlSlmC8ddAvMSyG1WuHk5oUnXGw+yUBs3BFoTizmG1La/Gr8fVJvDWAq+zlYTZ9DBgrlKRVY06g==} - cpu: [arm] - os: [android] - requiresBuild: true - dev: true + '@rollup/rollup-android-arm-eabi@4.14.3': optional: true - /@rollup/rollup-android-arm64@4.12.0: - resolution: {integrity: sha512-OBqcX2BMe6nvjQ0Nyp7cC90cnumt8PXmO7Dp3gfAju/6YwG0Tj74z1vKrfRz7qAv23nBcYM8BCbhrsWqO7PzQQ==} - cpu: [arm64] - os: [android] - requiresBuild: true - dev: true + '@rollup/rollup-android-arm64@4.12.0': optional: true - /@rollup/rollup-android-arm64@4.14.3: - resolution: {integrity: sha512-eQK5JIi+POhFpzk+LnjKIy4Ks+pwJ+NXmPxOCSvOKSNRPONzKuUvWE+P9JxGZVxrtzm6BAYMaL50FFuPe0oWMQ==} - cpu: [arm64] - os: [android] - requiresBuild: true - dev: true + '@rollup/rollup-android-arm64@4.14.3': optional: true - /@rollup/rollup-darwin-arm64@4.12.0: - resolution: {integrity: sha512-X64tZd8dRE/QTrBIEs63kaOBG0b5GVEd3ccoLtyf6IdXtHdh8h+I56C2yC3PtC9Ucnv0CpNFJLqKFVgCYe0lOQ==} - cpu: [arm64] - os: [darwin] - requiresBuild: true - dev: true + '@rollup/rollup-darwin-arm64@4.12.0': optional: true - /@rollup/rollup-darwin-arm64@4.14.3: - resolution: {integrity: sha512-Od4vE6f6CTT53yM1jgcLqNfItTsLt5zE46fdPaEmeFHvPs5SjZYlLpHrSiHEKR1+HdRfxuzXHjDOIxQyC3ptBA==} - cpu: [arm64] - os: [darwin] - requiresBuild: true - dev: true + '@rollup/rollup-darwin-arm64@4.14.3': optional: true - /@rollup/rollup-darwin-x64@4.12.0: - resolution: {integrity: sha512-cc71KUZoVbUJmGP2cOuiZ9HSOP14AzBAThn3OU+9LcA1+IUqswJyR1cAJj3Mg55HbjZP6OLAIscbQsQLrpgTOg==} - cpu: [x64] - os: [darwin] - requiresBuild: true - dev: true + '@rollup/rollup-darwin-x64@4.12.0': optional: true - /@rollup/rollup-darwin-x64@4.14.3: - resolution: {integrity: sha512-0IMAO21axJeNIrvS9lSe/PGthc8ZUS+zC53O0VhF5gMxfmcKAP4ESkKOCwEi6u2asUrt4mQv2rjY8QseIEb1aw==} - cpu: [x64] - os: [darwin] - requiresBuild: true - dev: true + '@rollup/rollup-darwin-x64@4.14.3': optional: true - /@rollup/rollup-linux-arm-gnueabihf@4.12.0: - resolution: {integrity: sha512-a6w/Y3hyyO6GlpKL2xJ4IOh/7d+APaqLYdMf86xnczU3nurFTaVN9s9jOXQg97BE4nYm/7Ga51rjec5nfRdrvA==} - cpu: [arm] - os: [linux] - requiresBuild: true - dev: true + '@rollup/rollup-linux-arm-gnueabihf@4.12.0': optional: true - /@rollup/rollup-linux-arm-gnueabihf@4.14.3: - resolution: {integrity: sha512-ge2DC7tHRHa3caVEoSbPRJpq7azhG+xYsd6u2MEnJ6XzPSzQsTKyXvh6iWjXRf7Rt9ykIUWHtl0Uz3T6yXPpKw==} - cpu: [arm] - os: [linux] - requiresBuild: true - dev: true + '@rollup/rollup-linux-arm-gnueabihf@4.14.3': optional: true - /@rollup/rollup-linux-arm-musleabihf@4.14.3: - resolution: {integrity: sha512-ljcuiDI4V3ySuc7eSk4lQ9wU8J8r8KrOUvB2U+TtK0TiW6OFDmJ+DdIjjwZHIw9CNxzbmXY39wwpzYuFDwNXuw==} - cpu: [arm] - os: [linux] - requiresBuild: true - dev: true + '@rollup/rollup-linux-arm-musleabihf@4.14.3': optional: true - /@rollup/rollup-linux-arm64-gnu@4.12.0: - resolution: {integrity: sha512-0fZBq27b+D7Ar5CQMofVN8sggOVhEtzFUwOwPppQt0k+VR+7UHMZZY4y+64WJ06XOhBTKXtQB/Sv0NwQMXyNAA==} - cpu: [arm64] - os: [linux] - requiresBuild: true - dev: true + '@rollup/rollup-linux-arm64-gnu@4.12.0': optional: true - /@rollup/rollup-linux-arm64-gnu@4.14.3: - resolution: {integrity: sha512-Eci2us9VTHm1eSyn5/eEpaC7eP/mp5n46gTRB3Aar3BgSvDQGJZuicyq6TsH4HngNBgVqC5sDYxOzTExSU+NjA==} - cpu: [arm64] - os: [linux] - requiresBuild: true - dev: true + '@rollup/rollup-linux-arm64-gnu@4.14.3': optional: true - /@rollup/rollup-linux-arm64-musl@4.12.0: - resolution: {integrity: sha512-eTvzUS3hhhlgeAv6bfigekzWZjaEX9xP9HhxB0Dvrdbkk5w/b+1Sxct2ZuDxNJKzsRStSq1EaEkVSEe7A7ipgQ==} - cpu: [arm64] - os: [linux] - requiresBuild: true - dev: true + '@rollup/rollup-linux-arm64-musl@4.12.0': optional: true - /@rollup/rollup-linux-arm64-musl@4.14.3: - resolution: {integrity: sha512-UrBoMLCq4E92/LCqlh+blpqMz5h1tJttPIniwUgOFJyjWI1qrtrDhhpHPuFxULlUmjFHfloWdixtDhSxJt5iKw==} - cpu: [arm64] - os: [linux] - requiresBuild: true - dev: true + '@rollup/rollup-linux-arm64-musl@4.14.3': optional: true - /@rollup/rollup-linux-powerpc64le-gnu@4.14.3: - resolution: {integrity: sha512-5aRjvsS8q1nWN8AoRfrq5+9IflC3P1leMoy4r2WjXyFqf3qcqsxRCfxtZIV58tCxd+Yv7WELPcO9mY9aeQyAmw==} - cpu: [ppc64] - os: [linux] - requiresBuild: true - dev: true + '@rollup/rollup-linux-powerpc64le-gnu@4.14.3': optional: true - /@rollup/rollup-linux-riscv64-gnu@4.12.0: - resolution: {integrity: sha512-ix+qAB9qmrCRiaO71VFfY8rkiAZJL8zQRXveS27HS+pKdjwUfEhqo2+YF2oI+H/22Xsiski+qqwIBxVewLK7sw==} - cpu: [riscv64] - os: [linux] - requiresBuild: true - dev: true + '@rollup/rollup-linux-riscv64-gnu@4.12.0': optional: true - /@rollup/rollup-linux-riscv64-gnu@4.14.3: - resolution: {integrity: sha512-sk/Qh1j2/RJSX7FhEpJn8n0ndxy/uf0kI/9Zc4b1ELhqULVdTfN6HL31CDaTChiBAOgLcsJ1sgVZjWv8XNEsAQ==} - cpu: [riscv64] - os: [linux] - requiresBuild: true - dev: true + '@rollup/rollup-linux-riscv64-gnu@4.14.3': optional: true - /@rollup/rollup-linux-s390x-gnu@4.14.3: - resolution: {integrity: sha512-jOO/PEaDitOmY9TgkxF/TQIjXySQe5KVYB57H/8LRP/ux0ZoO8cSHCX17asMSv3ruwslXW/TLBcxyaUzGRHcqg==} - cpu: [s390x] - os: [linux] - requiresBuild: true - dev: true + '@rollup/rollup-linux-s390x-gnu@4.14.3': optional: true - /@rollup/rollup-linux-x64-gnu@4.12.0: - resolution: {integrity: sha512-TenQhZVOtw/3qKOPa7d+QgkeM6xY0LtwzR8OplmyL5LrgTWIXpTQg2Q2ycBf8jm+SFW2Wt/DTn1gf7nFp3ssVA==} - cpu: [x64] - os: [linux] - requiresBuild: true - dev: true + '@rollup/rollup-linux-x64-gnu@4.12.0': optional: true - /@rollup/rollup-linux-x64-gnu@4.14.3: - resolution: {integrity: sha512-8ybV4Xjy59xLMyWo3GCfEGqtKV5M5gCSrZlxkPGvEPCGDLNla7v48S662HSGwRd6/2cSneMQWiv+QzcttLrrOA==} - cpu: [x64] - os: [linux] - requiresBuild: true - dev: true + '@rollup/rollup-linux-x64-gnu@4.14.3': optional: true - /@rollup/rollup-linux-x64-musl@4.12.0: - resolution: {integrity: sha512-LfFdRhNnW0zdMvdCb5FNuWlls2WbbSridJvxOvYWgSBOYZtgBfW9UGNJG//rwMqTX1xQE9BAodvMH9tAusKDUw==} - cpu: [x64] - os: [linux] - requiresBuild: true - dev: true + '@rollup/rollup-linux-x64-musl@4.12.0': optional: true - /@rollup/rollup-linux-x64-musl@4.14.3: - resolution: {integrity: sha512-s+xf1I46trOY10OqAtZ5Rm6lzHre/UiLA1J2uOhCFXWkbZrJRkYBPO6FhvGfHmdtQ3Bx793MNa7LvoWFAm93bg==} - cpu: [x64] - os: [linux] - requiresBuild: true - dev: true + '@rollup/rollup-linux-x64-musl@4.14.3': optional: true - /@rollup/rollup-win32-arm64-msvc@4.12.0: - resolution: {integrity: sha512-JPDxovheWNp6d7AHCgsUlkuCKvtu3RB55iNEkaQcf0ttsDU/JZF+iQnYcQJSk/7PtT4mjjVG8N1kpwnI9SLYaw==} - cpu: [arm64] - os: [win32] - requiresBuild: true - dev: true + '@rollup/rollup-win32-arm64-msvc@4.12.0': optional: true - /@rollup/rollup-win32-arm64-msvc@4.14.3: - resolution: {integrity: sha512-+4h2WrGOYsOumDQ5S2sYNyhVfrue+9tc9XcLWLh+Kw3UOxAvrfOrSMFon60KspcDdytkNDh7K2Vs6eMaYImAZg==} - cpu: [arm64] - os: [win32] - requiresBuild: true - dev: true + '@rollup/rollup-win32-arm64-msvc@4.14.3': optional: true - /@rollup/rollup-win32-ia32-msvc@4.12.0: - resolution: {integrity: sha512-fjtuvMWRGJn1oZacG8IPnzIV6GF2/XG+h71FKn76OYFqySXInJtseAqdprVTDTyqPxQOG9Exak5/E9Z3+EJ8ZA==} - cpu: [ia32] - os: [win32] - requiresBuild: true - dev: true + '@rollup/rollup-win32-ia32-msvc@4.12.0': optional: true - /@rollup/rollup-win32-ia32-msvc@4.14.3: - resolution: {integrity: sha512-T1l7y/bCeL/kUwh9OD4PQT4aM7Bq43vX05htPJJ46RTI4r5KNt6qJRzAfNfM+OYMNEVBWQzR2Gyk+FXLZfogGw==} - cpu: [ia32] - os: [win32] - requiresBuild: true - dev: true + '@rollup/rollup-win32-ia32-msvc@4.14.3': optional: true - /@rollup/rollup-win32-x64-msvc@4.12.0: - resolution: {integrity: sha512-ZYmr5mS2wd4Dew/JjT0Fqi2NPB/ZhZ2VvPp7SmvPZb4Y1CG/LRcS6tcRo2cYU7zLK5A7cdbhWnnWmUjoI4qapg==} - cpu: [x64] - os: [win32] - requiresBuild: true - dev: true + '@rollup/rollup-win32-x64-msvc@4.12.0': optional: true - /@rollup/rollup-win32-x64-msvc@4.14.3: - resolution: {integrity: sha512-/BypzV0H1y1HzgYpxqRaXGBRqfodgoBBCcsrujT6QRcakDQdfU+Lq9PENPh5jB4I44YWq+0C2eHsHya+nZY1sA==} - cpu: [x64] - os: [win32] - requiresBuild: true - dev: true + '@rollup/rollup-win32-x64-msvc@4.14.3': optional: true - /@shopify/jest-koa-mocks@5.0.0: - resolution: {integrity: sha512-keF5fgqAzWgC4O5uwUgQawp80IsDJdfyyMvWnIcsMaYw9CgURm4CW+v9NskUAn6AeaHd4Tkv+pWCFg/LRHHf4w==} - engines: {node: ^14.17.0 || >=16.0.0} + '@shopify/jest-koa-mocks@5.0.0': dependencies: koa: 2.13.4 node-mocks-http: 1.12.1 transitivePeerDependencies: - supports-color - dev: true - /@sideway/address@4.1.5: - resolution: {integrity: sha512-IqO/DUQHUkPeixNQ8n0JA6102hT9CmaljNTPmQ1u8MEhBo/R4Q8eKLN/vGZxuebwOroDB4cbpjheD4+/sKFK4Q==} + '@sideway/address@4.1.5': dependencies: '@hapi/hoek': 9.3.0 - dev: true - /@sideway/formula@3.0.1: - resolution: {integrity: sha512-/poHZJJVjx3L+zVD6g9KgHfYnb443oi7wLu/XKojDviHy6HOEOA6z1Trk5aR1dGcmPenJEgb2sK2I80LeS3MIg==} - dev: true + '@sideway/formula@3.0.1': {} - /@sideway/pinpoint@2.0.0: - resolution: {integrity: sha512-RNiOoTPkptFtSVzQevY/yWtZwf/RxyVnPy/OcA9HBM3MlGDnBEYL5B41H0MTn0Uec8Hi+2qUtTfG2WWZBmMejQ==} - dev: true + '@sideway/pinpoint@2.0.0': {} - /@silverhand/eslint-config-react@6.0.2(eslint@8.57.0)(postcss@8.4.31)(prettier@3.0.0)(stylelint@15.11.0)(typescript@5.3.3): - resolution: {integrity: sha512-4PqhypLqrX5FVXimKBz3S1c+usDns3N/XG66n2FQtO1FIa8WUVw1CsuWHT+tkqeIxDR1PRQX1e8Iwyy7vPclPA==} - engines: {node: ^20.9.0} - peerDependencies: - stylelint: ^15.0.0 || ^16.0.0 + '@silverhand/eslint-config-react@6.0.2(eslint@8.57.0)(postcss@8.4.31)(prettier@3.0.0)(stylelint@15.11.0)(typescript@5.3.3)': dependencies: '@silverhand/eslint-config': 6.0.1(eslint@8.57.0)(prettier@3.0.0)(typescript@5.3.3) eslint-config-xo-react: 0.27.0(eslint-plugin-react-hooks@4.6.0)(eslint-plugin-react@7.34.1)(eslint@8.57.0) @@ -8455,14 +15769,8 @@ packages: - prettier - supports-color - typescript - dev: true - /@silverhand/eslint-config@6.0.1(eslint@8.57.0)(prettier@3.0.0)(typescript@5.3.3): - resolution: {integrity: sha512-v7VbAiNgVwcjwGXe4LK6qNVKgltcm4XX9dkYgyaD22vcYCtp1BSd8NVsPDISV1nAwwirCklL0KSDtcD7pxkbHw==} - engines: {node: ^20.9.0} - peerDependencies: - eslint: ^8.57.0 - prettier: ^3.0.0 + '@silverhand/eslint-config@6.0.1(eslint@8.57.0)(prettier@3.0.0)(typescript@5.3.3)': dependencies: '@silverhand/eslint-plugin-fp': 2.5.0(eslint@8.57.0) '@typescript-eslint/eslint-plugin': 7.7.0(@typescript-eslint/parser@7.7.0)(eslint@8.57.0)(typescript@5.3.3) @@ -8489,28 +15797,18 @@ packages: - eslint-import-resolver-webpack - supports-color - typescript - dev: true - /@silverhand/eslint-plugin-fp@2.5.0(eslint@8.57.0): - resolution: {integrity: sha512-/oLO2Rs9nkhOk+rmC3PsWDvrDKrOfKuRtbSAwH4Scawn5GqAjo7ZXIZXj7RWa4nxLsCGc3ULvaVs1e1m4n6G/A==} - engines: {node: '>=14.15.0'} - peerDependencies: - eslint: ^8.1.0 + '@silverhand/eslint-plugin-fp@2.5.0(eslint@8.57.0)': dependencies: create-eslint-index: 1.0.0 eslint: 8.57.0 eslint-ast-utils: 1.1.0 import-modules: 2.1.0 lodash: 4.17.21 - dev: true - /@silverhand/essentials@2.9.0: - resolution: {integrity: sha512-n9mSO/gsLj0GRFXBRNhaQLRK6qbn6pBnKjMQdFwweKgT12ODBXpgkpXohpOBqSofnoaCQWqiDAT6xpCy/5dMIg==} - engines: {node: ^18.12.0 || ^20.9.0, pnpm: ^8.0.0} + '@silverhand/essentials@2.9.0': {} - /@silverhand/slonik@31.0.0-beta.2: - resolution: {integrity: sha512-4IM57Er5We8+hT8IY9z5La1JAGNRFZ63tp3N0XYUYTNV9fLfUXF78yT+PoW4arnf4qc+4n498bMmKgFmt/mo9Q==} - engines: {node: ^20.9.0} + '@silverhand/slonik@31.0.0-beta.2': dependencies: '@types/pg': 8.11.2 camelcase: 8.0.0 @@ -8530,34 +15828,20 @@ packages: transitivePeerDependencies: - pg-native - /@silverhand/ts-config-react@6.0.0(typescript@5.3.3): - resolution: {integrity: sha512-eEB8TwGzw5kJTKcuHtvifpcs6p8ZDNRFWH2W7ZM4Rf7DsFBQtXkYpwQFQvZ9UVOAs4YCIeSY4OJCjtaY0fUp8g==} - engines: {node: ^20.9.0} - peerDependencies: - typescript: ^5.3.3 + '@silverhand/ts-config-react@6.0.0(typescript@5.3.3)': dependencies: '@silverhand/ts-config': 6.0.0(typescript@5.3.3) typescript: 5.3.3 - dev: true - /@silverhand/ts-config@6.0.0(typescript@5.3.3): - resolution: {integrity: sha512-zgR9vxC/DBx+0ZhCxqGTlZfVX6Bi0/UZztt+8np5I07ahfGMVUJjWedgHNK2NrSX2Nwclr9zLlUbgxwgqi4Idw==} - engines: {node: ^20.9.0} - peerDependencies: - typescript: ^5.3.3 + '@silverhand/ts-config@6.0.0(typescript@5.3.3)': dependencies: typescript: 5.3.3 - dev: true - /@simplewebauthn/browser@9.0.1: - resolution: {integrity: sha512-wD2WpbkaEP4170s13/HUxPcAV5y4ZXaKo1TfNklS5zDefPinIgXOpgz1kpEvobAsaLPa2KeH7AKKX/od1mrBJw==} + '@simplewebauthn/browser@9.0.1': dependencies: '@simplewebauthn/types': 9.0.1 - dev: true - /@simplewebauthn/server@9.0.1: - resolution: {integrity: sha512-XnilMoBygy2BOZjIHPxby+7ENx5ChN2wXfhd14mOgO/XitYMqdphTo/kwgxEI4/Je3lELK1h/eLDJqM2fIKS1w==} - engines: {node: '>=16.0.0'} + '@simplewebauthn/server@9.0.1': dependencies: '@hexagon/base64': 1.1.28 '@peculiar/asn1-android': 2.3.10 @@ -8570,104 +15854,66 @@ packages: cross-fetch: 4.0.0 transitivePeerDependencies: - encoding - dev: false - /@simplewebauthn/types@9.0.1: - resolution: {integrity: sha512-tGSRP1QvsAvsJmnOlRQyw/mvK9gnPtjEc5fg2+m8n+QUa+D7rvrKkOYyfpy42GTs90X3RDOnqJgfHt+qO67/+w==} + '@simplewebauthn/types@9.0.1': {} - /@sinclair/typebox@0.24.46: - resolution: {integrity: sha512-ng4ut1z2MCBhK/NwDVwIQp3pAUOCs/KNaW3cBxdFB2xTDrOuo1xuNmpr/9HHFhxqIvHrs1NTH3KJg6q+JSy1Kw==} - dev: true + '@sinclair/typebox@0.24.46': {} - /@sinclair/typebox@0.25.21: - resolution: {integrity: sha512-gFukHN4t8K4+wVC+ECqeqwzBDeFeTzBXroBTqE6vcWrQGbEUpHO7LYdG0f4xnvYq4VOEwITSlHlp0JBAIFMS/g==} - dev: true + '@sinclair/typebox@0.25.21': {} - /@sinclair/typebox@0.27.8: - resolution: {integrity: sha512-+Fj43pSMwJs4KRrH/938Uf+uAELIgVBmQzg/q1YG10djyfA3TnrU8N8XzqCh/okZdszqBQTZf96idMfE5lnwTA==} - dev: true + '@sinclair/typebox@0.27.8': {} - /@sindresorhus/is@5.4.0: - resolution: {integrity: sha512-Ggh6E9AnMpiNXlbXfFUcWE9qm408rL8jDi7+PMBBx7TMbwEmiqAiSmZ+zydYwxcJLqPGNDoLc9mXDuMDBZg0sA==} - engines: {node: '>=14.16'} - dev: false + '@sindresorhus/is@5.4.0': {} - /@sindresorhus/is@6.1.0: - resolution: {integrity: sha512-BuvU07zq3tQ/2SIgBsEuxKYDyDjC0n7Zir52bpHy2xnBbW81+po43aLFPLbeV3HRAheFbGud1qgcqSYfhtHMAg==} - engines: {node: '>=16'} - dev: false + '@sindresorhus/is@6.1.0': {} - /@sinonjs/commons@2.0.0: - resolution: {integrity: sha512-uLa0j859mMrg2slwQYdO/AkrOfmH+X6LTVmNTS9CqexuE2IvVORIkSpJLqePAbEnKJ77aMmCwr1NUZ57120Xcg==} + '@sinonjs/commons@2.0.0': dependencies: type-detect: 4.0.8 - dev: true - /@sinonjs/commons@3.0.0: - resolution: {integrity: sha512-jXBtWAF4vmdNmZgD5FoKsVLv3rPgDnLgPbU84LIJ3otV44vJlDRokVng5v8NFJdCf/da9legHcKaRuZs4L7faA==} + '@sinonjs/commons@3.0.0': dependencies: type-detect: 4.0.8 - dev: true - /@sinonjs/fake-timers@10.3.0: - resolution: {integrity: sha512-V4BG07kuYSUkTCSBHG8G8TNhM+F19jXFWnQtzj+we8DrkpSBCee9Z3Ms8yiGer/dlmhe35/Xdgyo3/0rQKg7YA==} + '@sinonjs/fake-timers@10.3.0': dependencies: '@sinonjs/commons': 3.0.0 - dev: true - /@sinonjs/fake-timers@11.2.2: - resolution: {integrity: sha512-G2piCSxQ7oWOxwGSAyFHfPIsyeJGXYtc6mFbnFA+kRXkiEnTl8c/8jul2S329iFBnDI9HGoeWWAZvuvOkZccgw==} + '@sinonjs/fake-timers@11.2.2': dependencies: '@sinonjs/commons': 3.0.0 - dev: true - /@sinonjs/samsam@8.0.0: - resolution: {integrity: sha512-Bp8KUVlLp8ibJZrnvq2foVhP0IVX2CIprMJPK0vqGqgrDa0OHVKeZyBykqskkrdxV6yKBPmGasO8LVjAKR3Gew==} + '@sinonjs/samsam@8.0.0': dependencies: '@sinonjs/commons': 2.0.0 lodash.get: 4.4.2 type-detect: 4.0.8 - dev: true - /@sinonjs/text-encoding@0.7.2: - resolution: {integrity: sha512-sXXKG+uL9IrKqViTtao2Ws6dy0znu9sOaP1di/jKGW1M6VssO8vlpXCQcpZ+jisQ1tTFAC5Jo/EOzFbggBagFQ==} - dev: true + '@sinonjs/text-encoding@0.7.2': {} - /@smithy/abort-controller@2.2.0: - resolution: {integrity: sha512-wRlta7GuLWpTqtFfGo+nZyOO1vEvewdNR1R4rTxpC8XU6vG/NDyrFBhwLZsqg1NUoR1noVaXJPC/7ZK47QCySw==} - engines: {node: '>=14.0.0'} + '@smithy/abort-controller@2.2.0': dependencies: '@smithy/types': 2.12.0 tslib: 2.6.2 - dev: false - /@smithy/chunked-blob-reader-native@2.2.0: - resolution: {integrity: sha512-VNB5+1oCgX3Fzs072yuRsUoC2N4Zg/LJ11DTxX3+Qu+Paa6AmbIF0E9sc2wthz9Psrk/zcOlTCyuposlIhPjZQ==} + '@smithy/chunked-blob-reader-native@2.2.0': dependencies: '@smithy/util-base64': 2.3.0 tslib: 2.6.2 - dev: false - /@smithy/chunked-blob-reader@2.2.0: - resolution: {integrity: sha512-3GJNvRwXBGdkDZZOGiziVYzDpn4j6zfyULHMDKAGIUo72yHALpE9CbhfQp/XcLNVoc1byfMpn6uW5H2BqPjgaQ==} + '@smithy/chunked-blob-reader@2.2.0': dependencies: tslib: 2.6.2 - dev: false - /@smithy/config-resolver@2.2.0: - resolution: {integrity: sha512-fsiMgd8toyUba6n1WRmr+qACzXltpdDkPTAaDqc8QqPBUzO+/JKwL6bUBseHVi8tu9l+3JOK+tSf7cay+4B3LA==} - engines: {node: '>=14.0.0'} + '@smithy/config-resolver@2.2.0': dependencies: '@smithy/node-config-provider': 2.3.0 '@smithy/types': 2.12.0 '@smithy/util-config-provider': 2.3.0 '@smithy/util-middleware': 2.2.0 tslib: 2.6.2 - dev: false - /@smithy/core@1.4.2: - resolution: {integrity: sha512-2fek3I0KZHWJlRLvRTqxTEri+qV0GRHrJIoLFuBMZB4EMg4WgeBGfF0X6abnrNYpq55KJ6R4D6x4f0vLnhzinA==} - engines: {node: '>=14.0.0'} + '@smithy/core@1.4.2': dependencies: '@smithy/middleware-endpoint': 2.5.1 '@smithy/middleware-retry': 2.3.1 @@ -8677,135 +15923,95 @@ packages: '@smithy/types': 2.12.0 '@smithy/util-middleware': 2.2.0 tslib: 2.6.2 - dev: false - /@smithy/credential-provider-imds@2.3.0: - resolution: {integrity: sha512-BWB9mIukO1wjEOo1Ojgl6LrG4avcaC7T/ZP6ptmAaW4xluhSIPZhY+/PI5YKzlk+jsm+4sQZB45Bt1OfMeQa3w==} - engines: {node: '>=14.0.0'} + '@smithy/credential-provider-imds@2.3.0': dependencies: '@smithy/node-config-provider': 2.3.0 '@smithy/property-provider': 2.2.0 '@smithy/types': 2.12.0 '@smithy/url-parser': 2.2.0 tslib: 2.6.2 - dev: false - /@smithy/eventstream-codec@2.2.0: - resolution: {integrity: sha512-8janZoJw85nJmQZc4L8TuePp2pk1nxLgkxIR0TUjKJ5Dkj5oelB9WtiSSGXCQvNsJl0VSTvK/2ueMXxvpa9GVw==} + '@smithy/eventstream-codec@2.2.0': dependencies: '@aws-crypto/crc32': 3.0.0 '@smithy/types': 2.12.0 '@smithy/util-hex-encoding': 2.2.0 tslib: 2.6.2 - dev: false - /@smithy/eventstream-serde-browser@2.2.0: - resolution: {integrity: sha512-UaPf8jKbcP71BGiO0CdeLmlg+RhWnlN8ipsMSdwvqBFigl5nil3rHOI/5GE3tfiuX8LvY5Z9N0meuU7Rab7jWw==} - engines: {node: '>=14.0.0'} + '@smithy/eventstream-serde-browser@2.2.0': dependencies: '@smithy/eventstream-serde-universal': 2.2.0 '@smithy/types': 2.12.0 tslib: 2.6.2 - dev: false - /@smithy/eventstream-serde-config-resolver@2.2.0: - resolution: {integrity: sha512-RHhbTw/JW3+r8QQH7PrganjNCiuiEZmpi6fYUAetFfPLfZ6EkiA08uN3EFfcyKubXQxOwTeJRZSQmDDCdUshaA==} - engines: {node: '>=14.0.0'} + '@smithy/eventstream-serde-config-resolver@2.2.0': dependencies: '@smithy/types': 2.12.0 tslib: 2.6.2 - dev: false - /@smithy/eventstream-serde-node@2.2.0: - resolution: {integrity: sha512-zpQMtJVqCUMn+pCSFcl9K/RPNtQE0NuMh8sKpCdEHafhwRsjP50Oq/4kMmvxSRy6d8Jslqd8BLvDngrUtmN9iA==} - engines: {node: '>=14.0.0'} + '@smithy/eventstream-serde-node@2.2.0': dependencies: '@smithy/eventstream-serde-universal': 2.2.0 '@smithy/types': 2.12.0 tslib: 2.6.2 - dev: false - /@smithy/eventstream-serde-universal@2.2.0: - resolution: {integrity: sha512-pvoe/vvJY0mOpuF84BEtyZoYfbehiFj8KKWk1ds2AT0mTLYFVs+7sBJZmioOFdBXKd48lfrx1vumdPdmGlCLxA==} - engines: {node: '>=14.0.0'} + '@smithy/eventstream-serde-universal@2.2.0': dependencies: '@smithy/eventstream-codec': 2.2.0 '@smithy/types': 2.12.0 tslib: 2.6.2 - dev: false - /@smithy/fetch-http-handler@2.5.0: - resolution: {integrity: sha512-BOWEBeppWhLn/no/JxUL/ghTfANTjT7kg3Ww2rPqTUY9R4yHPXxJ9JhMe3Z03LN3aPwiwlpDIUcVw1xDyHqEhw==} + '@smithy/fetch-http-handler@2.5.0': dependencies: '@smithy/protocol-http': 3.3.0 '@smithy/querystring-builder': 2.2.0 '@smithy/types': 2.12.0 '@smithy/util-base64': 2.3.0 tslib: 2.6.2 - dev: false - /@smithy/hash-blob-browser@2.2.0: - resolution: {integrity: sha512-SGPoVH8mdXBqrkVCJ1Hd1X7vh1zDXojNN1yZyZTZsCno99hVue9+IYzWDjq/EQDDXxmITB0gBmuyPh8oAZSTcg==} + '@smithy/hash-blob-browser@2.2.0': dependencies: '@smithy/chunked-blob-reader': 2.2.0 '@smithy/chunked-blob-reader-native': 2.2.0 '@smithy/types': 2.12.0 tslib: 2.6.2 - dev: false - /@smithy/hash-node@2.2.0: - resolution: {integrity: sha512-zLWaC/5aWpMrHKpoDF6nqpNtBhlAYKF/7+9yMN7GpdR8CzohnWfGtMznPybnwSS8saaXBMxIGwJqR4HmRp6b3g==} - engines: {node: '>=14.0.0'} + '@smithy/hash-node@2.2.0': dependencies: '@smithy/types': 2.12.0 '@smithy/util-buffer-from': 2.2.0 '@smithy/util-utf8': 2.3.0 tslib: 2.6.2 - dev: false - /@smithy/hash-stream-node@2.2.0: - resolution: {integrity: sha512-aT+HCATOSRMGpPI7bi7NSsTNVZE/La9IaxLXWoVAYMxHT5hGO3ZOGEMZQg8A6nNL+pdFGtZQtND1eoY084HgHQ==} - engines: {node: '>=14.0.0'} + '@smithy/hash-stream-node@2.2.0': dependencies: '@smithy/types': 2.12.0 '@smithy/util-utf8': 2.3.0 tslib: 2.6.2 - dev: false - /@smithy/invalid-dependency@2.2.0: - resolution: {integrity: sha512-nEDASdbKFKPXN2O6lOlTgrEEOO9NHIeO+HVvZnkqc8h5U9g3BIhWsvzFo+UcUbliMHvKNPD/zVxDrkP1Sbgp8Q==} + '@smithy/invalid-dependency@2.2.0': dependencies: '@smithy/types': 2.12.0 tslib: 2.6.2 - dev: false - /@smithy/is-array-buffer@2.2.0: - resolution: {integrity: sha512-GGP3O9QFD24uGeAXYUjwSTXARoqpZykHadOmA8G5vfJPK0/DC67qa//0qvqrJzL1xc8WQWX7/yc7fwudjPHPhA==} - engines: {node: '>=14.0.0'} + '@smithy/is-array-buffer@2.2.0': dependencies: tslib: 2.6.2 - dev: false - /@smithy/md5-js@2.2.0: - resolution: {integrity: sha512-M26XTtt9IIusVMOWEAhIvFIr9jYj4ISPPGJROqw6vXngO3IYJCnVVSMFn4Tx1rUTG5BiKJNg9u2nxmBiZC5IlQ==} + '@smithy/md5-js@2.2.0': dependencies: '@smithy/types': 2.12.0 '@smithy/util-utf8': 2.3.0 tslib: 2.6.2 - dev: false - /@smithy/middleware-content-length@2.2.0: - resolution: {integrity: sha512-5bl2LG1Ah/7E5cMSC+q+h3IpVHMeOkG0yLRyQT1p2aMJkSrZG7RlXHPuAgb7EyaFeidKEnnd/fNaLLaKlHGzDQ==} - engines: {node: '>=14.0.0'} + '@smithy/middleware-content-length@2.2.0': dependencies: '@smithy/protocol-http': 3.3.0 '@smithy/types': 2.12.0 tslib: 2.6.2 - dev: false - /@smithy/middleware-endpoint@2.5.1: - resolution: {integrity: sha512-1/8kFp6Fl4OsSIVTWHnNjLnTL8IqpIb/D3sTSczrKFnrE9VMNWxnrRKNvpUHOJ6zpGD5f62TPm7+17ilTJpiCQ==} - engines: {node: '>=14.0.0'} + '@smithy/middleware-endpoint@2.5.1': dependencies: '@smithy/middleware-serde': 2.3.0 '@smithy/node-config-provider': 2.3.0 @@ -8814,11 +16020,8 @@ packages: '@smithy/url-parser': 2.2.0 '@smithy/util-middleware': 2.2.0 tslib: 2.6.2 - dev: false - /@smithy/middleware-retry@2.3.1: - resolution: {integrity: sha512-P2bGufFpFdYcWvqpyqqmalRtwFUNUA8vHjJR5iGqbfR6mp65qKOLcUd6lTr4S9Gn/enynSrSf3p3FVgVAf6bXA==} - engines: {node: '>=14.0.0'} + '@smithy/middleware-retry@2.3.1': dependencies: '@smithy/node-config-provider': 2.3.0 '@smithy/protocol-http': 3.3.0 @@ -8829,96 +16032,63 @@ packages: '@smithy/util-retry': 2.2.0 tslib: 2.6.2 uuid: 9.0.1 - dev: false - /@smithy/middleware-serde@2.3.0: - resolution: {integrity: sha512-sIADe7ojwqTyvEQBe1nc/GXB9wdHhi9UwyX0lTyttmUWDJLP655ZYE1WngnNyXREme8I27KCaUhyhZWRXL0q7Q==} - engines: {node: '>=14.0.0'} + '@smithy/middleware-serde@2.3.0': dependencies: '@smithy/types': 2.12.0 tslib: 2.6.2 - dev: false - /@smithy/middleware-stack@2.2.0: - resolution: {integrity: sha512-Qntc3jrtwwrsAC+X8wms8zhrTr0sFXnyEGhZd9sLtsJ/6gGQKFzNB+wWbOcpJd7BR8ThNCoKt76BuQahfMvpeA==} - engines: {node: '>=14.0.0'} + '@smithy/middleware-stack@2.2.0': dependencies: '@smithy/types': 2.12.0 tslib: 2.6.2 - dev: false - /@smithy/node-config-provider@2.3.0: - resolution: {integrity: sha512-0elK5/03a1JPWMDPaS726Iw6LpQg80gFut1tNpPfxFuChEEklo2yL823V94SpTZTxmKlXFtFgsP55uh3dErnIg==} - engines: {node: '>=14.0.0'} + '@smithy/node-config-provider@2.3.0': dependencies: '@smithy/property-provider': 2.2.0 '@smithy/shared-ini-file-loader': 2.4.0 '@smithy/types': 2.12.0 tslib: 2.6.2 - dev: false - /@smithy/node-http-handler@2.5.0: - resolution: {integrity: sha512-mVGyPBzkkGQsPoxQUbxlEfRjrj6FPyA3u3u2VXGr9hT8wilsoQdZdvKpMBFMB8Crfhv5dNkKHIW0Yyuc7eABqA==} - engines: {node: '>=14.0.0'} + '@smithy/node-http-handler@2.5.0': dependencies: '@smithy/abort-controller': 2.2.0 '@smithy/protocol-http': 3.3.0 '@smithy/querystring-builder': 2.2.0 '@smithy/types': 2.12.0 tslib: 2.6.2 - dev: false - /@smithy/property-provider@2.2.0: - resolution: {integrity: sha512-+xiil2lFhtTRzXkx8F053AV46QnIw6e7MV8od5Mi68E1ICOjCeCHw2XfLnDEUHnT9WGUIkwcqavXjfwuJbGlpg==} - engines: {node: '>=14.0.0'} + '@smithy/property-provider@2.2.0': dependencies: '@smithy/types': 2.12.0 tslib: 2.6.2 - dev: false - /@smithy/protocol-http@3.3.0: - resolution: {integrity: sha512-Xy5XK1AFWW2nlY/biWZXu6/krgbaf2dg0q492D8M5qthsnU2H+UgFeZLbM76FnH7s6RO/xhQRkj+T6KBO3JzgQ==} - engines: {node: '>=14.0.0'} + '@smithy/protocol-http@3.3.0': dependencies: '@smithy/types': 2.12.0 tslib: 2.6.2 - dev: false - /@smithy/querystring-builder@2.2.0: - resolution: {integrity: sha512-L1kSeviUWL+emq3CUVSgdogoM/D9QMFaqxL/dd0X7PCNWmPXqt+ExtrBjqT0V7HLN03Vs9SuiLrG3zy3JGnE5A==} - engines: {node: '>=14.0.0'} + '@smithy/querystring-builder@2.2.0': dependencies: '@smithy/types': 2.12.0 '@smithy/util-uri-escape': 2.2.0 tslib: 2.6.2 - dev: false - /@smithy/querystring-parser@2.2.0: - resolution: {integrity: sha512-BvHCDrKfbG5Yhbpj4vsbuPV2GgcpHiAkLeIlcA1LtfpMz3jrqizP1+OguSNSj1MwBHEiN+jwNisXLGdajGDQJA==} - engines: {node: '>=14.0.0'} + '@smithy/querystring-parser@2.2.0': dependencies: '@smithy/types': 2.12.0 tslib: 2.6.2 - dev: false - /@smithy/service-error-classification@2.1.5: - resolution: {integrity: sha512-uBDTIBBEdAQryvHdc5W8sS5YX7RQzF683XrHePVdFmAgKiMofU15FLSM0/HU03hKTnazdNRFa0YHS7+ArwoUSQ==} - engines: {node: '>=14.0.0'} + '@smithy/service-error-classification@2.1.5': dependencies: '@smithy/types': 2.12.0 - dev: false - /@smithy/shared-ini-file-loader@2.4.0: - resolution: {integrity: sha512-WyujUJL8e1B6Z4PBfAqC/aGY1+C7T0w20Gih3yrvJSk97gpiVfB+y7c46T4Nunk+ZngLq0rOIdeVeIklk0R3OA==} - engines: {node: '>=14.0.0'} + '@smithy/shared-ini-file-loader@2.4.0': dependencies: '@smithy/types': 2.12.0 tslib: 2.6.2 - dev: false - /@smithy/signature-v4@2.3.0: - resolution: {integrity: sha512-ui/NlpILU+6HAQBfJX8BBsDXuKSNrjTSuOYArRblcrErwKFutjrCNb/OExfVRyj9+26F9J+ZmfWT+fKWuDrH3Q==} - engines: {node: '>=14.0.0'} + '@smithy/signature-v4@2.3.0': dependencies: '@smithy/is-array-buffer': 2.2.0 '@smithy/types': 2.12.0 @@ -8927,11 +16097,8 @@ packages: '@smithy/util-uri-escape': 2.2.0 '@smithy/util-utf8': 2.3.0 tslib: 2.6.2 - dev: false - /@smithy/smithy-client@2.5.1: - resolution: {integrity: sha512-jrbSQrYCho0yDaaf92qWgd+7nAeap5LtHTI51KXqmpIFCceKU3K9+vIVTUH72bOJngBMqa4kyu1VJhRcSrk/CQ==} - engines: {node: '>=14.0.0'} + '@smithy/smithy-client@2.5.1': dependencies: '@smithy/middleware-endpoint': 2.5.1 '@smithy/middleware-stack': 2.2.0 @@ -8939,74 +16106,49 @@ packages: '@smithy/types': 2.12.0 '@smithy/util-stream': 2.2.0 tslib: 2.6.2 - dev: false - /@smithy/types@2.12.0: - resolution: {integrity: sha512-QwYgloJ0sVNBeBuBs65cIkTbfzV/Q6ZNPCJ99EICFEdJYG50nGIY/uYXp+TbsdJReIuPr0a0kXmCvren3MbRRw==} - engines: {node: '>=14.0.0'} + '@smithy/types@2.12.0': dependencies: tslib: 2.6.2 - dev: false - /@smithy/url-parser@2.2.0: - resolution: {integrity: sha512-hoA4zm61q1mNTpksiSWp2nEl1dt3j726HdRhiNgVJQMj7mLp7dprtF57mOB6JvEk/x9d2bsuL5hlqZbBuHQylQ==} + '@smithy/url-parser@2.2.0': dependencies: '@smithy/querystring-parser': 2.2.0 '@smithy/types': 2.12.0 tslib: 2.6.2 - dev: false - /@smithy/util-base64@2.3.0: - resolution: {integrity: sha512-s3+eVwNeJuXUwuMbusncZNViuhv2LjVJ1nMwTqSA0XAC7gjKhqqxRdJPhR8+YrkoZ9IiIbFk/yK6ACe/xlF+hw==} - engines: {node: '>=14.0.0'} + '@smithy/util-base64@2.3.0': dependencies: '@smithy/util-buffer-from': 2.2.0 '@smithy/util-utf8': 2.3.0 tslib: 2.6.2 - dev: false - /@smithy/util-body-length-browser@2.2.0: - resolution: {integrity: sha512-dtpw9uQP7W+n3vOtx0CfBD5EWd7EPdIdsQnWTDoFf77e3VUf05uA7R7TGipIo8e4WL2kuPdnsr3hMQn9ziYj5w==} + '@smithy/util-body-length-browser@2.2.0': dependencies: tslib: 2.6.2 - dev: false - /@smithy/util-body-length-node@2.3.0: - resolution: {integrity: sha512-ITWT1Wqjubf2CJthb0BuT9+bpzBfXeMokH/AAa5EJQgbv9aPMVfnM76iFIZVFf50hYXGbtiV71BHAthNWd6+dw==} - engines: {node: '>=14.0.0'} + '@smithy/util-body-length-node@2.3.0': dependencies: tslib: 2.6.2 - dev: false - /@smithy/util-buffer-from@2.2.0: - resolution: {integrity: sha512-IJdWBbTcMQ6DA0gdNhh/BwrLkDR+ADW5Kr1aZmd4k3DIF6ezMV4R2NIAmT08wQJ3yUK82thHWmC/TnK/wpMMIA==} - engines: {node: '>=14.0.0'} + '@smithy/util-buffer-from@2.2.0': dependencies: '@smithy/is-array-buffer': 2.2.0 tslib: 2.6.2 - dev: false - /@smithy/util-config-provider@2.3.0: - resolution: {integrity: sha512-HZkzrRcuFN1k70RLqlNK4FnPXKOpkik1+4JaBoHNJn+RnJGYqaa3c5/+XtLOXhlKzlRgNvyaLieHTW2VwGN0VQ==} - engines: {node: '>=14.0.0'} + '@smithy/util-config-provider@2.3.0': dependencies: tslib: 2.6.2 - dev: false - /@smithy/util-defaults-mode-browser@2.2.1: - resolution: {integrity: sha512-RtKW+8j8skk17SYowucwRUjeh4mCtnm5odCL0Lm2NtHQBsYKrNW0od9Rhopu9wF1gHMfHeWF7i90NwBz/U22Kw==} - engines: {node: '>= 10.0.0'} + '@smithy/util-defaults-mode-browser@2.2.1': dependencies: '@smithy/property-provider': 2.2.0 '@smithy/smithy-client': 2.5.1 '@smithy/types': 2.12.0 bowser: 2.11.0 tslib: 2.6.2 - dev: false - /@smithy/util-defaults-mode-node@2.3.1: - resolution: {integrity: sha512-vkMXHQ0BcLFysBMWgSBLSk3+leMpFSyyFj8zQtv5ZyUBx8/owVh1/pPEkzmW/DR/Gy/5c8vjLDD9gZjXNKbrpA==} - engines: {node: '>= 10.0.0'} + '@smithy/util-defaults-mode-node@2.3.1': dependencies: '@smithy/config-resolver': 2.2.0 '@smithy/credential-provider-imds': 2.3.0 @@ -9015,44 +16157,29 @@ packages: '@smithy/smithy-client': 2.5.1 '@smithy/types': 2.12.0 tslib: 2.6.2 - dev: false - /@smithy/util-endpoints@1.2.0: - resolution: {integrity: sha512-BuDHv8zRjsE5zXd3PxFXFknzBG3owCpjq8G3FcsXW3CykYXuEqM3nTSsmLzw5q+T12ZYuDlVUZKBdpNbhVtlrQ==} - engines: {node: '>= 14.0.0'} + '@smithy/util-endpoints@1.2.0': dependencies: '@smithy/node-config-provider': 2.3.0 '@smithy/types': 2.12.0 tslib: 2.6.2 - dev: false - /@smithy/util-hex-encoding@2.2.0: - resolution: {integrity: sha512-7iKXR+/4TpLK194pVjKiasIyqMtTYJsgKgM242Y9uzt5dhHnUDvMNb+3xIhRJ9QhvqGii/5cRUt4fJn3dtXNHQ==} - engines: {node: '>=14.0.0'} + '@smithy/util-hex-encoding@2.2.0': dependencies: tslib: 2.6.2 - dev: false - /@smithy/util-middleware@2.2.0: - resolution: {integrity: sha512-L1qpleXf9QD6LwLCJ5jddGkgWyuSvWBkJwWAZ6kFkdifdso+sk3L3O1HdmPvCdnCK3IS4qWyPxev01QMnfHSBw==} - engines: {node: '>=14.0.0'} + '@smithy/util-middleware@2.2.0': dependencies: '@smithy/types': 2.12.0 tslib: 2.6.2 - dev: false - /@smithy/util-retry@2.2.0: - resolution: {integrity: sha512-q9+pAFPTfftHXRytmZ7GzLFFrEGavqapFc06XxzZFcSIGERXMerXxCitjOG1prVDR9QdjqotF40SWvbqcCpf8g==} - engines: {node: '>= 14.0.0'} + '@smithy/util-retry@2.2.0': dependencies: '@smithy/service-error-classification': 2.1.5 '@smithy/types': 2.12.0 tslib: 2.6.2 - dev: false - /@smithy/util-stream@2.2.0: - resolution: {integrity: sha512-17faEXbYWIRst1aU9SvPZyMdWmqIrduZjVOqCPMIsWFNxs5yQQgFrJL6b2SdiCzyW9mJoDjFtgi53xx7EH+BXA==} - engines: {node: '>=14.0.0'} + '@smithy/util-stream@2.2.0': dependencies: '@smithy/fetch-http-handler': 2.5.0 '@smithy/node-http-handler': 2.5.0 @@ -9062,109 +16189,55 @@ packages: '@smithy/util-hex-encoding': 2.2.0 '@smithy/util-utf8': 2.3.0 tslib: 2.6.2 - dev: false - /@smithy/util-uri-escape@2.2.0: - resolution: {integrity: sha512-jtmJMyt1xMD/d8OtbVJ2gFZOSKc+ueYJZPW20ULW1GOp/q/YIM0wNh+u8ZFao9UaIGz4WoPW8hC64qlWLIfoDA==} - engines: {node: '>=14.0.0'} + '@smithy/util-uri-escape@2.2.0': dependencies: tslib: 2.6.2 - dev: false - /@smithy/util-utf8@2.3.0: - resolution: {integrity: sha512-R8Rdn8Hy72KKcebgLiv8jQcQkXoLMOGGv5uI1/k0l+snqkOzQ1R0ChUBCxWMlBsFMekWjq0wRudIweFs7sKT5A==} - engines: {node: '>=14.0.0'} + '@smithy/util-utf8@2.3.0': dependencies: '@smithy/util-buffer-from': 2.2.0 tslib: 2.6.2 - dev: false - /@smithy/util-waiter@2.2.0: - resolution: {integrity: sha512-IHk53BVw6MPMi2Gsn+hCng8rFA3ZmR3Rk7GllxDUW9qFJl/hiSvskn7XldkECapQVkIg/1dHpMAxI9xSTaLLSA==} - engines: {node: '>=14.0.0'} + '@smithy/util-waiter@2.2.0': dependencies: '@smithy/abort-controller': 2.2.0 '@smithy/types': 2.12.0 tslib: 2.6.2 - dev: false - /@svgr/babel-plugin-add-jsx-attribute@6.5.1(@babel/core@7.24.4): - resolution: {integrity: sha512-9PYGcXrAxitycIjRmZB+Q0JaN07GZIWaTBIGQzfaZv+qr1n8X1XUEJ5rZ/vx6OVD9RRYlrNnXWExQXcmZeD/BQ==} - engines: {node: '>=10'} - peerDependencies: - '@babel/core': ^7.0.0-0 + '@svgr/babel-plugin-add-jsx-attribute@6.5.1(@babel/core@7.24.4)': dependencies: '@babel/core': 7.24.4 - dev: true - /@svgr/babel-plugin-remove-jsx-attribute@6.5.0(@babel/core@7.24.4): - resolution: {integrity: sha512-8zYdkym7qNyfXpWvu4yq46k41pyNM9SOstoWhKlm+IfdCE1DdnRKeMUPsWIEO/DEkaWxJ8T9esNdG3QwQ93jBA==} - engines: {node: '>=10'} - peerDependencies: - '@babel/core': ^7.0.0-0 + '@svgr/babel-plugin-remove-jsx-attribute@6.5.0(@babel/core@7.24.4)': dependencies: '@babel/core': 7.24.4 - dev: true - /@svgr/babel-plugin-remove-jsx-empty-expression@6.5.0(@babel/core@7.24.4): - resolution: {integrity: sha512-NFdxMq3xA42Kb1UbzCVxplUc0iqSyM9X8kopImvFnB+uSDdzIHOdbs1op8ofAvVRtbg4oZiyRl3fTYeKcOe9Iw==} - engines: {node: '>=10'} - peerDependencies: - '@babel/core': ^7.0.0-0 + '@svgr/babel-plugin-remove-jsx-empty-expression@6.5.0(@babel/core@7.24.4)': dependencies: '@babel/core': 7.24.4 - dev: true - /@svgr/babel-plugin-replace-jsx-attribute-value@6.5.1(@babel/core@7.24.4): - resolution: {integrity: sha512-8DPaVVE3fd5JKuIC29dqyMB54sA6mfgki2H2+swh+zNJoynC8pMPzOkidqHOSc6Wj032fhl8Z0TVn1GiPpAiJg==} - engines: {node: '>=10'} - peerDependencies: - '@babel/core': ^7.0.0-0 + '@svgr/babel-plugin-replace-jsx-attribute-value@6.5.1(@babel/core@7.24.4)': dependencies: '@babel/core': 7.24.4 - dev: true - /@svgr/babel-plugin-svg-dynamic-title@6.5.1(@babel/core@7.24.4): - resolution: {integrity: sha512-FwOEi0Il72iAzlkaHrlemVurgSQRDFbk0OC8dSvD5fSBPHltNh7JtLsxmZUhjYBZo2PpcU/RJvvi6Q0l7O7ogw==} - engines: {node: '>=10'} - peerDependencies: - '@babel/core': ^7.0.0-0 + '@svgr/babel-plugin-svg-dynamic-title@6.5.1(@babel/core@7.24.4)': dependencies: '@babel/core': 7.24.4 - dev: true - /@svgr/babel-plugin-svg-em-dimensions@6.5.1(@babel/core@7.24.4): - resolution: {integrity: sha512-gWGsiwjb4tw+ITOJ86ndY/DZZ6cuXMNE/SjcDRg+HLuCmwpcjOktwRF9WgAiycTqJD/QXqL2f8IzE2Rzh7aVXA==} - engines: {node: '>=10'} - peerDependencies: - '@babel/core': ^7.0.0-0 + '@svgr/babel-plugin-svg-em-dimensions@6.5.1(@babel/core@7.24.4)': dependencies: '@babel/core': 7.24.4 - dev: true - /@svgr/babel-plugin-transform-react-native-svg@6.5.1(@babel/core@7.24.4): - resolution: {integrity: sha512-2jT3nTayyYP7kI6aGutkyfJ7UMGtuguD72OjeGLwVNyfPRBD8zQthlvL+fAbAKk5n9ZNcvFkp/b1lZ7VsYqVJg==} - engines: {node: '>=10'} - peerDependencies: - '@babel/core': ^7.0.0-0 + '@svgr/babel-plugin-transform-react-native-svg@6.5.1(@babel/core@7.24.4)': dependencies: '@babel/core': 7.24.4 - dev: true - /@svgr/babel-plugin-transform-svg-component@6.5.1(@babel/core@7.24.4): - resolution: {integrity: sha512-a1p6LF5Jt33O3rZoVRBqdxL350oge54iZWHNI6LJB5tQ7EelvD/Mb1mfBiZNAan0dt4i3VArkFRjA4iObuNykQ==} - engines: {node: '>=12'} - peerDependencies: - '@babel/core': ^7.0.0-0 + '@svgr/babel-plugin-transform-svg-component@6.5.1(@babel/core@7.24.4)': dependencies: '@babel/core': 7.24.4 - dev: true - /@svgr/babel-preset@6.5.1(@babel/core@7.24.4): - resolution: {integrity: sha512-6127fvO/FF2oi5EzSQOAjo1LE3OtNVh11R+/8FXa+mHx1ptAaS4cknIjnUA7e6j6fwGGJ17NzaTJFUwOV2zwCw==} - engines: {node: '>=10'} - peerDependencies: - '@babel/core': ^7.0.0-0 + '@svgr/babel-preset@6.5.1(@babel/core@7.24.4)': dependencies: '@babel/core': 7.24.4 '@svgr/babel-plugin-add-jsx-attribute': 6.5.1(@babel/core@7.24.4) @@ -9175,11 +16248,8 @@ packages: '@svgr/babel-plugin-svg-em-dimensions': 6.5.1(@babel/core@7.24.4) '@svgr/babel-plugin-transform-react-native-svg': 6.5.1(@babel/core@7.24.4) '@svgr/babel-plugin-transform-svg-component': 6.5.1(@babel/core@7.24.4) - dev: true - /@svgr/core@6.5.1: - resolution: {integrity: sha512-/xdLSWxK5QkqG524ONSjvg3V/FkNyCv538OIBdQqPNaAta3AsXj/Bd2FbvR87yMbXO2hFSWiAe/Q6IkVPDw+mw==} - engines: {node: '>=10'} + '@svgr/core@6.5.1': dependencies: '@babel/core': 7.24.4 '@svgr/babel-preset': 6.5.1(@babel/core@7.24.4) @@ -9188,21 +16258,13 @@ packages: cosmiconfig: 7.1.0 transitivePeerDependencies: - supports-color - dev: true - /@svgr/hast-util-to-babel-ast@6.5.1: - resolution: {integrity: sha512-1hnUxxjd83EAxbL4a0JDJoD3Dao3hmjvyvyEV8PzWmLK3B9m9NPlW7GKjFyoWE8nM7HnXzPcmmSyOW8yOddSXw==} - engines: {node: '>=10'} + '@svgr/hast-util-to-babel-ast@6.5.1': dependencies: '@babel/types': 7.20.2 entities: 4.4.0 - dev: true - /@svgr/plugin-jsx@6.5.1(@svgr/core@6.5.1): - resolution: {integrity: sha512-+UdQxI3jgtSjCykNSlEMuy1jSRQlGC7pqBCPvkG/2dATdWo082zHTTK3uhnAju2/6XpE6B5mZ3z4Z8Ns01S8Gw==} - engines: {node: '>=10'} - peerDependencies: - '@svgr/core': ^6.0.0 + '@svgr/plugin-jsx@6.5.1(@svgr/core@6.5.1)': dependencies: '@babel/core': 7.24.4 '@svgr/babel-preset': 6.5.1(@babel/core@7.24.4) @@ -9211,119 +16273,45 @@ packages: svg-parser: 2.0.4 transitivePeerDependencies: - supports-color - dev: true - /@svgr/plugin-svgo@6.5.1(@svgr/core@6.5.1): - resolution: {integrity: sha512-omvZKf8ixP9z6GWgwbtmP9qQMPX4ODXi+wzbVZgomNFsUIlHA1sf4fThdwTWSsZGgvGAG6yE+b/F5gWUkcZ/iQ==} - engines: {node: '>=10'} - peerDependencies: - '@svgr/core': '*' + '@svgr/plugin-svgo@6.5.1(@svgr/core@6.5.1)': dependencies: '@svgr/core': 6.5.1 cosmiconfig: 7.1.0 deepmerge: 4.3.1 svgo: 2.8.0 - dev: true - /@swc/core-darwin-arm64@1.3.52: - resolution: {integrity: sha512-Y+4YDN7mAhMgqLVMjpIOagFg93uWdQRsJXd3NAXo24CAJXLBuXsiXQdJVdhGavQkF0+NuhFSTGrzB8TknzWQkg==} - engines: {node: '>=10'} - cpu: [arm64] - os: [darwin] - requiresBuild: true - dev: true + '@swc/core-darwin-arm64@1.3.52': optional: true - /@swc/core-darwin-x64@1.3.52: - resolution: {integrity: sha512-XbvBA+DwTedleh/smYA6E1Z1L1tVnF+ULhpszAAW4YYDzH47R73ucCdcSH/aHs4swv+uyvRquKoDtTTNZFvD4A==} - engines: {node: '>=10'} - cpu: [x64] - os: [darwin] - requiresBuild: true - dev: true + '@swc/core-darwin-x64@1.3.52': optional: true - /@swc/core-linux-arm-gnueabihf@1.3.52: - resolution: {integrity: sha512-YRTLjZcoGH09q0vjg5s6vxOryzAGlMx2Ly6Hq8+8ruBtG3QTsCN3y7MI8mX254xdFCJiTX5YwQheGjRXS7FF9A==} - engines: {node: '>=10'} - cpu: [arm] - os: [linux] - requiresBuild: true - dev: true + '@swc/core-linux-arm-gnueabihf@1.3.52': optional: true - /@swc/core-linux-arm64-gnu@1.3.52: - resolution: {integrity: sha512-B0HKtj0XpqpqflGKMxFlyXyORN0xshF8TVzUBD/2FgF7o8fE2RM1eqtdf1EzmZTT1hwxLpJXrEj+0gSXfWPW4A==} - engines: {node: '>=10'} - cpu: [arm64] - os: [linux] - requiresBuild: true - dev: true + '@swc/core-linux-arm64-gnu@1.3.52': optional: true - /@swc/core-linux-arm64-musl@1.3.52: - resolution: {integrity: sha512-GCxNjTAborAmv4VV1AMZLyejHLGgIzu13tvLUFqybtU4jFxVbE2ZK4ZnPCfDlWN+eBwyRWk1oNFR2hH+66vaUQ==} - engines: {node: '>=10'} - cpu: [arm64] - os: [linux] - requiresBuild: true - dev: true + '@swc/core-linux-arm64-musl@1.3.52': optional: true - /@swc/core-linux-x64-gnu@1.3.52: - resolution: {integrity: sha512-mrvDBSkLI3Mza2qcu3uzB5JGwMBYDb1++UQ1VB0RXf2AR21/cCper4P44IpfdeqFz9XyXq18Sh3gblICUCGvig==} - engines: {node: '>=10'} - cpu: [x64] - os: [linux] - requiresBuild: true - dev: true + '@swc/core-linux-x64-gnu@1.3.52': optional: true - /@swc/core-linux-x64-musl@1.3.52: - resolution: {integrity: sha512-r9RIvKUQv7yBkpXz+QxPAucdoj8ymBlgIm5rLE0b5VmU7dlKBnpAmRBYaITdH6IXhF0pwuG+FHAd5elBcrkIwA==} - engines: {node: '>=10'} - cpu: [x64] - os: [linux] - requiresBuild: true - dev: true + '@swc/core-linux-x64-musl@1.3.52': optional: true - /@swc/core-win32-arm64-msvc@1.3.52: - resolution: {integrity: sha512-YRtEr7tDo0Wes3M2ZhigF4erUjWBXeFP+O+iz6ELBBmPG7B7m/lrA21eiW9/90YGnzi0iNo46shK6PfXuPhP+Q==} - engines: {node: '>=10'} - cpu: [arm64] - os: [win32] - requiresBuild: true - dev: true + '@swc/core-win32-arm64-msvc@1.3.52': optional: true - /@swc/core-win32-ia32-msvc@1.3.52: - resolution: {integrity: sha512-t1x6EdYg3nnnmZBkEtmdXwGpVFTnkNCYyTILcn4367tKI6NpcNe75tz6wBUZAWAmol6Bn75je9KHDNC9uBcO2A==} - engines: {node: '>=10'} - cpu: [ia32] - os: [win32] - requiresBuild: true - dev: true + '@swc/core-win32-ia32-msvc@1.3.52': optional: true - /@swc/core-win32-x64-msvc@1.3.52: - resolution: {integrity: sha512-ef0KzcHxWgRii0EyUlgzNA0ycqaRRKxSb6QCO9Ev3tib4SSjbPy0MAndU7f82Ndm/pPmXT+7cciRtZ083vzjZA==} - engines: {node: '>=10'} - cpu: [x64] - os: [win32] - requiresBuild: true - dev: true + '@swc/core-win32-x64-msvc@1.3.52': optional: true - /@swc/core@1.3.52: - resolution: {integrity: sha512-2LOkkl5Ebyzg1e2pu/tqz5zAAiNAtSR99KZDJz4+FTpo6lYwr+SRkeXSNFrYAReHBMb5VJoimrLDLHJ2X1E7Lg==} - engines: {node: '>=10'} - requiresBuild: true - peerDependencies: - '@swc/helpers': ^0.5.0 - peerDependenciesMeta: - '@swc/helpers': - optional: true + '@swc/core@1.3.52': optionalDependencies: '@swc/core-darwin-arm64': 1.3.52 '@swc/core-darwin-x64': 1.3.52 @@ -9335,35 +16323,22 @@ packages: '@swc/core-win32-arm64-msvc': 1.3.52 '@swc/core-win32-ia32-msvc': 1.3.52 '@swc/core-win32-x64-msvc': 1.3.52 - dev: true - /@swc/helpers@0.5.1: - resolution: {integrity: sha512-sJ902EfIzn1Fa+qYmjdQqh8tPsoxyBz+8yBKC2HKUxyezKJFwPGOn7pv4WY6QuQW//ySQi5lJjA/ZT9sNWWNTg==} + '@swc/helpers@0.5.1': dependencies: tslib: 2.6.2 - dev: true - /@swc/jest@0.2.26(@swc/core@1.3.52): - resolution: {integrity: sha512-7lAi7q7ShTO3E5Gt1Xqf3pIhRbERxR1DUxvtVa9WKzIB+HGQ7wZP5sYx86zqnaEoKKGhmOoZ7gyW0IRu8Br5+A==} - engines: {npm: '>= 7.0.0'} - peerDependencies: - '@swc/core': '*' + '@swc/jest@0.2.26(@swc/core@1.3.52)': dependencies: '@jest/create-cache-key-function': 27.5.1 '@swc/core': 1.3.52 jsonc-parser: 3.2.0 - dev: true - /@szmarczak/http-timer@5.0.1: - resolution: {integrity: sha512-+PmQX0PiAYPMeVYe237LJAYvOMYW1j2rH5YROyS3b4CTVJum34HfRvKvAzozHAQG0TnHNdUfY9nCeUyRAs//cw==} - engines: {node: '>=14.16'} + '@szmarczak/http-timer@5.0.1': dependencies: defer-to-connect: 2.0.1 - dev: false - /@testing-library/dom@10.0.0: - resolution: {integrity: sha512-PmJPnogldqoVFf+EwbHvbBJ98MmqASV8kLrBYgsDNxQcFMeIS7JFL48sfyXvuMtgmWO/wMhh25odr+8VhDmn4g==} - engines: {node: '>=18'} + '@testing-library/dom@10.0.0': dependencies: '@babel/code-frame': 7.22.5 '@babel/runtime': 7.21.0 @@ -9373,327 +16348,210 @@ packages: dom-accessibility-api: 0.5.10 lz-string: 1.5.0 pretty-format: 27.5.1 - dev: true - /@testing-library/react-hooks@8.0.1(@types/react@18.0.31)(react-dom@18.2.0)(react@18.2.0): - resolution: {integrity: sha512-Aqhl2IVmLt8IovEVarNDFuJDVWVvhnr9/GCU6UUnrYXwgDFF9h2L2o2P9KBni1AST5sT6riAyoukFLyjQUgD/g==} - engines: {node: '>=12'} - peerDependencies: - '@types/react': ^16.9.0 || ^17.0.0 - react: ^16.9.0 || ^17.0.0 || ^18.0.0 - react-dom: ^16.9.0 || ^17.0.0 - react-test-renderer: ^16.9.0 || ^17.0.0 - peerDependenciesMeta: - '@types/react': - optional: true - react-dom: - optional: true - react-test-renderer: - optional: true + '@testing-library/react-hooks@8.0.1(@types/react@18.0.31)(react-dom@18.2.0)(react@18.2.0)': dependencies: '@babel/runtime': 7.21.0 '@types/react': 18.0.31 react: 18.2.0 react-dom: 18.2.0(react@18.2.0) react-error-boundary: 3.1.4(react@18.2.0) - dev: true - /@testing-library/react@15.0.2(react-dom@18.2.0)(react@18.2.0): - resolution: {integrity: sha512-5mzIpuytB1ctpyywvyaY2TAAUQVCZIGqwiqFQf6u9lvj/SJQepGUzNV18Xpk+NLCaCE2j7CWrZE0tEf9xLZYiQ==} - engines: {node: '>=18'} - peerDependencies: - react: ^18.0.0 - react-dom: ^18.0.0 + '@testing-library/react@15.0.2(react-dom@18.2.0)(react@18.2.0)': dependencies: '@babel/runtime': 7.21.0 '@testing-library/dom': 10.0.0 '@types/react-dom': 18.0.6 react: 18.2.0 react-dom: 18.2.0(react@18.2.0) - dev: true - /@tootallnate/once@2.0.0: - resolution: {integrity: sha512-XCuKFP5PS55gnMVu3dty8KPatLqUoy/ZYzDzAGCQ8JNFCkLXzmI7vNHCR+XpbZaMWQK/vQubr7PkYq8g470J/A==} - engines: {node: '>= 10'} + '@tootallnate/once@2.0.0': {} - /@tootallnate/quickjs-emscripten@0.23.0: - resolution: {integrity: sha512-C5Mc6rdnsaJDjO3UpGW/CQTHtCKaYlScZTly4JIu97Jxo/odCiH0ITnDXSJPTOrEKk/ycSZ0AOgTmkDtkOsvIA==} - dev: true + '@tootallnate/quickjs-emscripten@0.23.0': {} - /@trysound/sax@0.2.0: - resolution: {integrity: sha512-L7z9BgrNEcYyUYtF+HaEfiS5ebkh9jXqbszz7pC0hRBPaatV0XjSD3+eHrpqFemQfgwiFF0QPIarnIihIDn7OA==} - engines: {node: '>=10.13.0'} - dev: true + '@trysound/sax@0.2.0': {} - /@tsconfig/node10@1.0.9: - resolution: {integrity: sha512-jNsYVVxU8v5g43Erja32laIDHXeoNvFEpX33OK4d6hljo3jDhCBDhx5dhCCTMWUojscpAagGiRkBKxpdl9fxqA==} - dev: true + '@tsconfig/node10@1.0.9': {} - /@tsconfig/node12@1.0.11: - resolution: {integrity: sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag==} - dev: true + '@tsconfig/node12@1.0.11': {} - /@tsconfig/node14@1.0.3: - resolution: {integrity: sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow==} - dev: true + '@tsconfig/node14@1.0.3': {} - /@tsconfig/node16@1.0.4: - resolution: {integrity: sha512-vxhUy4J8lyeyinH7Azl1pdd43GJhZH/tP2weN8TntQblOY+A0XbT8DJk1/oCPuOOyg/Ja757rG0CgHcWC8OfMA==} - dev: true + '@tsconfig/node16@1.0.4': {} - /@types/accepts@1.3.5: - resolution: {integrity: sha512-jOdnI/3qTpHABjM5cx1Hc0sKsPoYCp+DP/GJRGtDlPd7fiV9oXGGIcjW/ZOxLIvjGz8MA+uMZI9metHlgqbgwQ==} + '@types/accepts@1.3.5': dependencies: '@types/node': 20.12.7 - /@types/aria-query@5.0.1: - resolution: {integrity: sha512-XTIieEY+gvJ39ChLcB4If5zHtPxt3Syj5rgZR+e1ctpmK8NjPf0zFqsz4JpLJT0xla9GFDKjy8Cpu331nrmE1Q==} - dev: true + '@types/aria-query@5.0.1': {} - /@types/babel__core@7.1.19: - resolution: {integrity: sha512-WEOTgRsbYkvA/KCsDwVEGkd7WAr1e3g31VHQ8zy5gul/V1qKullU/BU5I68X5v7V3GnB9eotmom4v5a5gjxorw==} + '@types/babel__core@7.1.19': dependencies: '@babel/parser': 7.24.4 '@babel/types': 7.24.0 '@types/babel__generator': 7.6.4 '@types/babel__template': 7.4.1 '@types/babel__traverse': 7.18.2 - dev: true - /@types/babel__generator@7.6.4: - resolution: {integrity: sha512-tFkciB9j2K755yrTALxD44McOrk+gfpIpvC3sxHjRawj6PfnQxrse4Clq5y/Rq+G3mrBurMax/lG8Qn2t9mSsg==} + '@types/babel__generator@7.6.4': dependencies: '@babel/types': 7.24.0 - dev: true - /@types/babel__template@7.4.1: - resolution: {integrity: sha512-azBFKemX6kMg5Io+/rdGT0dkGreboUVR0Cdm3fz9QJWpaQGJRQXl7C+6hOTCZcMll7KFyEQpgbYI2lHdsS4U7g==} + '@types/babel__template@7.4.1': dependencies: '@babel/parser': 7.24.4 '@babel/types': 7.24.0 - dev: true - /@types/babel__traverse@7.18.2: - resolution: {integrity: sha512-FcFaxOr2V5KZCviw1TnutEMVUVsGt4D2hP1TAfXZAMKuHYW3xQhe3jTxNPWutgCJ3/X1c5yX8ZoGVEItxKbwBg==} + '@types/babel__traverse@7.18.2': dependencies: '@babel/types': 7.24.0 - dev: true - /@types/body-parser@1.19.2: - resolution: {integrity: sha512-ALYone6pm6QmwZoAgeyNksccT9Q4AWZQ6PvfwR37GT6r6FWUPguq6sUmNGSMV2Wr761oQoBxwGGa6DR5o1DC9g==} + '@types/body-parser@1.19.2': dependencies: '@types/connect': 3.4.35 '@types/node': 20.12.7 - /@types/caseless@0.12.5: - resolution: {integrity: sha512-hWtVTC2q7hc7xZ/RLbxapMvDMgUnDvKvMOpKal4DrMyfGBUfB1oKaZlIRr6mJL+If3bAP6sV/QneGzF6tJjZDg==} - dev: false + '@types/caseless@0.12.5': {} - /@types/co-body@6.1.3: - resolution: {integrity: sha512-UhuhrQ5hclX6UJctv5m4Rfp52AfG9o9+d9/HwjxhVB5NjXxr5t9oKgJxN8xRHgr35oo8meUEHUPFWiKg6y71aA==} + '@types/co-body@6.1.3': dependencies: '@types/node': 20.12.7 '@types/qs': 6.9.7 - dev: false - /@types/color-convert@2.0.0: - resolution: {integrity: sha512-m7GG7IKKGuJUXvkZ1qqG3ChccdIM/qBBo913z+Xft0nKCX4hAU/IxKwZBU4cpRZ7GS5kV4vOblUkILtSShCPXQ==} + '@types/color-convert@2.0.0': dependencies: '@types/color-name': 1.1.1 - dev: true - /@types/color-name@1.1.1: - resolution: {integrity: sha512-rr+OQyAjxze7GgWrSaJwydHStIhHq2lvY3BOC2Mj7KnzI7XK0Uw1TOOdI9lDoajEbSWLiYgoo4f1R51erQfhPQ==} - dev: true + '@types/color-name@1.1.1': {} - /@types/color@3.0.3: - resolution: {integrity: sha512-X//qzJ3d3Zj82J9sC/C18ZY5f43utPbAJ6PhYt/M7uG6etcF6MRpKdN880KBy43B0BMzSfeT96MzrsNjFI3GbA==} + '@types/color@3.0.3': dependencies: '@types/color-convert': 2.0.0 - dev: true - /@types/connect@3.4.35: - resolution: {integrity: sha512-cdeYyv4KWoEgpBISTxWvqYsVy444DOqehiF3fM3ne10AmJ62RSyNkUnxMJXHQWRQQX2eR94m5y1IZyDwBjV9FQ==} + '@types/connect@3.4.35': dependencies: '@types/node': 20.12.7 - /@types/content-disposition@0.5.4: - resolution: {integrity: sha512-0mPF08jn9zYI0n0Q/Pnz7C4kThdSt+6LD4amsrYDDpgBfrVWa3TcCOxKX1zkGgYniGagRv8heN2cbh+CAn+uuQ==} + '@types/content-disposition@0.5.4': {} - /@types/conventional-commits-parser@5.0.0: - resolution: {integrity: sha512-loB369iXNmAZglwWATL+WRe+CRMmmBPtpolYzIebFaX4YA3x+BEfLqhUAV9WanycKI3TG1IMr5bMJDajDKLlUQ==} + '@types/conventional-commits-parser@5.0.0': dependencies: '@types/node': 20.12.7 - dev: true - /@types/cookiejar@2.1.5: - resolution: {integrity: sha512-he+DHOWReW0nghN24E1WUqM0efK4kI9oTqDm6XmK8ZPe2djZ90BSNdGnIyCLzCPw7/pogPlGbzI2wHGGmi4O/Q==} - dev: true + '@types/cookiejar@2.1.5': {} - /@types/cookies@0.7.7: - resolution: {integrity: sha512-h7BcvPUogWbKCzBR2lY4oqaZbO3jXZksexYJVFvkrFeLgbZjQkU4x8pRq6eg2MHXQhY0McQdqmmsxRWlVAHooA==} + '@types/cookies@0.7.7': dependencies: '@types/connect': 3.4.35 '@types/express': 4.17.13 '@types/keygrip': 1.0.2 '@types/node': 20.12.7 - /@types/debug@4.1.7: - resolution: {integrity: sha512-9AonUzyTjXXhEOa0DnqpzZi6VHlqKMswga9EXjpXnnqxwLtdvPPtlO8evrI5D9S6asFRCQ6v+wpiUKbw+vKqyg==} + '@types/debug@4.1.7': dependencies: '@types/ms': 0.7.31 - dev: true - /@types/estree@1.0.5: - resolution: {integrity: sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw==} - dev: true + '@types/estree@1.0.5': {} - /@types/etag@1.8.1: - resolution: {integrity: sha512-bsKkeSqN7HYyYntFRAmzcwx/dKW4Wa+KVMTInANlI72PWLQmOpZu96j0OqHZGArW4VQwCmJPteQlXaUDeOB0WQ==} + '@types/etag@1.8.1': dependencies: '@types/node': 20.12.7 - dev: true - /@types/express-serve-static-core@4.17.26: - resolution: {integrity: sha512-zeu3tpouA043RHxW0gzRxwCHchMgftE8GArRsvYT0ByDMbn19olQHx5jLue0LxWY6iYtXb7rXmuVtSkhy9YZvQ==} + '@types/express-serve-static-core@4.17.26': dependencies: '@types/node': 20.12.7 '@types/qs': 6.9.7 '@types/range-parser': 1.2.4 - /@types/express@4.17.13: - resolution: {integrity: sha512-6bSZTPaTIACxn48l50SR+axgrqm6qXFIxrdAKaG6PaJk3+zuUr35hBlgT7vOmJcum+OEaIBLtHV/qloEAFITeA==} + '@types/express@4.17.13': dependencies: '@types/body-parser': 1.19.2 '@types/express-serve-static-core': 4.17.26 '@types/qs': 6.9.7 '@types/serve-static': 1.13.10 - /@types/formidable@2.0.6: - resolution: {integrity: sha512-L4HcrA05IgQyNYJj6kItuIkXrInJvsXTPC5B1i64FggWKKqSL+4hgt7asiSNva75AoLQjq29oPxFfU4GAQ6Z2w==} + '@types/formidable@2.0.6': dependencies: '@types/node': 20.12.7 - dev: false - /@types/graceful-fs@4.1.5: - resolution: {integrity: sha512-anKkLmZZ+xm4p8JWBf4hElkM4XR+EZeA2M9BAkkTldmcyDY4mbdIJnRghDJH3Ov5ooY7/UAoENtmdMSkaAd7Cw==} + '@types/graceful-fs@4.1.5': dependencies: '@types/node': 20.12.7 - dev: true - /@types/hast@2.3.4: - resolution: {integrity: sha512-wLEm0QvaoawEDoTRwzTXp4b4jpwiJDvR5KMnFnVodm3scufTlBOWRD6N1OBf9TZMhjlNsSfcO5V+7AF4+Vy+9g==} + '@types/hast@2.3.4': dependencies: '@types/unist': 3.0.0 - dev: true - /@types/hast@3.0.1: - resolution: {integrity: sha512-hs/iBJx2aydugBQx5ETV3ZgeSS0oIreQrFJ4bjBl0XvM4wAmDjFEALY7p0rTSLt2eL+ibjRAAs9dTPiCLtmbqQ==} + '@types/hast@3.0.1': dependencies: '@types/unist': 2.0.6 - dev: true - /@types/history@4.7.11: - resolution: {integrity: sha512-qjDJRrmvBMiTx+jyLxvLfJU7UznFuokDv4f3WRuriHKERccVpFU+8XMQUAbDzoiJCsmexxRExQeMwwCdamSKDA==} - dev: true + '@types/history@4.7.11': {} - /@types/http-assert@1.5.3: - resolution: {integrity: sha512-FyAOrDuQmBi8/or3ns4rwPno7/9tJTijVW6aQQjK02+kOQ8zmoNg2XJtAuQhvQcy1ASJq38wirX5//9J1EqoUA==} + '@types/http-assert@1.5.3': {} - /@types/http-cache-semantics@4.0.4: - resolution: {integrity: sha512-1m0bIFVc7eJWyve9S0RnuRgcQqF/Xd5QsUZAZeQFr1Q3/p9JWoQQEqmVy+DPTNpGXwhgIetAoYF8JSc33q29QA==} - dev: false + '@types/http-cache-semantics@4.0.4': {} - /@types/http-errors@1.8.2: - resolution: {integrity: sha512-EqX+YQxINb+MeXaIqYDASb6U6FCHbWjkj4a1CKDBks3d/QiB2+PqBLyO72vLDgAO1wUI4O+9gweRcQK11bTL/w==} + '@types/http-errors@1.8.2': {} - /@types/inquirer@9.0.3: - resolution: {integrity: sha512-CzNkWqQftcmk2jaCWdBTf9Sm7xSw4rkI1zpU/Udw3HX5//adEZUIm9STtoRP1qgWj0CWQtJ9UTvqmO2NNjhMJw==} + '@types/inquirer@9.0.3': dependencies: '@types/through': 0.0.30 rxjs: 7.8.0 - dev: true - /@types/is-ci@3.0.0: - resolution: {integrity: sha512-Q0Op0hdWbYd1iahB+IFNQcWXFq4O0Q5MwQP7uN0souuQ4rPg1vEYcnIOfr1gY+M+6rc8FGoRaBO1mOOvL29sEQ==} + '@types/is-ci@3.0.0': dependencies: ci-info: 3.8.0 - dev: true - /@types/istanbul-lib-coverage@2.0.4: - resolution: {integrity: sha512-z/QT1XN4K4KYuslS23k62yDIDLwLFkzxOuMplDtObz0+y7VqJCaO2o+SPwHCvLFZh7xazvvoor2tA/hPz9ee7g==} - dev: true + '@types/istanbul-lib-coverage@2.0.4': {} - /@types/istanbul-lib-report@3.0.0: - resolution: {integrity: sha512-plGgXAPfVKFoYfa9NpYDAkseG+g6Jr294RqeqcqDixSbU34MZVJRi/P+7Y8GDpzkEwLaGZZOpKIEmeVZNtKsrg==} + '@types/istanbul-lib-report@3.0.0': dependencies: '@types/istanbul-lib-coverage': 2.0.4 - dev: true - /@types/istanbul-reports@3.0.1: - resolution: {integrity: sha512-c3mAZEuK0lvBp8tmuL74XRKn1+y2dcwOUpH7x4WrF6gk1GIgiluDRgMYQtw2OFcBvAJWlt6ASU3tSqxp0Uu0Aw==} + '@types/istanbul-reports@3.0.1': dependencies: '@types/istanbul-lib-report': 3.0.0 - dev: true - /@types/jest@29.4.0: - resolution: {integrity: sha512-VaywcGQ9tPorCX/Jkkni7RWGFfI11whqzs8dvxF41P17Z+z872thvEvlIbznjPJ02kl1HMX3LmLOonsj2n7HeQ==} + '@types/jest@29.4.0': dependencies: expect: 29.7.0 pretty-format: 29.7.0 - dev: true - /@types/jsdom@20.0.0: - resolution: {integrity: sha512-YfAchFs0yM1QPDrLm2VHe+WHGtqms3NXnXAMolrgrVP6fgBHHXy1ozAbo/dFtPNtZC/m66bPiCTWYmqp1F14gA==} + '@types/jsdom@20.0.0': dependencies: '@types/node': 20.12.7 '@types/tough-cookie': 4.0.2 parse5: 7.1.1 - dev: true - /@types/json-schema@7.0.15: - resolution: {integrity: sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==} - dev: true + '@types/json-schema@7.0.15': {} - /@types/json5@0.0.29: - resolution: {integrity: sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ==} - dev: true + '@types/json5@0.0.29': {} - /@types/keygrip@1.0.2: - resolution: {integrity: sha512-GJhpTepz2udxGexqos8wgaBx4I/zWIDPh/KOGEwAqtuGDkOUJu5eFvwmdBX4AmB8Odsr+9pHCQqiAqDL/yKMKw==} + '@types/keygrip@1.0.2': {} - /@types/koa-compose@3.2.5: - resolution: {integrity: sha512-B8nG/OoE1ORZqCkBVsup/AKcvjdgoHnfi4pZMn5UwAPCbhk/96xyv284eBYW8JlQbQ7zDmnpFr68I/40mFoIBQ==} + '@types/koa-compose@3.2.5': dependencies: '@types/koa': 2.13.4 - /@types/koa-compress@4.0.3: - resolution: {integrity: sha512-nJSII/tOSvYCwk3yDEBJLHd8ctkt5CQFZ0j8ZBnHZ2x0hg24z9H1i38lWXA/5z0Ix0uitMW1jov+kVbQI1aNPQ==} + '@types/koa-compress@4.0.3': dependencies: '@types/koa': 2.13.4 '@types/node': 20.12.7 - dev: true - /@types/koa-logger@3.1.2: - resolution: {integrity: sha512-sioTA1xlKYiIgryANWPRHBkG3XGbWftw9slWADUPC+qvPIY/yRLSrhvX7zkJwMrntub5dPO0GuAoyGGf0yitfQ==} + '@types/koa-logger@3.1.2': dependencies: '@types/koa': 2.13.4 - dev: true - /@types/koa-mount@4.0.1: - resolution: {integrity: sha512-HNeg80CVS9Dfq8dGYqCZZCAUm7g6jPCNJ1ydqVLEJxLrjmeburpvq+lOZkE4rxBZ6O38dr3tj9IA3IfbdoI05w==} + '@types/koa-mount@4.0.1': dependencies: '@types/koa': 2.13.4 - dev: true - /@types/koa-send@4.1.3: - resolution: {integrity: sha512-daaTqPZlgjIJycSTNjKpHYuKhXYP30atFc1pBcy6HHqB9+vcymDgYTguPdx9tO4HMOqNyz6bz/zqpxt5eLR+VA==} + '@types/koa-send@4.1.3': dependencies: '@types/koa': 2.13.4 - dev: true - /@types/koa@2.13.4: - resolution: {integrity: sha512-dfHYMfU+z/vKtQB7NUrthdAEiSvnLebvBjwHtfFmpZmB7em2N3WVQdHgnFq+xvyVgxW5jKDmjWfLD3lw4g4uTw==} + '@types/koa@2.13.4': dependencies: '@types/accepts': 1.3.5 '@types/content-disposition': 0.5.4 @@ -9704,8 +16562,7 @@ packages: '@types/koa-compose': 3.2.5 '@types/node': 20.12.7 - /@types/koa@2.15.0: - resolution: {integrity: sha512-7QFsywoE5URbuVnG3loe03QXuGajrnotr3gQkXcEBShORai23MePfFYdhz90FEtBBpkyIYQbVD+evKtloCgX3g==} + '@types/koa@2.15.0': dependencies: '@types/accepts': 1.3.5 '@types/content-disposition': 0.5.4 @@ -9715,335 +16572,213 @@ packages: '@types/keygrip': 1.0.2 '@types/koa-compose': 3.2.5 '@types/node': 20.12.7 - dev: false - /@types/koa__cors@5.0.0: - resolution: {integrity: sha512-LCk/n25Obq5qlernGOK/2LUwa/2YJb2lxHUkkvYFDOpLXlVI6tKcdfCHRBQnOY4LwH6el5WOLs6PD/a8Uzau6g==} + '@types/koa__cors@5.0.0': dependencies: '@types/koa': 2.13.4 - dev: true - /@types/mdast@3.0.10: - resolution: {integrity: sha512-W864tg/Osz1+9f4lrGTZpCSO5/z4608eUp19tbozkq2HJK6i3z1kT0H9tlADXuYIb1YYOBByU4Jsqkk75q48qA==} + '@types/mdast@3.0.10': dependencies: '@types/unist': 3.0.0 - dev: true - /@types/mdast@4.0.1: - resolution: {integrity: sha512-IlKct1rUTJ1T81d8OHzyop15kGv9A/ff7Gz7IJgrk6jDb4Udw77pCJ+vq8oxZf4Ghpm+616+i1s/LNg/Vh7d+g==} + '@types/mdast@4.0.1': dependencies: '@types/unist': 3.0.0 - dev: true - /@types/mdx-js__react@1.5.5: - resolution: {integrity: sha512-k8pnaP6JXVlQh18HgL5X6sYFNC/qZnzO7R2+HsmwrwUd+JnnsU0d9lyyT0RQrHg1anxDU36S98TI/fsGtmYqqg==} + '@types/mdx-js__react@1.5.5': dependencies: '@types/react': 18.0.31 - dev: true - /@types/mdx@2.0.1: - resolution: {integrity: sha512-JPEv4iAl0I+o7g8yVWDwk30es8mfVrjkvh5UeVR2sYPpZCK44vrAPsbJpIS+rJAUxLgaSAMKTEH5Vn5qd9XsrQ==} - dev: true + '@types/mdx@2.0.1': {} - /@types/methods@1.1.4: - resolution: {integrity: sha512-ymXWVrDiCxTBE3+RIrrP533E70eA+9qu7zdWoHuOmGujkYtzf4HQF96b8nwHLqhuf4ykX61IGRIB38CC6/sImQ==} - dev: true + '@types/methods@1.1.4': {} - /@types/mime@1.3.2: - resolution: {integrity: sha512-YATxVxgRqNH6nHEIsvg6k2Boc1JHI9ZbH5iWFFv/MTkchz3b1ieGDa5T0a9RznNdI0KhVbdbWSN+KWWrQZRxTw==} + '@types/mime@1.3.2': {} - /@types/minimist@1.2.2: - resolution: {integrity: sha512-jhuKLIRrhvCPLqwPcx6INqmKeiA5EWrsCOPhrlFSrbrmU4ZMPjj5Ul/oLCMDO98XRUIwVm78xICz4EPCektzeQ==} - dev: true + '@types/minimist@1.2.2': {} - /@types/ms@0.7.31: - resolution: {integrity: sha512-iiUgKzV9AuaEkZqkOLDIvlQiL6ltuZd9tGcW3gwpnX8JbuiuhFlEGmmFXEXkN50Cvq7Os88IY2v0dkDqXYWVgA==} - dev: true + '@types/ms@0.7.31': {} - /@types/node-fetch@2.6.2: - resolution: {integrity: sha512-DHqhlq5jeESLy19TYhLakJ07kNumXWjcDdxXsLUMJZ6ue8VZJj4kLPQVE/2mdHh3xZziNF1xppu5lwmS53HR+A==} + '@types/node-fetch@2.6.2': dependencies: '@types/node': 20.12.7 form-data: 3.0.1 - dev: false - /@types/node@12.20.55: - resolution: {integrity: sha512-J8xLz7q2OFulZ2cyGTLE1TbbZcjpno7FaN6zdJNrgAdrJ+DZzh/uFR6YrTb4C+nXakvud8Q4+rbhoIWlYQbUFQ==} - dev: true + '@types/node@12.20.55': {} - /@types/node@20.10.4: - resolution: {integrity: sha512-D08YG6rr8X90YB56tSIuBaddy/UXAA9RKJoFvrsnogAum/0pmjkgi4+2nx96A330FmioegBWmEYQ+syqCFaveg==} + '@types/node@20.10.4': dependencies: undici-types: 5.26.5 - dev: true - /@types/node@20.11.20: - resolution: {integrity: sha512-7/rR21OS+fq8IyHTgtLkDK949uzsa6n8BkziAKtPVpugIkO6D+/ooXMvzXxDnZrmtXVfjb1bKQafYpb8s89LOg==} + '@types/node@20.11.20': dependencies: undici-types: 5.26.5 - dev: true - /@types/node@20.12.7: - resolution: {integrity: sha512-wq0cICSkRLVaf3UGLMGItu/PtdY7oaXaI/RVU+xliKVOtRna3PRY57ZDfztpDL0n11vfymMUnXv8QwYCO7L1wg==} + '@types/node@20.12.7': dependencies: undici-types: 5.26.5 - /@types/nodemailer@6.4.7: - resolution: {integrity: sha512-f5qCBGAn/f0qtRcd4SEn88c8Fp3Swct1731X4ryPKqS61/A3LmmzN8zaEz7hneJvpjFbUUgY7lru/B/7ODTazg==} + '@types/nodemailer@6.4.7': dependencies: '@types/node': 20.12.7 - dev: true - /@types/normalize-package-data@2.4.1: - resolution: {integrity: sha512-Gj7cI7z+98M282Tqmp2K5EIsoouUEzbBJhQQzDE3jSIRk6r9gsz0oUokqIUR4u1R3dMHo0pDHM7sNOHyhulypw==} - dev: true + '@types/normalize-package-data@2.4.1': {} - /@types/oidc-provider@8.4.4: - resolution: {integrity: sha512-+SlmKc4qlCJLjpw6Du/8cXw18JsPEYyQwoy+xheLkiuNsCz1mPEYI/lRXLQHvfJD9TH6+2/WDTLZQ2UUJ5G4bw==} + '@types/oidc-provider@8.4.4': dependencies: '@types/koa': 2.13.4 '@types/node': 20.12.7 - dev: true - /@types/parse-json@4.0.0: - resolution: {integrity: sha512-//oorEZjL6sbPcKUaCdIGlIUeH26mgzimjBB77G6XRgnDl/L5wOnpyBGRe/Mmf5CVW3PwEBE1NjiMZ/ssFh4wA==} - dev: true + '@types/parse-json@4.0.0': {} - /@types/parse5@5.0.3: - resolution: {integrity: sha512-kUNnecmtkunAoQ3CnjmMkzNU/gtxG8guhi+Fk2U/kOpIKjIMKnXGp4IJCgQJrXSgMsWYimYG4TGjz/UzbGEBTw==} - dev: true + '@types/parse5@5.0.3': {} - /@types/pg@8.11.2: - resolution: {integrity: sha512-G2Mjygf2jFMU/9hCaTYxJrwdObdcnuQde1gndooZSOHsNSaCehAuwc7EIuSA34Do8Jx2yZ19KtvW8P0j4EuUXw==} + '@types/pg@8.11.2': dependencies: '@types/node': 20.12.7 pg-protocol: 1.6.0 pg-types: 4.0.2 - /@types/pg@8.6.6: - resolution: {integrity: sha512-O2xNmXebtwVekJDD+02udOncjVcMZQuTEQEMpKJ0ZRf5E7/9JJX3izhKUcUifBkyKpljyUM6BTgy2trmviKlpw==} + '@types/pg@8.6.6': dependencies: '@types/node': 20.12.7 pg-protocol: 1.6.0 pg-types: 2.2.0 - dev: true - /@types/pluralize@0.0.33: - resolution: {integrity: sha512-JOqsl+ZoCpP4e8TDke9W79FDcSgPAR0l6pixx2JHkhnRjvShyYiAYw2LVsnA7K08Y6DeOnaU6ujmENO4os/cYg==} - dev: true + '@types/pluralize@0.0.33': {} - /@types/prop-types@15.7.4: - resolution: {integrity: sha512-rZ5drC/jWjrArrS8BR6SIr4cWpW09RNTYt9AMZo3Jwwif+iacXAqgVjm0B0Bv/S1jhDXKHqRVNCbACkJ89RAnQ==} - dev: true + '@types/prop-types@15.7.4': {} - /@types/qrcode@1.5.2: - resolution: {integrity: sha512-W4KDz75m7rJjFbyCctzCtRzZUj+PrUHV+YjqDp50sSRezTbrtEAIq2iTzC6lISARl3qw+8IlcCyljdcVJE0Wug==} + '@types/qrcode@1.5.2': dependencies: '@types/node': 20.12.7 - dev: true - /@types/qs@6.9.7: - resolution: {integrity: sha512-FGa1F62FT09qcrueBA6qYTrJPVDzah9a+493+o2PCXsesWHIn27G98TsSMs3WPNbZIEj4+VJf6saSFpvD+3Zsw==} + '@types/qs@6.9.7': {} - /@types/range-parser@1.2.4: - resolution: {integrity: sha512-EEhsLsD6UsDM1yFhAvy0Cjr6VwmpMWqFBCb9w07wVugF7w9nfajxLuVmngTIpgS6svCnm6Vaw+MZhoDCKnOfsw==} + '@types/range-parser@1.2.4': {} - /@types/react-color@3.0.6: - resolution: {integrity: sha512-OzPIO5AyRmLA7PlOyISlgabpYUa3En74LP8mTMa0veCA719SvYQov4WLMsHvCgXP+L+KI9yGhYnqZafVGG0P4w==} + '@types/react-color@3.0.6': dependencies: '@types/react': 18.0.31 '@types/reactcss': 1.2.6 - dev: true - /@types/react-dom@18.0.6: - resolution: {integrity: sha512-/5OFZgfIPSwy+YuIBP/FgJnQnsxhZhjjrnxudMddeblOouIodEQ75X14Rr4wGSG/bknL+Omy9iWlLo1u/9GzAA==} + '@types/react-dom@18.0.6': dependencies: '@types/react': 18.0.31 - dev: true - /@types/react-helmet@6.1.6: - resolution: {integrity: sha512-ZKcoOdW/Tg+kiUbkFCBtvDw0k3nD4HJ/h/B9yWxN4uDO8OkRksWTO+EL+z/Qu3aHTeTll3Ro0Cc/8UhwBCMG5A==} + '@types/react-helmet@6.1.6': dependencies: '@types/react': 18.0.31 - dev: true - /@types/react-modal@3.13.1: - resolution: {integrity: sha512-iY/gPvTDIy6Z+37l+ibmrY+GTV4KQTHcCyR5FIytm182RQS69G5ps4PH2FxtC7bAQ2QRHXMevsBgck7IQruHNg==} + '@types/react-modal@3.13.1': dependencies: '@types/react': 18.0.31 - dev: true - /@types/react-router-dom@5.3.2: - resolution: {integrity: sha512-ELEYRUie2czuJzaZ5+ziIp9Hhw+juEw8b7C11YNA4QdLCVbQ3qLi2l4aq8XnlqM7V31LZX8dxUuFUCrzHm6sqQ==} + '@types/react-router-dom@5.3.2': dependencies: '@types/history': 4.7.11 '@types/react': 18.0.31 '@types/react-router': 5.1.17 - dev: true - /@types/react-router@5.1.17: - resolution: {integrity: sha512-RNSXOyb3VyRs/EOGmjBhhGKTbnN6fHWvy5FNLzWfOWOGjgVUKqJZXfpKzLmgoU8h6Hj8mpALj/mbXQASOb92wQ==} + '@types/react-router@5.1.17': dependencies: '@types/history': 4.7.11 '@types/react': 18.0.31 - dev: true - /@types/react-syntax-highlighter@15.5.1: - resolution: {integrity: sha512-+yD6D8y21JqLf89cRFEyRfptVMqo2ROHyAlysRvFwT28gT5gDo3KOiXHwGilHcq9y/OKTjlWK0f/hZUicrBFPQ==} + '@types/react-syntax-highlighter@15.5.1': dependencies: '@types/react': 18.0.31 - dev: true - /@types/react@18.0.31: - resolution: {integrity: sha512-EEG67of7DsvRDU6BLLI0p+k1GojDLz9+lZsnCpCRTa/lOokvyPBvp8S5x+A24hME3yyQuIipcP70KJ6H7Qupww==} + '@types/react@18.0.31': dependencies: '@types/prop-types': 15.7.4 '@types/scheduler': 0.16.2 csstype: 3.0.11 - dev: true - /@types/reactcss@1.2.6: - resolution: {integrity: sha512-qaIzpCuXNWomGR1Xq8SCFTtF4v8V27Y6f+b9+bzHiv087MylI/nTCqqdChNeWS7tslgROmYB7yeiruWX7WnqNg==} + '@types/reactcss@1.2.6': dependencies: '@types/react': 18.0.31 - dev: true - /@types/request@2.48.12: - resolution: {integrity: sha512-G3sY+NpsA9jnwm0ixhAFQSJ3Q9JkpLZpJbI3GMv0mIAT0y3mRabYeINzal5WOChIiaTEGQYlHOKgkaM9EisWHw==} + '@types/request@2.48.12': dependencies: '@types/caseless': 0.12.5 '@types/node': 20.12.7 '@types/tough-cookie': 4.0.2 form-data: 2.5.1 - dev: false - /@types/resolve@1.20.2: - resolution: {integrity: sha512-60BCwRFOZCQhDncwQdxxeOEEkbc5dIMccYLwbxsS4TUNeVECQ/pBJ0j09mrHOl/JJvpRPGwO9SvE4nR2Nb/a4Q==} - dev: true + '@types/resolve@1.20.2': {} - /@types/retry@0.12.2: - resolution: {integrity: sha512-XISRgDJ2Tc5q4TRqvgJtzsRkFYNJzZrhTdtMoGVBttwzzQJkPnS3WWTFc7kuDRoPtPakl+T+OfdEUjYJj7Jbow==} - dev: false + '@types/retry@0.12.2': {} - /@types/scheduler@0.16.2: - resolution: {integrity: sha512-hppQEBDmlwhFAXKJX2KnWLYu5yMfi91yazPb2l+lbJiwW+wdo1gNeRA+3RgNSO39WYX2euey41KEwnqesU2Jew==} - dev: true + '@types/scheduler@0.16.2': {} - /@types/semver@7.3.12: - resolution: {integrity: sha512-WwA1MW0++RfXmCr12xeYOOC5baSC9mSb0ZqCquFzKhcoF4TvHu5MKOuXsncgZcpVFhB1pXd5hZmM0ryAoCp12A==} - dev: true + '@types/semver@7.3.12': {} - /@types/semver@7.5.0: - resolution: {integrity: sha512-G8hZ6XJiHnuhQKR7ZmysCeJWE08o8T0AXtk5darsCaTVsYZhhgUrq53jizaR2FvsoeCwJhlmwTjkXBY5Pn/ZHw==} - dev: true + '@types/semver@7.5.0': {} - /@types/semver@7.5.8: - resolution: {integrity: sha512-I8EUhyrgfLrcTkzV3TSsGyl1tSuPrEDzr0yd5m90UgNxQkyDXULk3b6MlQqTCpZpNtWe1K0hzclnZkTcLBe2UQ==} - dev: true + '@types/semver@7.5.8': {} - /@types/serve-static@1.13.10: - resolution: {integrity: sha512-nCkHGI4w7ZgAdNkrEu0bv+4xNV/XDqW+DydknebMOQwkpDGx8G+HTlj7R7ABI8i8nKxVw0wtKPi1D+lPOkh4YQ==} + '@types/serve-static@1.13.10': dependencies: '@types/mime': 1.3.2 '@types/node': 20.12.7 - /@types/shimmer@1.0.2: - resolution: {integrity: sha512-dKkr1bTxbEsFlh2ARpKzcaAmsYixqt9UyCdoEZk8rHyE4iQYcDCyvSjDSf7JUWJHlJiTtbIoQjxKh6ViywqDAg==} - dev: false + '@types/shimmer@1.0.2': {} - /@types/sinon@17.0.2: - resolution: {integrity: sha512-Zt6heIGsdqERkxctIpvN5Pv3edgBrhoeb3yHyxffd4InN0AX2SVNKSrhdDZKGQICVOxWP/q4DyhpfPNMSrpIiA==} + '@types/sinon@17.0.2': dependencies: '@types/sinonjs__fake-timers': 8.1.2 - dev: true - /@types/sinonjs__fake-timers@8.1.2: - resolution: {integrity: sha512-9GcLXF0/v3t80caGs5p2rRfkB+a8VBGLJZVih6CNFkx8IZ994wiKKLSRs9nuFwk1HevWs/1mnUmkApGrSGsShA==} - dev: true + '@types/sinonjs__fake-timers@8.1.2': {} - /@types/stack-utils@2.0.1: - resolution: {integrity: sha512-Hl219/BT5fLAaz6NDkSuhzasy49dwQS/DSdu4MdggFB8zcXv7vflBI3xp7FEmkmdDkBUI2bPUNeMttp2knYdxw==} - dev: true + '@types/stack-utils@2.0.1': {} - /@types/superagent@8.1.1: - resolution: {integrity: sha512-YQyEXA4PgCl7EVOoSAS3o0fyPFU6erv5mMixztQYe1bqbWmmn8c+IrqoxjQeZe4MgwXikgcaZPiI/DsbmOVlzA==} + '@types/superagent@8.1.1': dependencies: '@types/cookiejar': 2.1.5 '@types/methods': 1.1.4 '@types/node': 20.12.7 - dev: true - /@types/supertest@6.0.2: - resolution: {integrity: sha512-137ypx2lk/wTQbW6An6safu9hXmajAifU/s7szAHLN/FeIm5w7yR0Wkl9fdJMRSHwOn4HLAI0DaB2TOORuhPDg==} + '@types/supertest@6.0.2': dependencies: '@types/methods': 1.1.4 '@types/superagent': 8.1.1 - dev: true - /@types/tar@6.1.12: - resolution: {integrity: sha512-FwbJPi9YuovB6ilnHrz8Y4pb0Fh6N7guFkbnlCl39ua893Qi5gkXui7LSDpTQMJCmA4z5f6SeSrTPQEWLdtFVw==} + '@types/tar@6.1.12': dependencies: '@types/node': 20.11.20 minipass: 4.2.8 - dev: true - /@types/through@0.0.30: - resolution: {integrity: sha512-FvnCJljyxhPM3gkRgWmxmDZyAQSiBQQWLI0A0VFL0K7W1oRUrPJSqNO0NvTnLkBcotdlp3lKvaT0JrnyRDkzOg==} + '@types/through@0.0.30': dependencies: '@types/node': 20.12.7 - dev: true - /@types/tough-cookie@4.0.2: - resolution: {integrity: sha512-Q5vtl1W5ue16D+nIaW8JWebSSraJVlK+EthKn7e7UcD4KWsaSJ8BqGPXNaPghgtcn/fhvrN17Tv8ksUsQpiplw==} + '@types/tough-cookie@4.0.2': {} - /@types/tunnel@0.0.3: - resolution: {integrity: sha512-sOUTGn6h1SfQ+gbgqC364jLFBw2lnFqkgF3q0WovEHRLMrVD1sd5aufqi/aJObLekJO+Aq5z646U4Oxy6shXMA==} + '@types/tunnel@0.0.3': dependencies: '@types/node': 20.12.7 - dev: false - /@types/unist@2.0.6: - resolution: {integrity: sha512-PBjIUxZHOuj0R15/xuwJYjFi+KZdNFrehocChv4g5hu6aFroHue8m0lBP0POdK2nKzbw0cgV1mws8+V/JAcEkQ==} - dev: true + '@types/unist@2.0.6': {} - /@types/unist@3.0.0: - resolution: {integrity: sha512-MFETx3tbTjE7Uk6vvnWINA/1iJ7LuMdO4fcq8UfF0pRbj01aGLduVvQcRyswuACJdpnHgg8E3rQLhaRdNEJS0w==} - dev: true + '@types/unist@3.0.0': {} - /@types/yargs-parser@21.0.0: - resolution: {integrity: sha512-iO9ZQHkZxHn4mSakYV0vFHAVDyEOIJQrV2uZ06HxEPcx+mt8swXoZHIbaaJ2crJYFfErySgktuTZ3BeLz+XmFA==} - dev: true + '@types/yargs-parser@21.0.0': {} - /@types/yargs@16.0.4: - resolution: {integrity: sha512-T8Yc9wt/5LbJyCaLiHPReJa0kApcIgJ7Bn735GjItUfh08Z1pJvu8QZqb9s+mMvKV6WUQRV7K2R46YbjMXTTJw==} + '@types/yargs@16.0.4': dependencies: '@types/yargs-parser': 21.0.0 - dev: true - /@types/yargs@17.0.13: - resolution: {integrity: sha512-9sWaruZk2JGxIQU+IhI1fhPYRcQ0UuTNuKuCW9bR5fp7qi2Llf7WDzNa17Cy7TKnh3cdxDOiyTu6gaLS0eDatg==} + '@types/yargs@17.0.13': dependencies: '@types/yargs-parser': 21.0.0 - dev: true - /@types/yauzl@2.10.3: - resolution: {integrity: sha512-oJoftv0LSuaDZE3Le4DbKX+KS9G36NzOeSap90UIK0yMA/NhKJhqlSGtNDORNRaIbQfzjXDrQa0ytJ6mNRGz/Q==} - requiresBuild: true + '@types/yauzl@2.10.3': dependencies: '@types/node': 20.12.7 - dev: true optional: true - /@typescript-eslint/eslint-plugin@7.7.0(@typescript-eslint/parser@7.7.0)(eslint@8.57.0)(typescript@5.3.3): - resolution: {integrity: sha512-GJWR0YnfrKnsRoluVO3PRb9r5aMZriiMMM/RHj5nnTrBy1/wIgk76XCtCKcnXGjpZQJQRFtGV9/0JJ6n30uwpQ==} - engines: {node: ^18.18.0 || >=20.0.0} - peerDependencies: - '@typescript-eslint/parser': ^7.0.0 - eslint: ^8.56.0 - typescript: '*' - peerDependenciesMeta: - typescript: - optional: true + '@typescript-eslint/eslint-plugin@7.7.0(@typescript-eslint/parser@7.7.0)(eslint@8.57.0)(typescript@5.3.3)': dependencies: '@eslint-community/regexpp': 4.10.0 '@typescript-eslint/parser': 7.7.0(eslint@8.57.0)(typescript@5.3.3) @@ -10061,17 +16796,8 @@ packages: typescript: 5.3.3 transitivePeerDependencies: - supports-color - dev: true - /@typescript-eslint/parser@7.7.0(eslint@8.57.0)(typescript@5.3.3): - resolution: {integrity: sha512-fNcDm3wSwVM8QYL4HKVBggdIPAy9Q41vcvC/GtDobw3c4ndVT3K6cqudUmjHPw8EAp4ufax0o58/xvWaP2FmTg==} - engines: {node: ^18.18.0 || >=20.0.0} - peerDependencies: - eslint: ^8.56.0 - typescript: '*' - peerDependenciesMeta: - typescript: - optional: true + '@typescript-eslint/parser@7.7.0(eslint@8.57.0)(typescript@5.3.3)': dependencies: '@typescript-eslint/scope-manager': 7.7.0 '@typescript-eslint/types': 7.7.0 @@ -10082,25 +16808,13 @@ packages: typescript: 5.3.3 transitivePeerDependencies: - supports-color - dev: true - /@typescript-eslint/scope-manager@7.7.0: - resolution: {integrity: sha512-/8INDn0YLInbe9Wt7dK4cXLDYp0fNHP5xKLHvZl3mOT5X17rK/YShXaiNmorl+/U4VKCVIjJnx4Ri5b0y+HClw==} - engines: {node: ^18.18.0 || >=20.0.0} + '@typescript-eslint/scope-manager@7.7.0': dependencies: '@typescript-eslint/types': 7.7.0 '@typescript-eslint/visitor-keys': 7.7.0 - dev: true - /@typescript-eslint/type-utils@7.7.0(eslint@8.57.0)(typescript@5.3.3): - resolution: {integrity: sha512-bOp3ejoRYrhAlnT/bozNQi3nio9tIgv3U5C0mVDdZC7cpcQEDZXvq8inrHYghLVwuNABRqrMW5tzAv88Vy77Sg==} - engines: {node: ^18.18.0 || >=20.0.0} - peerDependencies: - eslint: ^8.56.0 - typescript: '*' - peerDependenciesMeta: - typescript: - optional: true + '@typescript-eslint/type-utils@7.7.0(eslint@8.57.0)(typescript@5.3.3)': dependencies: '@typescript-eslint/typescript-estree': 7.7.0(typescript@5.3.3) '@typescript-eslint/utils': 7.7.0(eslint@8.57.0)(typescript@5.3.3) @@ -10110,21 +16824,10 @@ packages: typescript: 5.3.3 transitivePeerDependencies: - supports-color - dev: true - /@typescript-eslint/types@7.7.0: - resolution: {integrity: sha512-G01YPZ1Bd2hn+KPpIbrAhEWOn5lQBrjxkzHkWvP6NucMXFtfXoevK82hzQdpfuQYuhkvFDeQYbzXCjR1z9Z03w==} - engines: {node: ^18.18.0 || >=20.0.0} - dev: true + '@typescript-eslint/types@7.7.0': {} - /@typescript-eslint/typescript-estree@7.7.0(typescript@5.3.3): - resolution: {integrity: sha512-8p71HQPE6CbxIBy2kWHqM1KGrC07pk6RJn40n0DSc6bMOBBREZxSDJ+BmRzc8B5OdaMh1ty3mkuWRg4sCFiDQQ==} - engines: {node: ^18.18.0 || >=20.0.0} - peerDependencies: - typescript: '*' - peerDependenciesMeta: - typescript: - optional: true + '@typescript-eslint/typescript-estree@7.7.0(typescript@5.3.3)': dependencies: '@typescript-eslint/types': 7.7.0 '@typescript-eslint/visitor-keys': 7.7.0 @@ -10137,13 +16840,8 @@ packages: typescript: 5.3.3 transitivePeerDependencies: - supports-color - dev: true - /@typescript-eslint/utils@7.7.0(eslint@8.57.0)(typescript@5.3.3): - resolution: {integrity: sha512-LKGAXMPQs8U/zMRFXDZOzmMKgFv3COlxUQ+2NMPhbqgVm6R1w+nU1i4836Pmxu9jZAuIeyySNrN/6Rc657ggig==} - engines: {node: ^18.18.0 || >=20.0.0} - peerDependencies: - eslint: ^8.56.0 + '@typescript-eslint/utils@7.7.0(eslint@8.57.0)(typescript@5.3.3)': dependencies: '@eslint-community/eslint-utils': 4.4.0(eslint@8.57.0) '@types/json-schema': 7.0.15 @@ -10156,24 +16854,15 @@ packages: transitivePeerDependencies: - supports-color - typescript - dev: true - /@typescript-eslint/visitor-keys@7.7.0: - resolution: {integrity: sha512-h0WHOj8MhdhY8YWkzIF30R379y0NqyOHExI9N9KCzvmu05EgG4FumeYa3ccfKUSphyWkWQE1ybVrgz/Pbam6YA==} - engines: {node: ^18.18.0 || >=20.0.0} + '@typescript-eslint/visitor-keys@7.7.0': dependencies: '@typescript-eslint/types': 7.7.0 eslint-visitor-keys: 3.4.3 - dev: true - /@ungap/structured-clone@1.2.0: - resolution: {integrity: sha512-zuVdFrMJiuCDQUMCzQaD6KL28MjnqqN8XnAqiEq9PNm/hCPTSGfrXCOfwj1ow4LFb/tNymJPwsNbVePc1xFqrQ==} - dev: true + '@ungap/structured-clone@1.2.0': {} - /@vitest/coverage-v8@1.4.0(vitest@1.4.0): - resolution: {integrity: sha512-4hDGyH1SvKpgZnIByr9LhGgCEuF9DKM34IBLCC/fVfy24Z3+PZ+Ii9hsVBsHvY1umM1aGPEjceRkzxCfcQ10wg==} - peerDependencies: - vitest: 1.4.0 + '@vitest/coverage-v8@1.4.0(vitest@1.4.0)': dependencies: '@ampproject/remapping': 2.3.0 '@bcoe/v8-coverage': 0.2.3 @@ -10192,292 +16881,174 @@ packages: vitest: 1.4.0(@types/node@20.10.4) transitivePeerDependencies: - supports-color - dev: true - /@vitest/expect@1.4.0: - resolution: {integrity: sha512-Jths0sWCJZ8BxjKe+p+eKsoqev1/T8lYcrjavEaz8auEJ4jAVY0GwW3JKmdVU4mmNPLPHixh4GNXP7GFtAiDHA==} + '@vitest/expect@1.4.0': 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==} + '@vitest/runner@1.4.0': 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==} + '@vitest/snapshot@1.4.0': 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==} + '@vitest/spy@1.4.0': dependencies: tinyspy: 2.2.1 - dev: true - /@vitest/utils@1.4.0: - resolution: {integrity: sha512-mx3Yd1/6e2Vt/PUC98DcqTirtfxUyAZ32uK82r8rZzbtBeBo+nqgnjx/LvqQdWsrvNtm14VmurNgcf4nqY5gJg==} + '@vitest/utils@1.4.0': 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.7(zod@3.22.4): - resolution: {integrity: sha512-qK+Tsczvko8mBRACtHGYj0CdMZFaBmosMGUahTAr544Jb183INPZPn/NpUFtTEpl5g3e4lUjMc5jPH0V78D0+g==} + '@withtyped/client@0.8.7(zod@3.22.4)': dependencies: '@withtyped/server': 0.13.6(zod@3.22.4) '@withtyped/shared': 0.2.2 transitivePeerDependencies: - zod - /@withtyped/server@0.13.6(zod@3.22.4): - resolution: {integrity: sha512-l+jaZ6Gy/S3oF9q91JuHtWlRqB+bK8ycniAK2atK05/ZfhS/qBPV/JPA18fM+JzSQA+tr3CYXnul5SshmYsRoA==} - peerDependencies: - zod: ^3.19.1 + '@withtyped/server@0.13.6(zod@3.22.4)': dependencies: '@silverhand/essentials': 2.9.0 '@withtyped/shared': 0.2.2 nanoid: 4.0.2 zod: 3.22.4 - /@withtyped/shared@0.2.2: - resolution: {integrity: sha512-Vpcj12NqaoZ8M5Z/1kffheI9FBZEm9goed0THmgTcMKXLHjXSRbMZMp0olVxovEgaTIAydshqJOQUXKZMctIZw==} + '@withtyped/shared@0.2.2': {} - /@xmldom/xmldom@0.8.7: - resolution: {integrity: sha512-sI1Ly2cODlWStkINzqGrZ8K6n+MTSbAeQnAipGyL+KZCXuHaRlj2gyyy8B/9MvsFFqN7XHryQnB2QwhzvJXovg==} - engines: {node: '>=10.0.0'} - dev: false + '@xmldom/xmldom@0.8.7': {} - /JSONStream@1.3.5: - resolution: {integrity: sha512-E+iruNOY8VV9s4JEbe1aNEm6MiszPRr/UfcHMz0TQh1BXSxHK+ASV1R6W4HpjBhSeS+54PIsAMCBmwD06LLsqQ==} - hasBin: true + JSONStream@1.3.5: dependencies: jsonparse: 1.3.1 through: 2.3.8 - dev: true - /abab@2.0.6: - resolution: {integrity: sha512-j2afSsaIENvHZN2B8GOpF566vZ5WVk5opAiMTvWgaQT8DkbOqsTfvNAvHoRGU2zzP8cPoqys+xHTRDWW8L+/BA==} - dev: true + abab@2.0.6: {} - /abbrev@1.1.1: - resolution: {integrity: sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==} - dev: true + abbrev@1.1.1: {} - /abort-controller@3.0.0: - resolution: {integrity: sha512-h8lQ8tacZYnR3vNQTgibj+tODHI5/+l06Au2Pcriv/Gmet0eaj4TwWH41sO9wnHDiQsEj19q0drzdWdeAHtweg==} - engines: {node: '>=6.5'} + abort-controller@3.0.0: dependencies: event-target-shim: 5.0.1 - dev: false - /abortcontroller-polyfill@1.7.5: - resolution: {integrity: sha512-JMJ5soJWP18htbbxJjG7bG6yuI6pRhgJ0scHHTfkUjf6wjP912xZWvM+A4sJK3gqd9E8fcPbDnOefbA9Th/FIQ==} - dev: true + abortcontroller-polyfill@1.7.5: {} - /accepts@1.3.7: - resolution: {integrity: sha512-Il80Qs2WjYlJIBNzNkK6KYqlVMTbZLXgHx2oT0pU/fjRHyEp+PEfEPY0R3WCwAGVOtauxh1hOxNgIf5bv7dQpA==} - engines: {node: '>= 0.6'} + accepts@1.3.7: dependencies: mime-types: 2.1.35 negotiator: 0.6.2 - /accepts@1.3.8: - resolution: {integrity: sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==} - engines: {node: '>= 0.6'} + accepts@1.3.8: dependencies: mime-types: 2.1.35 negotiator: 0.6.3 - /acorn-globals@7.0.1: - resolution: {integrity: sha512-umOSDSDrfHbTNPuNpC2NSnnA3LUrqpevPb4T9jRx4MagXNS0rs+gwiTcAvqCRmsD6utzsrzNt+ebm00SNWiC3Q==} + acorn-globals@7.0.1: dependencies: acorn: 8.10.0 acorn-walk: 8.3.2 - dev: true - /acorn-import-assertions@1.9.0(acorn@8.11.3): - resolution: {integrity: sha512-cmMwop9x+8KFhxvKrKfPYmN6/pKTYYHBqLa0DfvVZcKMJWNyWLnaqND7dx/qn66R7ewM1UX5XMaDVP5wlVTaVA==} - peerDependencies: - acorn: ^8 + acorn-import-assertions@1.9.0(acorn@8.11.3): dependencies: acorn: 8.11.3 - dev: false - /acorn-jsx@5.3.2(acorn@8.10.0): - resolution: {integrity: sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==} - peerDependencies: - acorn: ^6.0.0 || ^7.0.0 || ^8.0.0 + acorn-jsx@5.3.2(acorn@8.10.0): dependencies: acorn: 8.10.0 - dev: true - /acorn-jsx@5.3.2(acorn@8.11.3): - resolution: {integrity: sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==} - peerDependencies: - acorn: ^6.0.0 || ^7.0.0 || ^8.0.0 + acorn-jsx@5.3.2(acorn@8.11.3): dependencies: acorn: 8.11.3 - dev: true - /acorn-walk@8.2.0: - resolution: {integrity: sha512-k+iyHEuPgSw6SbuDpGQM+06HQUa04DZ3o+F6CSzXMvvI5KMvnaEqXe+YVe555R9nn6GPt404fos4wcgpw12SDA==} - engines: {node: '>=0.4.0'} - dev: true + acorn-walk@8.2.0: {} - /acorn-walk@8.3.2: - resolution: {integrity: sha512-cjkyv4OtNCIeqhHrfS81QWXoCBPExR/J62oyEqepVw8WaQeSqpW2uhuLPh1m9eWhDuOo/jUXVTlifvesOWp/4A==} - engines: {node: '>=0.4.0'} - dev: true + acorn-walk@8.3.2: {} - /acorn@8.10.0: - resolution: {integrity: sha512-F0SAmZ8iUtS//m8DmCTA0jlh6TDKkHQyK6xc6V4KDTyZKA9dnvX9/3sRTVQrWm79glUAZbnmmNcdYwUIHWVybw==} - engines: {node: '>=0.4.0'} - hasBin: true - dev: true + acorn@8.10.0: {} - /acorn@8.11.3: - resolution: {integrity: sha512-Y9rRfJG5jcKOE0CLisYbojUjIrIEE7AGMzA/Sm4BslANhbS+cDMpgBdcPT91oJ7OuJ9hYJBx59RjbhxVnrF8Xg==} - engines: {node: '>=0.4.0'} - hasBin: true + acorn@8.11.3: {} - /agent-base@6.0.2: - resolution: {integrity: sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==} - engines: {node: '>= 6.0.0'} + agent-base@6.0.2: dependencies: debug: 4.3.4 transitivePeerDependencies: - supports-color - /agent-base@7.1.0: - resolution: {integrity: sha512-o/zjMZRhJxny7OyEF+Op8X+efiELC7k7yOjMzgfzVqOzXqkBkWI79YoTdOtsuWd5BWhAGAuOY/Xa6xpiaWXiNg==} - engines: {node: '>= 14'} + agent-base@7.1.0: dependencies: debug: 4.3.4 transitivePeerDependencies: - supports-color - /ajv-draft-04@1.0.0(ajv@8.12.0): - resolution: {integrity: sha512-mv00Te6nmYbRp5DCwclxtt7yV/joXJPGS7nM+97GdxvuttCOfgI3K4U25zboyeX0O+myI8ERluxQe5wljMmVIw==} - peerDependencies: - ajv: ^8.5.0 - peerDependenciesMeta: - ajv: - optional: true + ajv-draft-04@1.0.0(ajv@8.12.0): dependencies: ajv: 8.12.0 - dev: true - /ajv-formats@2.1.1(ajv@8.12.0): - resolution: {integrity: sha512-Wx0Kx52hxE7C18hkMEggYlEifqWZtYaRgouJor+WMdPnQyEK13vgEWyVNup7SoeeoLMsr4kf5h6dOW11I15MUA==} - peerDependencies: - ajv: ^8.0.0 - peerDependenciesMeta: - ajv: - optional: true + ajv-formats@2.1.1(ajv@8.12.0): dependencies: ajv: 8.12.0 - dev: true - /ajv@6.12.6: - resolution: {integrity: sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==} + ajv@6.12.6: dependencies: fast-deep-equal: 3.1.3 fast-json-stable-stringify: 2.1.0 json-schema-traverse: 0.4.1 uri-js: 4.4.1 - /ajv@8.12.0: - resolution: {integrity: sha512-sRu1kpcO9yLtYxBKvqfTeh9KzZEwO3STyX1HT+4CaDzC6HpTGYhIhPIzj9XuKU7KYDwnaeh5hcOwjy1QuJzBPA==} + ajv@8.12.0: dependencies: fast-deep-equal: 3.1.3 json-schema-traverse: 1.0.0 require-from-string: 2.0.2 uri-js: 4.4.1 - dev: true - /ansi-colors@4.1.3: - resolution: {integrity: sha512-/6w/C21Pm1A7aZitlI5Ni/2J6FFQN8i1Cvz3kHABAAbw93v/NlvKdVOqz7CCWz/3iv/JplRSEEZ83XION15ovw==} - engines: {node: '>=6'} - dev: true + ansi-colors@4.1.3: {} - /ansi-escapes@4.3.2: - resolution: {integrity: sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==} - engines: {node: '>=8'} + ansi-escapes@4.3.2: dependencies: type-fest: 0.21.3 - dev: true - /ansi-escapes@5.0.0: - resolution: {integrity: sha512-5GFMVX8HqE/TB+FuBJGuO5XG0WrsA6ptUqoODaT/n9mmUaZFkqnBueB4leqGBCmrUHnCnC4PCZTCd0E7QQ83bA==} - engines: {node: '>=12'} + ansi-escapes@5.0.0: dependencies: type-fest: 1.4.0 - dev: true - /ansi-escapes@6.0.0: - resolution: {integrity: sha512-IG23inYII3dWlU2EyiAiGj6Bwal5GzsgPMwjYGvc1HPE2dgbj4ZB5ToWBKSquKw74nB3TIuOwaI6/jSULzfgrw==} - engines: {node: '>=14.16'} + ansi-escapes@6.0.0: dependencies: type-fest: 3.13.1 - dev: false - /ansi-regex@5.0.1: - resolution: {integrity: sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==} - engines: {node: '>=8'} + ansi-regex@5.0.1: {} - /ansi-regex@6.0.1: - resolution: {integrity: sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==} - engines: {node: '>=12'} + ansi-regex@6.0.1: {} - /ansi-styles@3.2.1: - resolution: {integrity: sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==} - engines: {node: '>=4'} + ansi-styles@3.2.1: dependencies: color-convert: 1.9.3 - /ansi-styles@4.3.0: - resolution: {integrity: sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==} - engines: {node: '>=8'} + ansi-styles@4.3.0: dependencies: color-convert: 2.0.1 - /ansi-styles@5.2.0: - resolution: {integrity: sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==} - engines: {node: '>=10'} - dev: true + ansi-styles@5.2.0: {} - /ansi-styles@6.2.1: - resolution: {integrity: sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==} - engines: {node: '>=12'} + ansi-styles@6.2.1: {} - /anymatch@3.1.3: - resolution: {integrity: sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==} - engines: {node: '>= 8'} + anymatch@3.1.3: dependencies: normalize-path: 3.0.0 picomatch: 2.3.1 - dev: true - /applicationinsights@2.9.5: - resolution: {integrity: sha512-APQ8IWyYDHFvKbitFKpsmZXxkzQh0yYTFacQqoVW7HwlPo3eeLprwnq5RFNmmG6iqLmvQ+xRJSDLEQCgqPh+bw==} - engines: {node: '>=8.0.0'} - peerDependencies: - applicationinsights-native-metrics: '*' - peerDependenciesMeta: - applicationinsights-native-metrics: - optional: true + applicationinsights@2.9.5: dependencies: '@azure/core-auth': 1.7.2 '@azure/core-rest-pipeline': 1.10.1 @@ -10494,43 +17065,27 @@ packages: diagnostic-channel-publishers: 1.0.8(diagnostic-channel@1.1.1) transitivePeerDependencies: - supports-color - dev: false - /arg@4.1.3: - resolution: {integrity: sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==} - dev: true + arg@4.1.3: {} - /argparse@1.0.10: - resolution: {integrity: sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==} + argparse@1.0.10: dependencies: sprintf-js: 1.0.3 - dev: true - /argparse@2.0.1: - resolution: {integrity: sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==} - dev: true + argparse@2.0.1: {} - /aria-query@5.3.0: - resolution: {integrity: sha512-b0P0sZPKtyu8HkeRAfCq0IfURZK+SuwMjY1UXGBU27wpAiTwQAIlq56IbIO+ytk/JjS1fMR14ee5WBBfKi5J6A==} + aria-query@5.3.0: dependencies: dequal: 2.0.3 - dev: true - /array-buffer-byte-length@1.0.1: - resolution: {integrity: sha512-ahC5W1xgou+KTXix4sAO8Ki12Q+jf4i0+tmk3sC+zgcynshkHxzpXdImBehiUYKKKDwvfFiJl1tZt6ewscS1Mg==} - engines: {node: '>= 0.4'} + array-buffer-byte-length@1.0.1: dependencies: call-bind: 1.0.7 is-array-buffer: 3.0.4 - dev: true - /array-ify@1.0.0: - resolution: {integrity: sha512-c5AMf34bKdvPhQ7tBGhqkgKNUzMr4WUs+WDtC2ZUGOUncbxKMTvqxYctiseW3+L4bA8ec+GcZ6/A/FW4m8ukng==} - dev: true + array-ify@1.0.0: {} - /array-includes@3.1.8: - resolution: {integrity: sha512-itaWrbYbqpGXkGhZPGUulwnhVf5Hpy1xiCFsGqyIGglbBxmG5vSjxQen3/WGOjPpNEv1RtBLKxbmVXm8HpJStQ==} - engines: {node: '>= 0.4'} + array-includes@3.1.8: dependencies: call-bind: 1.0.7 define-properties: 1.2.1 @@ -10538,16 +17093,10 @@ packages: es-object-atoms: 1.0.0 get-intrinsic: 1.2.4 is-string: 1.0.7 - dev: true - /array-union@2.1.0: - resolution: {integrity: sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==} - engines: {node: '>=8'} - dev: true + array-union@2.1.0: {} - /array.prototype.findlast@1.2.5: - resolution: {integrity: sha512-CVvd6FHg1Z3POpBLxO6E6zr+rSKEQ9L6rZHAaY7lLfhKsWYUBBOuMs0e9o24oopj6H+geRCX0YJ+TJLBK2eHyQ==} - engines: {node: '>= 0.4'} + array.prototype.findlast@1.2.5: dependencies: call-bind: 1.0.7 define-properties: 1.2.1 @@ -10555,11 +17104,8 @@ packages: es-errors: 1.3.0 es-object-atoms: 1.0.0 es-shim-unscopables: 1.0.2 - dev: true - /array.prototype.findlastindex@1.2.5: - resolution: {integrity: sha512-zfETvRFA8o7EiNn++N5f/kaCw221hrpGsDmcpndVupkPzEc1Wuf3VgC0qby1BbHs7f5DVYjgtEU2LLh5bqeGfQ==} - engines: {node: '>= 0.4'} + array.prototype.findlastindex@1.2.5: dependencies: call-bind: 1.0.7 define-properties: 1.2.1 @@ -10567,60 +17113,44 @@ packages: es-errors: 1.3.0 es-object-atoms: 1.0.0 es-shim-unscopables: 1.0.2 - dev: true - /array.prototype.flat@1.3.1: - resolution: {integrity: sha512-roTU0KWIOmJ4DRLmwKd19Otg0/mT3qPNt0Qb3GWW8iObuZXxrjB/pzn0R3hqpRSWg4HCwqx+0vwOnWnvlOyeIA==} - engines: {node: '>= 0.4'} + array.prototype.flat@1.3.1: dependencies: call-bind: 1.0.7 define-properties: 1.1.4 es-abstract: 1.20.4 es-shim-unscopables: 1.0.0 - dev: true - /array.prototype.flat@1.3.2: - resolution: {integrity: sha512-djYB+Zx2vLewY8RWlNCUdHjDXs2XOgm602S9E7P/UpHgfeHL00cRiIF+IN/G/aUJ7kGPb6yO/ErDI5V2s8iycA==} - engines: {node: '>= 0.4'} + array.prototype.flat@1.3.2: dependencies: call-bind: 1.0.7 define-properties: 1.2.1 es-abstract: 1.23.3 es-shim-unscopables: 1.0.2 - dev: true - /array.prototype.flatmap@1.3.2: - resolution: {integrity: sha512-Ewyx0c9PmpcsByhSW4r+9zDU7sGjFc86qf/kKtuSCRdhfbk0SNLLkaT5qvcHnRGgc5NP/ly/y+qkXkqONX54CQ==} - engines: {node: '>= 0.4'} + array.prototype.flatmap@1.3.2: dependencies: call-bind: 1.0.7 define-properties: 1.2.1 es-abstract: 1.23.3 es-shim-unscopables: 1.0.2 - dev: true - /array.prototype.toreversed@1.1.2: - resolution: {integrity: sha512-wwDCoT4Ck4Cz7sLtgUmzR5UV3YF5mFHUlbChCzZBQZ+0m2cl/DH3tKgvphv1nKgFsJ48oCSg6p91q2Vm0I/ZMA==} + array.prototype.toreversed@1.1.2: dependencies: call-bind: 1.0.7 define-properties: 1.2.1 es-abstract: 1.23.3 es-shim-unscopables: 1.0.2 - dev: true - /array.prototype.tosorted@1.1.3: - resolution: {integrity: sha512-/DdH4TiTmOKzyQbp/eadcCVexiCb36xJg7HshYOYJnNZFDj33GEv0P7GxsynpShhq4OLYJzbGcBDkLsDt7MnNg==} + array.prototype.tosorted@1.1.3: dependencies: call-bind: 1.0.7 define-properties: 1.2.1 es-abstract: 1.23.3 es-errors: 1.3.0 es-shim-unscopables: 1.0.2 - dev: true - /arraybuffer.prototype.slice@1.0.3: - resolution: {integrity: sha512-bMxMKAjg13EBSVscxTaYA4mRc5t1UAXa2kXiGTNfZ079HIWXEkKmkgFrh/nJqamaLSrXO5H4WFFkPEaLJWbs3A==} - engines: {node: '>= 0.4'} + arraybuffer.prototype.slice@1.0.3: dependencies: array-buffer-byte-length: 1.0.1 call-bind: 1.0.7 @@ -10630,127 +17160,73 @@ packages: get-intrinsic: 1.2.4 is-array-buffer: 3.0.4 is-shared-array-buffer: 1.0.3 - dev: true - /arrify@1.0.1: - resolution: {integrity: sha512-3CYzex9M9FGQjCGMGyi6/31c8GJbgb0qGyrx5HWxPd0aCwh4cB2YjMb2Xf9UuoogrMrlO9cTqnB5rI5GHZTcUA==} - engines: {node: '>=0.10.0'} - dev: true + arrify@1.0.1: {} - /arrify@2.0.1: - resolution: {integrity: sha512-3duEwti880xqi4eAMN8AyR4a0ByT90zoYdLlevfrvU43vb0YZwZVfxOgxWrLXXXpyugL0hNZc9G6BiB5B3nUug==} - engines: {node: '>=8'} - dev: false + arrify@2.0.1: {} - /asap@2.0.6: - resolution: {integrity: sha512-BSHWgDSAiKs50o2Re8ppvp3seVHXSRM44cdSsT9FfNEUUZLOGWVCsiWaRPWM1Znn+mqZ1OfVZ3z3DWEzSp7hRA==} + asap@2.0.6: {} - /asn1@0.2.6: - resolution: {integrity: sha512-ix/FxPn0MDjeyJ7i/yoHGFt/EX6LyNbxSEhPPXODPL+KB0VPk86UYfL0lMdy+KCnv+fmvIzySwaK5COwqVbWTQ==} + asn1@0.2.6: dependencies: safer-buffer: 2.1.2 - dev: false - /asn1js@3.0.5: - resolution: {integrity: sha512-FVnvrKJwpt9LP2lAMl8qZswRNm3T4q9CON+bxldk2iwk3FFpuwhx2FfinyitizWHsVYyaY+y5JzDR0rCMV5yTQ==} - engines: {node: '>=12.0.0'} + asn1js@3.0.5: dependencies: pvtsutils: 1.3.5 pvutils: 1.1.3 tslib: 2.6.2 - dev: false - /assertion-error@1.1.0: - resolution: {integrity: sha512-jgsaNduz+ndvGyFt3uSuWqvy4lCnIJiovtouQN5JZHOKCS2QuhEdbcQHFhVksz2N2U9hXJo8odG7ETyWlEeuDw==} - dev: true + assertion-error@1.1.0: {} - /ast-types-flow@0.0.8: - resolution: {integrity: sha512-OH/2E5Fg20h2aPrbe+QL8JZQFko0YZaF+j4mnQ7BGhfavO7OpSLa8a0y9sBwomHdSbkhTS8TQNayBfnW5DwbvQ==} - dev: true + ast-types-flow@0.0.8: {} - /ast-types@0.13.4: - resolution: {integrity: sha512-x1FCFnFifvYDDzTaLII71vG5uvDwgtmDTEVWAxrgeiR8VjMONcCXJx7E+USjDtHlwFmt9MysbqgF9b9Vjr6w+w==} - engines: {node: '>=4'} + ast-types@0.13.4: dependencies: tslib: 2.6.2 - dev: true - /astral-regex@2.0.0: - resolution: {integrity: sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ==} - engines: {node: '>=8'} - dev: true + astral-regex@2.0.0: {} - /astring@1.8.3: - resolution: {integrity: sha512-sRpyiNrx2dEYIMmUXprS8nlpRg2Drs8m9ElX9vVEXaCB4XEAJhKfs7IcX0IwShjuOAjLR6wzIrgoptz1n19i1A==} - hasBin: true - dev: true + astring@1.8.3: {} - /async-hook-jl@1.7.6: - resolution: {integrity: sha512-gFaHkFfSxTjvoxDMYqDuGHlcRyUuamF8s+ZTtJdDzqjws4mCt7v0vuV79/E2Wr2/riMQgtG4/yUtXWs1gZ7JMg==} - engines: {node: ^4.7 || >=6.9 || >=7.3} + async-hook-jl@1.7.6: dependencies: stack-chain: 1.3.7 - dev: false - /async-listener@0.6.10: - resolution: {integrity: sha512-gpuo6xOyF4D5DE5WvyqZdPA3NGhiT6Qf07l7DCB0wwDEsLvDIbCr6j9S5aj5Ch96dLace5tXVzWBZkxU/c5ohw==} - engines: {node: <=0.11.8 || >0.11.10} + async-listener@0.6.10: dependencies: semver: 5.7.2 shimmer: 1.2.1 - dev: false - /async-retry@1.3.3: - resolution: {integrity: sha512-wfr/jstw9xNi/0teMHrRW7dsz3Lt5ARhYNZ2ewpadnhaIp5mbALhOAP+EAdsC7t4Z6wqsDVv9+W6gm1Dk9mEyw==} + async-retry@1.3.3: dependencies: retry: 0.13.1 - dev: false - /asynckit@0.4.0: - resolution: {integrity: sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==} + asynckit@0.4.0: {} - /attr-accept@2.2.2: - resolution: {integrity: sha512-7prDjvt9HmqiZ0cl5CRjtS84sEyhsHP2coDkaZKRKVfCDo9s7iw7ChVmar78Gu9pC4SoR/28wFu/G5JJhTnqEg==} - engines: {node: '>=4'} - dev: true + attr-accept@2.2.2: {} - /available-typed-arrays@1.0.7: - resolution: {integrity: sha512-wvUjBtSGN7+7SjNpq/9M2Tg350UZD3q62IFZLbRAR1bSMlCo1ZaeW+BJ+D090e4hIIZLBcTDWe4Mh4jvUDajzQ==} - engines: {node: '>= 0.4'} + available-typed-arrays@1.0.7: dependencies: possible-typed-array-names: 1.0.0 - dev: true - /axe-core@4.7.0: - resolution: {integrity: sha512-M0JtH+hlOL5pLQwHOLNYZaXuhqmvS8oExsqB1SBYgA4Dk7u/xx+YdGHXaK5pyUfed5mYXdlYiphWq3G8cRi5JQ==} - engines: {node: '>=4'} - dev: true + axe-core@4.7.0: {} - /axios@1.6.7: - resolution: {integrity: sha512-/hDJGff6/c7u0hDkvkGxR/oy6CbCs8ziCsC7SqmhjfozqiJGc8Z11wrv9z9lYfY4K8l+H9TpjcMDX0xOZmx+RA==} + axios@1.6.7: dependencies: follow-redirects: 1.15.6 form-data: 4.0.0 proxy-from-env: 1.1.0 transitivePeerDependencies: - debug - dev: true - /axobject-query@3.2.1: - resolution: {integrity: sha512-jsyHu61e6N4Vbz/v18DHwWYKK0bSWLqn47eeDSKPB7m8tqMHF9YJ+mhIk2lVteyZrY8tnSj/jHOv4YiTCuCJgg==} + axobject-query@3.2.1: dependencies: dequal: 2.0.3 - dev: true - /b4a@1.6.4: - resolution: {integrity: sha512-fpWrvyVHEKyeEvbKZTVOeZF3VSKKWtJxFIxX/jaVPf+cLbGUSitjb49pHLqPV2BUNNZ0LcoeEGfE/YCpyDYHIw==} - dev: true + b4a@1.6.4: {} - /babel-jest@29.7.0(@babel/core@7.24.4): - resolution: {integrity: sha512-BrvGY3xZSwEcCzKvKsCi2GgHqDqsYkOP4/by5xCgIwGXQxIEh+8ew3gmrE1y7XRR6LHZIj6yLYnUi/mm2KXKBg==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - peerDependencies: - '@babel/core': ^7.8.0 + babel-jest@29.7.0(@babel/core@7.24.4): dependencies: '@babel/core': 7.24.4 '@jest/transform': 29.7.0 @@ -10762,27 +17238,18 @@ packages: slash: 3.0.0 transitivePeerDependencies: - supports-color - dev: true - /babel-plugin-apply-mdx-type-prop@1.6.22(@babel/core@7.12.9): - resolution: {integrity: sha512-VefL+8o+F/DfK24lPZMtJctrCVOfgbqLAGZSkxwhazQv4VxPg3Za/i40fu22KR2m8eEda+IfSOlPLUSIiLcnCQ==} - peerDependencies: - '@babel/core': ^7.11.6 + babel-plugin-apply-mdx-type-prop@1.6.22(@babel/core@7.12.9): dependencies: '@babel/core': 7.12.9 '@babel/helper-plugin-utils': 7.10.4 '@mdx-js/util': 1.6.22 - dev: true - /babel-plugin-extract-import-names@1.6.22: - resolution: {integrity: sha512-yJ9BsJaISua7d8zNT7oRG1ZLBJCIdZ4PZqmH8qa9N5AK01ifk3fnkc98AXhtzE7UkfCsEumvoQWgoYLhOnJ7jQ==} + babel-plugin-extract-import-names@1.6.22: dependencies: '@babel/helper-plugin-utils': 7.10.4 - dev: true - /babel-plugin-istanbul@6.1.1: - resolution: {integrity: sha512-Y1IQok9821cC9onCx5otgFfRm7Lm+I+wwxOx738M/WLPZ9Q42m4IG5W0FNX8WLL2gYMZo3JkuXIH2DOpWM+qwA==} - engines: {node: '>=8'} + babel-plugin-istanbul@6.1.1: dependencies: '@babel/helper-plugin-utils': 7.20.2 '@istanbuljs/load-nyc-config': 1.1.0 @@ -10791,22 +17258,15 @@ packages: test-exclude: 6.0.0 transitivePeerDependencies: - supports-color - dev: true - /babel-plugin-jest-hoist@29.6.3: - resolution: {integrity: sha512-ESAc/RJvGTFEzRwOTT4+lNDk/GNHMkKbNzsvT0qKRfDyyYTskxB5rnU2njIDYVxXCBHHEI1c0YwHob3WaYujOg==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + babel-plugin-jest-hoist@29.6.3: dependencies: '@babel/template': 7.18.10 '@babel/types': 7.24.0 '@types/babel__core': 7.1.19 '@types/babel__traverse': 7.18.2 - dev: true - /babel-preset-current-node-syntax@1.0.1(@babel/core@7.24.4): - resolution: {integrity: sha512-M7LQ0bxarkxQoN+vz5aJPsLBn77n8QgTFmo8WK0/44auK2xlCXrYcUxHFxgU7qW5Yzw/CjmLRK2uJzaCd7LvqQ==} - peerDependencies: - '@babel/core': ^7.0.0 + babel-preset-current-node-syntax@1.0.1(@babel/core@7.24.4): dependencies: '@babel/core': 7.24.4 '@babel/plugin-syntax-async-generators': 7.8.4(@babel/core@7.24.4) @@ -10821,234 +17281,138 @@ packages: '@babel/plugin-syntax-optional-catch-binding': 7.8.3(@babel/core@7.24.4) '@babel/plugin-syntax-optional-chaining': 7.8.3(@babel/core@7.24.4) '@babel/plugin-syntax-top-level-await': 7.14.5(@babel/core@7.24.4) - dev: true - /babel-preset-jest@29.6.3(@babel/core@7.24.4): - resolution: {integrity: sha512-0B3bhxR6snWXJZtR/RliHTDPRgn1sNHOR0yVtq/IiQFyuOVjFS+wuio/R4gSNkyYmKmJB4wGZv2NZanmKmTnNA==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - peerDependencies: - '@babel/core': ^7.0.0 + babel-preset-jest@29.6.3(@babel/core@7.24.4): dependencies: '@babel/core': 7.24.4 babel-plugin-jest-hoist: 29.6.3 babel-preset-current-node-syntax: 1.0.1(@babel/core@7.24.4) - dev: true - /bail@1.0.5: - resolution: {integrity: sha512-xFbRxM1tahm08yHBP16MMjVUAvDaBMD38zsM9EMAUN61omwLmKlOpB/Zku5QkjZ8TZ4vn53pj+t518cH0S03RQ==} - dev: true + bail@1.0.5: {} - /bail@2.0.2: - resolution: {integrity: sha512-0xO6mYd7JB2YesxDKplafRpsiOzPt9V02ddPCLbY1xYGPOX24NTyN50qnUxgCPcSoYMhKpAuBTjQoRZCAkUDRw==} - dev: true + bail@2.0.2: {} - /balanced-match@1.0.2: - resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==} + balanced-match@1.0.2: {} - /balanced-match@2.0.0: - resolution: {integrity: sha512-1ugUSr8BHXRnK23KfuYS+gVMC3LB8QGH9W1iGtDPsNWoQbgtXSExkBu2aDR4epiGWZOjZsj6lDl/N/AqqTC3UA==} - dev: true + balanced-match@2.0.0: {} - /bare-events@2.2.2: - resolution: {integrity: sha512-h7z00dWdG0PYOQEvChhOSWvOfkIKsdZGkWr083FgN/HyoQuebSew/cgirYqh9SCuy/hRvxc5Vy6Fw8xAmYHLkQ==} - requiresBuild: true - dev: true + bare-events@2.2.2: optional: true - /bare-fs@2.2.3: - resolution: {integrity: sha512-amG72llr9pstfXOBOHve1WjiuKKAMnebcmMbPWDZ7BCevAoJLpugjuAPRsDINEyjT0a6tbaVx3DctkXIRbLuJw==} - requiresBuild: true + bare-fs@2.2.3: dependencies: bare-events: 2.2.2 bare-path: 2.1.1 streamx: 2.15.1 - dev: true optional: true - /bare-os@2.2.1: - resolution: {integrity: sha512-OwPyHgBBMkhC29Hl3O4/YfxW9n7mdTr2+SsO29XBWKKJsbgj3mnorDB80r5TiCQgQstgE5ga1qNYrpes6NvX2w==} - requiresBuild: true - dev: true + bare-os@2.2.1: optional: true - /bare-path@2.1.1: - resolution: {integrity: sha512-OHM+iwRDRMDBsSW7kl3dO62JyHdBKO3B25FB9vNQBPcGHMo4+eA8Yj41Lfbk3pS/seDY+siNge0LdRTulAau/A==} - requiresBuild: true + bare-path@2.1.1: dependencies: bare-os: 2.2.1 - dev: true optional: true - /base-x@3.0.9: - resolution: {integrity: sha512-H7JU6iBHTal1gp56aKoaa//YUxEaAOUiydvrV/pILqIHXTtqxSkATOnDA2u+jZ/61sD+L/412+7kzXRtWukhpQ==} + base-x@3.0.9: dependencies: safe-buffer: 5.2.1 - dev: true - /base64-js@1.5.1: - resolution: {integrity: sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==} + base64-js@1.5.1: {} - /basic-ftp@5.0.3: - resolution: {integrity: sha512-QHX8HLlncOLpy54mh+k/sWIFd0ThmRqwe9ZjELybGZK+tZ8rUb9VO0saKJUROTbE+KhzDUT7xziGpGrW8Kmd+g==} - engines: {node: '>=10.0.0'} - dev: true + basic-ftp@5.0.3: {} - /better-path-resolve@1.0.0: - resolution: {integrity: sha512-pbnl5XzGBdrFU/wT4jqmJVPn2B6UHPBOhzMQkY/SPUPB6QtUXtmBHBIwCbXJol93mOpGMnQyP/+BB19q04xj7g==} - engines: {node: '>=4'} + better-path-resolve@1.0.0: dependencies: is-windows: 1.0.2 - dev: true - /bignumber.js@9.1.2: - resolution: {integrity: sha512-2/mKyZH9K85bzOEfhXDBFZTGd1CTs+5IHpeFQo9luiBG7hghdC851Pj2WAhb6E3R6b9tZj/XKhbg4fum+Kepug==} - dev: false + bignumber.js@9.1.2: {} - /binary-extensions@2.2.0: - resolution: {integrity: sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==} - engines: {node: '>=8'} - dev: true + binary-extensions@2.2.0: {} - /bl@5.1.0: - resolution: {integrity: sha512-tv1ZJHLfTDnXE6tMHv73YgSJaWR2AFuPwMntBe7XL/GBFHnT0CLnsHMogfk5+GzCDC5ZWarSCYaIGATZt9dNsQ==} + bl@5.1.0: dependencies: buffer: 6.0.3 inherits: 2.0.4 readable-stream: 3.6.2 - dev: false - /bluebird@3.7.2: - resolution: {integrity: sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==} + bluebird@3.7.2: {} - /boolbase@1.0.0: - resolution: {integrity: sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww==} - dev: true + boolbase@1.0.0: {} - /boolean@3.1.4: - resolution: {integrity: sha512-3hx0kwU3uzG6ReQ3pnaFQPSktpBw6RHN3/ivDKEuU8g1XSfafowyvDnadjv1xp8IZqhtSukxlwv9bF6FhX8m0w==} + boolean@3.1.4: {} - /bowser@2.11.0: - resolution: {integrity: sha512-AlcaJBi/pqqJBIQ8U9Mcpc9i8Aqxn88Skv5d+xBX006BY5u8N3mGLHa5Lgppa7L/HfwgwLgZ6NYs+Ag6uUmJRA==} - dev: false + bowser@2.11.0: {} - /brace-expansion@1.1.11: - resolution: {integrity: sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==} + brace-expansion@1.1.11: dependencies: balanced-match: 1.0.2 concat-map: 0.0.1 - dev: true - /brace-expansion@2.0.1: - resolution: {integrity: sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==} + brace-expansion@2.0.1: dependencies: balanced-match: 1.0.2 - /braces@3.0.2: - resolution: {integrity: sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==} - engines: {node: '>=8'} + braces@3.0.2: dependencies: fill-range: 7.0.1 - dev: true - /breakword@1.0.5: - resolution: {integrity: sha512-ex5W9DoOQ/LUEU3PMdLs9ua/CYZl1678NUkKOdUSi8Aw5F1idieaiRURCBFJCwVcrD1J8Iy3vfWSloaMwO2qFg==} + breakword@1.0.5: dependencies: wcwidth: 1.0.1 - dev: true - /browserslist@4.21.4: - resolution: {integrity: sha512-CBHJJdDmgjl3daYjN5Cp5kbTf1mUhZoS+beLklHIvkOWscs83YAhLlF3Wsh/lciQYAcbBJgTOD44VtG31ZM4Hw==} - engines: {node: ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7} - hasBin: true + browserslist@4.21.4: dependencies: caniuse-lite: 1.0.30001561 electron-to-chromium: 1.4.281 node-releases: 2.0.6 update-browserslist-db: 1.0.10(browserslist@4.21.4) - dev: true - /browserslist@4.23.0: - resolution: {integrity: sha512-QW8HiM1shhT2GuzkvklfjcKDiWFXHOeFCIA/huJPwHsslwcydgk7X+z2zXpEijP98UCY7HbubZt5J2Zgvf0CaQ==} - engines: {node: ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7} - hasBin: true + browserslist@4.23.0: dependencies: caniuse-lite: 1.0.30001610 electron-to-chromium: 1.4.738 node-releases: 2.0.14 update-browserslist-db: 1.0.13(browserslist@4.23.0) - dev: true - /bser@2.1.1: - resolution: {integrity: sha512-gQxTNE/GAfIIrmHLUE3oJyp5FO6HRBfhjnw4/wMmA63ZGDJnWBmgY/lyQBpnDUkGmAhbSe39tx2d/iTOAfglwQ==} + bser@2.1.1: dependencies: node-int64: 0.4.0 - dev: true - /buffer-crc32@0.2.13: - resolution: {integrity: sha512-VO9Ht/+p3SN7SKWqcrgEzjGbRSJYTx+Q1pTQC0wrWqHx0vpJraQ6GtHx8tvcg1rlK1byhU5gccxgOgj7B0TDkQ==} - dev: true + buffer-crc32@0.2.13: {} - /buffer-equal-constant-time@1.0.1: - resolution: {integrity: sha512-zRpUiDwd/xk6ADqPMATG8vc9VPrkck7T07OIx0gnjmJAnHnTVXNQG3vfvWNuiZIkwu9KrKdA1iJKfsfTVxE6NA==} - dev: false + buffer-equal-constant-time@1.0.1: {} - /buffer-from@1.1.2: - resolution: {integrity: sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==} - dev: true + buffer-from@1.1.2: {} - /buffer-writer@2.0.0: - resolution: {integrity: sha512-a7ZpuTZU1TRtnwyCNW3I5dc0wWNC3VR9S++Ewyk2HHZdrO3CQJqSpd+95Us590V6AL7JqUAH2IwZ/398PmNFgw==} - engines: {node: '>=4'} + buffer-writer@2.0.0: {} - /buffer@5.7.1: - resolution: {integrity: sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==} + buffer@5.7.1: dependencies: base64-js: 1.5.1 ieee754: 1.2.1 - dev: true - /buffer@6.0.3: - resolution: {integrity: sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==} + buffer@6.0.3: dependencies: base64-js: 1.5.1 ieee754: 1.2.1 - dev: false - /builtin-modules@3.3.0: - resolution: {integrity: sha512-zhaCDicdLuWN5UbN5IMnFqNMhNfo919sH85y2/ea+5Yg9TsTkeZxpL+JLbp6cgYFS4sRLp3YV4S6yDuqVWHYOw==} - engines: {node: '>=6'} - dev: true + builtin-modules@3.3.0: {} - /bytes@3.1.1: - resolution: {integrity: sha512-dWe4nWO/ruEOY7HkUJ5gFt1DCFV9zPRoJr8pV0/ASQermOZjtq8jMjOprC0Kd10GLN+l7xaUPvxzJFWtxGu8Fg==} - engines: {node: '>= 0.8'} - dev: false + bytes@3.1.1: {} - /bytes@3.1.2: - resolution: {integrity: sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==} - engines: {node: '>= 0.8'} - dev: false + bytes@3.1.2: {} - /cac@6.7.14: - resolution: {integrity: sha512-b6Ilus+c3RrdDk+JhLKUAQfzzgLEPy6wcXqS7f/xe1EETvsDP6GORG7SFuOs6cID5YkqchW/LXZbX5bc8j7ZcQ==} - engines: {node: '>=8'} - dev: true + cac@6.7.14: {} - /cache-content-type@1.0.1: - resolution: {integrity: sha512-IKufZ1o4Ut42YUrZSo8+qnMTrFuKkvyoLXUywKz9GJ5BrhOFGhLdkx9sG4KAnVvbY6kEcSFjLQul+DVmBm2bgA==} - engines: {node: '>= 6.0.0'} + cache-content-type@1.0.1: dependencies: mime-types: 2.1.35 ylru: 1.2.1 - /cacheable-lookup@7.0.0: - resolution: {integrity: sha512-+qJyx4xiKra8mZrcwhjMRMUhD5NR1R8esPkzIYxX96JiecFoxAXFuz/GpR3+ev4PE1WamHip78wV0vcmPQtp8w==} - engines: {node: '>=14.16'} - dev: false + cacheable-lookup@7.0.0: {} - /cacheable-request@10.2.14: - resolution: {integrity: sha512-zkDT5WAF4hSSoUgyfg5tFIxz8XQK+25W/TLVojJTMKBaxevLBBtLxgqguAuVQB8PVW79FVjHcU+GJ9tVbDZ9mQ==} - engines: {node: '>=14.16'} + cacheable-request@10.2.14: dependencies: '@types/http-cache-semantics': 4.0.4 get-stream: 6.0.1 @@ -11057,11 +17421,8 @@ packages: mimic-response: 4.0.0 normalize-url: 8.0.0 responselike: 3.0.0 - dev: false - /call-bind@1.0.7: - resolution: {integrity: sha512-GHTSNSYICQ7scH7sZ+M2rFopRoLh8t2bLSW6BbgrtLsahOIB5iyAVJf9GjWK3cYTDaMj4XdBpM1cA6pIS0Kv2w==} - engines: {node: '>= 0.4'} + call-bind@1.0.7: dependencies: es-define-property: 1.0.0 es-errors: 1.3.0 @@ -11069,72 +17430,43 @@ packages: get-intrinsic: 1.2.4 set-function-length: 1.2.2 - /call-me-maybe@1.0.2: - resolution: {integrity: sha512-HpX65o1Hnr9HH25ojC1YGs7HCQLq0GCOibSaWER0eNpgJ/Z1MZv2mTc7+xh6WOPxbRVcmgbv4hGU+uSQ/2xFZQ==} - dev: true + call-me-maybe@1.0.2: {} - /callsites@3.1.0: - resolution: {integrity: sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==} - engines: {node: '>=6'} - dev: true + callsites@3.1.0: {} - /camelcase-css@2.0.1: - resolution: {integrity: sha512-QOSvevhslijgYwRx6Rv7zKdMF8lbRmx+uQGx2+vDc+KI/eBnsy9kit5aj23AgGu3pa4t9AgwbnXWqS+iOY+2aA==} - engines: {node: '>= 6'} - dev: true + camelcase-css@2.0.1: {} - /camelcase-keys@6.2.2: - resolution: {integrity: sha512-YrwaA0vEKazPBkn0ipTiMpSajYDSe+KjQfrjhcBMxJt/znbvlHd8Pw/Vamaz5EB4Wfhs3SUR3Z9mwRu/P3s3Yg==} - engines: {node: '>=8'} + camelcase-keys@6.2.2: dependencies: camelcase: 5.3.1 map-obj: 4.3.0 quick-lru: 4.0.1 - dev: true - /camelcase-keys@7.0.2: - resolution: {integrity: sha512-Rjs1H+A9R+Ig+4E/9oyB66UC5Mj9Xq3N//vcLf2WzgdTi/3gUu3Z9KoqmlrEG4VuuLK8wJHofxzdQXz/knhiYg==} - engines: {node: '>=12'} + camelcase-keys@7.0.2: dependencies: camelcase: 6.3.0 map-obj: 4.3.0 quick-lru: 5.1.1 type-fest: 1.4.0 - dev: true - /camelcase-keys@9.0.0: - resolution: {integrity: sha512-GdZ92DNXdcfFB/5Kq4O82EL6UW5neiRBhfNP5M3mGw7CX2sPDbVA04ZPLsqbp7oMi2l3m2I0AZ/kFP5Nk5kopA==} - engines: {node: '>=16'} + camelcase-keys@9.0.0: dependencies: camelcase: 8.0.0 map-obj: 5.0.0 quick-lru: 6.1.1 type-fest: 4.2.0 - /camelcase@5.3.1: - resolution: {integrity: sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==} - engines: {node: '>=6'} + camelcase@5.3.1: {} - /camelcase@6.3.0: - resolution: {integrity: sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==} - engines: {node: '>=10'} + camelcase@6.3.0: {} - /camelcase@8.0.0: - resolution: {integrity: sha512-8WB3Jcas3swSvjIeA2yvCJ+Miyz5l1ZmB6HFb9R1317dt9LCQoswg/BGrmAmkWVEszSrrg4RwmO46qIm2OEnSA==} - engines: {node: '>=16'} + camelcase@8.0.0: {} - /caniuse-lite@1.0.30001561: - resolution: {integrity: sha512-NTt0DNoKe958Q0BE0j0c1V9jbUzhBxHIEJy7asmGrpE0yG63KTV7PLHPnK2E1O9RsQrQ081I3NLuXGS6zht3cw==} - dev: true + caniuse-lite@1.0.30001561: {} - /caniuse-lite@1.0.30001610: - resolution: {integrity: sha512-QFutAY4NgaelojVMjY63o6XlZyORPaLfyMnsl3HgnWdJUcX6K0oaJymHjH8PT5Gk7sTm8rvC/c5COUQKXqmOMA==} - dev: true + caniuse-lite@1.0.30001610: {} - /cbor-extract@2.2.0: - resolution: {integrity: sha512-Ig1zM66BjLfTXpNgKpvBePq271BPOvu8MR0Jl080yG7Jsl+wAZunfrwiwA+9ruzm/WEdIV5QF/bjDZTqyAIVHA==} - hasBin: true - requiresBuild: true + cbor-extract@2.2.0: dependencies: node-gyp-build-optional-packages: 5.1.1 optionalDependencies: @@ -11144,26 +17476,17 @@ packages: '@cbor-extract/cbor-extract-linux-arm64': 2.2.0 '@cbor-extract/cbor-extract-linux-x64': 2.2.0 '@cbor-extract/cbor-extract-win32-x64': 2.2.0 - dev: false optional: true - /cbor-x@1.5.4: - resolution: {integrity: sha512-PVKILDn+Rf6MRhhcyzGXi5eizn1i0i3F8Fe6UMMxXBnWkalq9+C5+VTmlIjAYM4iF2IYF2N+zToqAfYOp+3rfw==} + cbor-x@1.5.4: optionalDependencies: cbor-extract: 2.2.0 - dev: false - /ccount@1.1.0: - resolution: {integrity: sha512-vlNK021QdI7PNeiUh/lKkC/mNHHfV0m/Ad5JoI0TYtlBnJAslM/JIkm/tGC88bkLIwO6OQ5uV6ztS6kVAtCDlg==} - dev: true + ccount@1.1.0: {} - /ccount@2.0.1: - resolution: {integrity: sha512-eyrF0jiFpY+3drT6383f1qhkbGsLSifNAjA61IUjZjmLCWjItY6LB9ft9YhoDgwfmclB2zhu51Lc7+95b8NRAg==} - dev: true + ccount@2.0.1: {} - /chai@4.4.1: - resolution: {integrity: sha512-13sOfMv2+DWduEU+/xbun3LScLoqN17nBeTLUsmDfKdoiC1fr0n9PU4guu4AhRcOVFk/sW8LyZWHuhWtQZiF+g==} - engines: {node: '>=4'} + chai@4.4.1: dependencies: assertion-error: 1.1.0 check-error: 1.0.3 @@ -11172,65 +17495,39 @@ packages: loupe: 2.3.7 pathval: 1.1.1 type-detect: 4.0.8 - dev: true - /chalk@2.4.2: - resolution: {integrity: sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==} - engines: {node: '>=4'} + chalk@2.4.2: dependencies: ansi-styles: 3.2.1 escape-string-regexp: 1.0.5 supports-color: 5.5.0 - /chalk@4.1.2: - resolution: {integrity: sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==} - engines: {node: '>=10'} + chalk@4.1.2: dependencies: ansi-styles: 4.3.0 supports-color: 7.2.0 - dev: true - /chalk@5.1.2: - resolution: {integrity: sha512-E5CkT4jWURs1Vy5qGJye+XwCkNj7Od3Af7CP6SujMetSMkLs8Do2RWJK5yx1wamHV/op8Rz+9rltjaTQWDnEFQ==} - engines: {node: ^12.17.0 || ^14.13 || >=16.0.0} + chalk@5.1.2: {} - /chalk@5.3.0: - resolution: {integrity: sha512-dLitG79d+GV1Nb/VYcCDFivJeK1hiukt9QjRNVOsUtTy1rR1YJsmpGGTZ3qJos+uw7WmWF4wUwBd9jxjocFC2w==} - engines: {node: ^12.17.0 || ^14.13 || >=16.0.0} + chalk@5.3.0: {} - /char-regex@1.0.2: - resolution: {integrity: sha512-kWWXztvZ5SBQV+eRgKFeh8q5sLuZY2+8WUIzlxWVTg+oGwY14qylx1KbKzHd8P6ZYkAg0xyIDU9JMHhyJMZ1jw==} - engines: {node: '>=10'} - dev: true + char-regex@1.0.2: {} - /character-entities-legacy@1.1.4: - resolution: {integrity: sha512-3Xnr+7ZFS1uxeiUDvV02wQ+QDbc55o97tIV5zHScSPJpcLm/r0DFPcoY3tYRp+VZukxuMeKgXYmsXQHO05zQeA==} - dev: true + character-entities-legacy@1.1.4: {} - /character-entities@1.2.4: - resolution: {integrity: sha512-iBMyeEHxfVnIakwOuDXpVkc54HijNgCyQB2w0VfGQThle6NXn50zU6V/u+LDhxHcDUPojn6Kpga3PTAD8W1bQw==} - dev: true + character-entities@1.2.4: {} - /character-entities@2.0.1: - resolution: {integrity: sha512-OzmutCf2Kmc+6DrFrrPS8/tDh2+DpnrfzdICHWhcVC9eOd0N1PXmQEE1a8iM4IziIAG+8tmTq3K+oo0ubH6RRQ==} - dev: true + character-entities@2.0.1: {} - /character-reference-invalid@1.1.4: - resolution: {integrity: sha512-mKKUkUbhPpQlCOfIuZkvSEgktjPFIsZKRRbC6KWVEMvlzblj3i3asQv5ODsrwt0N3pHAEvjP8KTQPHkp0+6jOg==} - dev: true + character-reference-invalid@1.1.4: {} - /chardet@0.7.0: - resolution: {integrity: sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA==} + chardet@0.7.0: {} - /check-error@1.0.3: - resolution: {integrity: sha512-iKEoDYaRmd1mxM90a2OEfWhjsjPpYPuQ+lMYsoxB126+t8fw7ySEO48nmDg5COTjxDI65/Y2OWpeEHk3ZOe8zg==} + check-error@1.0.3: dependencies: get-func-name: 2.0.2 - dev: true - /chokidar@3.5.3: - resolution: {integrity: sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==} - engines: {node: '>= 8.10.0'} + chokidar@3.5.3: dependencies: anymatch: 3.1.3 braces: 3.0.2 @@ -11241,415 +17538,239 @@ packages: readdirp: 3.6.0 optionalDependencies: fsevents: 2.3.3 - dev: true - /chownr@3.0.0: - resolution: {integrity: sha512-+IxzY9BZOQd/XuYPRmrvEVjF/nqj5kgT4kEq7VofrDoM1MxoRjEWkrCC3EtLi59TVawxTAn+orJwFQcrqEN1+g==} - engines: {node: '>=18'} - dev: false + chownr@3.0.0: {} - /chrome-trace-event@1.0.3: - resolution: {integrity: sha512-p3KULyQg4S7NIHixdwbGX+nFHkoBiA4YQmyWtjb8XngSKV124nJmRysgAeujbUVb15vh+RvFUfCPqU7rXk+hZg==} - engines: {node: '>=6.0'} - dev: true + chrome-trace-event@1.0.3: {} - /chromium-bidi@0.5.17(devtools-protocol@0.0.1262051): - resolution: {integrity: sha512-BqOuIWUgTPj8ayuBFJUYCCuwIcwjBsb3/614P7tt1bEPJ4i1M0kCdIl0Wi9xhtswBXnfO2bTpTMkHD71H8rJMg==} - peerDependencies: - devtools-protocol: '*' + chromium-bidi@0.5.17(devtools-protocol@0.0.1262051): dependencies: devtools-protocol: 0.0.1262051 mitt: 3.0.1 urlpattern-polyfill: 10.0.0 zod: 3.22.4 - dev: true - /ci-info@3.8.0: - resolution: {integrity: sha512-eXTggHWSooYhq49F2opQhuHWgzucfF2YgODK4e1566GQs5BIfP30B0oenwBJHfWxAs2fyPB1s7Mg949zLf61Yw==} - engines: {node: '>=8'} - dev: true + ci-info@3.8.0: {} - /ci-info@4.0.0: - resolution: {integrity: sha512-TdHqgGf9odd8SXNuxtUBVx8Nv+qZOejE6qyqiy5NtbYYQOeFa6zmHkxlPzmaLxWWHsU6nJmB7AETdVPi+2NBUg==} - engines: {node: '>=8'} - dev: true + ci-info@4.0.0: {} - /cjs-module-lexer@1.2.2: - resolution: {integrity: sha512-cOU9usZw8/dXIXKtwa8pM0OTJQuJkxMN6w30csNRUerHfeQ5R6U3kkU/FtJeIf3M202OHfY2U8ccInBG7/xogA==} + cjs-module-lexer@1.2.2: {} - /classnames@2.3.1: - resolution: {integrity: sha512-OlQdbZ7gLfGarSqxesMesDa5uz7KFbID8Kpq/SxIoNGDqY8lSYs0D+hhtBXhcdB3rcbXArFr7vlHheLk1voeNA==} - dev: true + classnames@2.3.1: {} - /clean-deep@3.4.0: - resolution: {integrity: sha512-Lo78NV5ItJL/jl+B5w0BycAisaieJGXK1qYi/9m4SjR8zbqmrUtO7Yhro40wEShGmmxs/aJLI/A+jNhdkXK8mw==} - engines: {node: '>=4'} + clean-deep@3.4.0: dependencies: lodash.isempty: 4.4.0 lodash.isplainobject: 4.0.6 lodash.transform: 4.6.0 - /clean-regexp@1.0.0: - resolution: {integrity: sha512-GfisEZEJvzKrmGWkvfhgzcz/BllN1USeqD2V6tg14OAOgaCD2Z/PUEuxnAZ/nPvmaHRG7a8y77p1T/IRQ4D1Hw==} - engines: {node: '>=4'} + clean-regexp@1.0.0: dependencies: escape-string-regexp: 1.0.5 - dev: true - /cli-cursor@4.0.0: - resolution: {integrity: sha512-VGtlMu3x/4DOtIUwEkRezxUZ2lBacNJCHash0N0WeZDBS+7Ux1dm3XWAgWYxLJFMMdOeXMHXorshEFhbMSGelg==} - engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + cli-cursor@4.0.0: dependencies: restore-cursor: 4.0.0 - /cli-spinners@2.7.0: - resolution: {integrity: sha512-qu3pN8Y3qHNgE2AFweciB1IfMnmZ/fsNTEE+NOFjmGB2F/7rLhnhzppvpCnN4FovtP26k8lHyy9ptEbNwWFLzw==} - engines: {node: '>=6'} - dev: false + cli-spinners@2.7.0: {} - /cli-spinners@2.9.2: - resolution: {integrity: sha512-ywqV+5MmyL4E7ybXgKys4DugZbX0FC6LnwrhjuykIjnK9k8OQacQ7axGKnjDXWNhns0xot3bZI5h55H8yo9cJg==} - engines: {node: '>=6'} - dev: false + cli-spinners@2.9.2: {} - /cli-truncate@3.1.0: - resolution: {integrity: sha512-wfOBkjXteqSnI59oPcJkcPl/ZmwvMMOj340qUIY1SKZCv0B9Cf4D4fAucRkIKQmsIuYK3x1rrgU7MeGRruiuiA==} - engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + cli-truncate@3.1.0: dependencies: slice-ansi: 5.0.0 string-width: 5.1.2 - dev: true - /cli-width@4.0.0: - resolution: {integrity: sha512-ZksGS2xpa/bYkNzN3BAw1wEjsLV/ZKOf/CCrJ/QOBsxx6fOARIkwTutxp1XIOIohi6HKmOFjMoK/XaqDVUpEEw==} - engines: {node: '>= 12'} - dev: false + cli-width@4.0.0: {} - /cliui@6.0.0: - resolution: {integrity: sha512-t6wbgtoCXvAzst7QgXxJYqPt0usEfbgQdftEPbLL/cvv6HPE5VgvqCuAIDR0NgU52ds6rFwqrgakNLrHEjCbrQ==} + cliui@6.0.0: dependencies: string-width: 4.2.3 strip-ansi: 6.0.1 wrap-ansi: 6.2.0 - /cliui@8.0.1: - resolution: {integrity: sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==} - engines: {node: '>=12'} + cliui@8.0.1: dependencies: string-width: 4.2.3 strip-ansi: 6.0.1 wrap-ansi: 7.0.0 - /clone@1.0.4: - resolution: {integrity: sha512-JQHZ2QMW6l3aH/j6xCqQThY/9OH4D/9ls34cgkUBiEeocRTU04tHfKPBsUK1PqZCUQM7GiA0IIXJSuXHI64Kbg==} - engines: {node: '>=0.8'} + clone@1.0.4: {} - /clone@2.1.2: - resolution: {integrity: sha512-3Pe/CF1Nn94hyhIYpjtiLhdCoEoz0DqQ+988E9gmeEdQZlojxnOb74wctFyuwWQHzqyf9X7C7MG8juUpqBJT8w==} - engines: {node: '>=0.8'} - dev: true + clone@2.1.2: {} - /cls-hooked@4.2.2: - resolution: {integrity: sha512-J4Xj5f5wq/4jAvcdgoGsL3G103BtWpZrMo8NEinRltN+xpTZdI+M38pyQqhuFU/P792xkMFvnKSf+Lm81U1bxw==} - engines: {node: ^4.7 || >=6.9 || >=7.3 || >=8.2.1} + cls-hooked@4.2.2: dependencies: async-hook-jl: 1.7.6 emitter-listener: 1.1.2 semver: 5.7.2 - dev: false - /cluster-key-slot@1.1.2: - resolution: {integrity: sha512-RMr0FhtfXemyinomL4hrWcYJxmX6deFdCxpJzhDttxgO1+bcCnkk+9drydLVDmAMG7NE6aN/fl4F7ucU/90gAA==} - engines: {node: '>=0.10.0'} - dev: false + cluster-key-slot@1.1.2: {} - /co-body@6.1.0: - resolution: {integrity: sha512-m7pOT6CdLN7FuXUcpuz/8lfQ/L77x8SchHCF4G0RBTJO20Wzmhn5Sp4/5WsKy8OSpifBSUrmg83qEqaDHdyFuQ==} + co-body@6.1.0: dependencies: inflation: 2.0.0 qs: 6.12.1 raw-body: 2.5.2 type-is: 1.6.18 - dev: false - /co@4.6.0: - resolution: {integrity: sha512-QVb0dM5HvG+uaxitm8wONl7jltx8dqhfU33DcqtOZcLSVIKSDDLDi7+0LbAKiyI8hD9u42m2YxXSkMGWThaecQ==} - engines: {iojs: '>= 1.0.0', node: '>= 0.12.0'} + co@4.6.0: {} - /collapse-white-space@1.0.6: - resolution: {integrity: sha512-jEovNnrhMuqyCcjfEJA56v0Xq8SkIoPKDyaHahwo3POf4qcSXqMYuwNcOTzp74vTsR9Tn08z4MxWqAhcekogkQ==} - dev: true + collapse-white-space@1.0.6: {} - /collect-v8-coverage@1.0.1: - resolution: {integrity: sha512-iBPtljfCNcTKNAto0KEtDfZ3qzjJvqE3aTGZsbhjSBlorqpXJlaWWtPO35D+ZImoC3KWejX64o+yPGxhWSTzfg==} - dev: true + collect-v8-coverage@1.0.1: {} - /color-convert@1.9.3: - resolution: {integrity: sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==} + color-convert@1.9.3: dependencies: color-name: 1.1.3 - /color-convert@2.0.1: - resolution: {integrity: sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==} - engines: {node: '>=7.0.0'} + color-convert@2.0.1: dependencies: color-name: 1.1.4 - /color-name@1.1.3: - resolution: {integrity: sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==} + color-name@1.1.3: {} - /color-name@1.1.4: - resolution: {integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==} + color-name@1.1.4: {} - /color-string@1.9.1: - resolution: {integrity: sha512-shrVawQFojnZv6xM40anx4CkoDP+fZsw/ZerEMsW/pyzsRbElpsL/DBVW7q3ExxwusdNXI3lXpuhEZkzs8p5Eg==} + color-string@1.9.1: dependencies: color-name: 1.1.4 simple-swizzle: 0.2.2 - /color@4.2.3: - resolution: {integrity: sha512-1rXeuUUiGGrykh+CeBdu5Ie7OJwinCgQY0bc7GCRxy5xVHy+moaqkpL/jqQq0MtQOeYcrqEz4abc5f0KtU7W4A==} - engines: {node: '>=12.5.0'} + color@4.2.3: dependencies: color-convert: 2.0.1 color-string: 1.9.1 - /colord@2.9.3: - resolution: {integrity: sha512-jeC1axXpnb0/2nn/Y1LPuLdgXBLH7aDcHu4KEKfqw3CUhX7ZpfBSlPKyqXE6btIgEzfWtrX3/tyBCaCvXvMkOw==} - dev: true + colord@2.9.3: {} - /colorette@2.0.20: - resolution: {integrity: sha512-IfEDxwoWIjkeXL1eXcDiow4UbKjhLdq6/EuSVR9GMN7KVH3r9gQ83e73hsz1Nd1T3ijd5xv1wcWRYO+D6kCI2w==} - dev: true + colorette@2.0.20: {} - /combined-stream@1.0.8: - resolution: {integrity: sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==} - engines: {node: '>= 0.8'} + combined-stream@1.0.8: dependencies: delayed-stream: 1.0.0 - /comma-separated-tokens@1.0.8: - resolution: {integrity: sha512-GHuDRO12Sypu2cV70d1dkA2EUmXHgntrzbpvOB+Qy+49ypNfGgFQIC2fhhXbnyrJRynDCAARsT7Ou0M6hirpfw==} - dev: true + comma-separated-tokens@1.0.8: {} - /comma-separated-tokens@2.0.2: - resolution: {integrity: sha512-G5yTt3KQN4Yn7Yk4ed73hlZ1evrFKXeUW3086p3PRFNp7m2vIjI6Pg+Kgb+oyzhd9F2qdcoj67+y3SdxL5XWsg==} - dev: true + comma-separated-tokens@2.0.2: {} - /commander@11.1.0: - resolution: {integrity: sha512-yPVavfyCcRhmorC7rWlkHn15b4wDVgVmBA7kV4QVBsF7kv/9TKJAbAXVTxvTnwP8HHKjRCJDClKbciiYS7p0DQ==} - engines: {node: '>=16'} - dev: true + commander@11.1.0: {} - /commander@5.1.0: - resolution: {integrity: sha512-P0CysNDQ7rtVw4QIQtm+MRxV66vKFSvlsQvGYXZWR3qFU0jlMKHZZZgw8e+8DSah4UDKMqnknRDQz+xuQXQ/Zg==} - engines: {node: '>= 6'} - dev: true + commander@5.1.0: {} - /commander@7.2.0: - resolution: {integrity: sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw==} - engines: {node: '>= 10'} - dev: true + commander@7.2.0: {} - /commondir@1.0.1: - resolution: {integrity: sha512-W9pAhw0ja1Edb5GVdIF1mjZw/ASI0AlShXM83UUGe2DVr5TdAPEA1OA8m/g8zWp9x6On7gqufY+FatDbC3MDQg==} - dev: true + commondir@1.0.1: {} - /compare-func@2.0.0: - resolution: {integrity: sha512-zHig5N+tPWARooBnb0Zx1MFcdfpyJrfTJ3Y5L+IFvUm8rM74hHz66z0gw0x4tijh5CorKkKUCnW82R2vmpeCRA==} + compare-func@2.0.0: dependencies: array-ify: 1.0.0 dot-prop: 5.3.0 - dev: true - /component-emitter@1.3.0: - resolution: {integrity: sha512-Rd3se6QB+sO1TwqZjscQrurpEPIfO0/yYnSin6Q/rD3mOutHvUrCAhJub3r90uNb+SESBuE0QYoB90YdfatsRg==} - dev: true + component-emitter@1.3.0: {} - /compressible@2.0.18: - resolution: {integrity: sha512-AF3r7P5dWxL8MxyITRMlORQNaOA2IkAFaTr4k7BUumjPtRpGDTZpl0Pb1XCO6JeDCBdp126Cgs9sMxqSjgYyRg==} - engines: {node: '>= 0.6'} + compressible@2.0.18: dependencies: mime-db: 1.52.0 - dev: false - /concat-map@0.0.1: - resolution: {integrity: sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==} - dev: true + concat-map@0.0.1: {} - /confusing-browser-globals@1.0.11: - resolution: {integrity: sha512-JsPKdmh8ZkmnHxDk55FZ1TqVLvEQTvoByJZRN9jzI0UjxK/QgAmsphz7PGtqgPieQZ/CQcHWXCR7ATDNhGe+YA==} - dev: true + confusing-browser-globals@1.0.11: {} - /content-disposition@0.5.4: - resolution: {integrity: sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ==} - engines: {node: '>= 0.6'} + content-disposition@0.5.4: dependencies: safe-buffer: 5.2.1 - /content-type@1.0.4: - resolution: {integrity: sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA==} - engines: {node: '>= 0.6'} + content-type@1.0.4: {} - /content-type@1.0.5: - resolution: {integrity: sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==} - engines: {node: '>= 0.6'} - dev: false + content-type@1.0.5: {} - /continuation-local-storage@3.2.1: - resolution: {integrity: sha512-jx44cconVqkCEEyLSKWwkvUXwO561jXMa3LPjTPsm5QR22PA0/mhe33FT4Xb5y74JDvt/Cq+5lm8S8rskLv9ZA==} + continuation-local-storage@3.2.1: dependencies: async-listener: 0.6.10 emitter-listener: 1.1.2 - dev: false - /conventional-changelog-angular@7.0.0: - resolution: {integrity: sha512-ROjNchA9LgfNMTTFSIWPzebCwOGFdgkEq45EnvvrmSLvCtAw0HSmrCs7/ty+wAeYUZyNay0YMUNYFTRL72PkBQ==} - engines: {node: '>=16'} + conventional-changelog-angular@7.0.0: dependencies: compare-func: 2.0.0 - dev: true - /conventional-changelog-conventionalcommits@7.0.2: - resolution: {integrity: sha512-NKXYmMR/Hr1DevQegFB4MwfM5Vv0m4UIxKZTTYuD98lpTknaZlSRrDOG4X7wIXpGkfsYxZTghUN+Qq+T0YQI7w==} - engines: {node: '>=16'} + conventional-changelog-conventionalcommits@7.0.2: dependencies: compare-func: 2.0.0 - dev: true - /conventional-commits-parser@5.0.0: - resolution: {integrity: sha512-ZPMl0ZJbw74iS9LuX9YIAiW8pfM5p3yh2o/NbXHbkFuZzY5jvdi5jFycEOkmBW5H5I7nA+D6f3UcsCLP2vvSEA==} - engines: {node: '>=16'} - hasBin: true + conventional-commits-parser@5.0.0: dependencies: JSONStream: 1.3.5 is-text-path: 2.0.0 meow: 12.1.1 split2: 4.2.0 - dev: true - /convert-source-map@1.9.0: - resolution: {integrity: sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A==} - dev: true + convert-source-map@1.9.0: {} - /convert-source-map@2.0.0: - resolution: {integrity: sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==} - dev: true + convert-source-map@2.0.0: {} - /cookiejar@2.1.4: - resolution: {integrity: sha512-LDx6oHrK+PhzLKJU9j5S7/Y3jM/mUHvD/DeI1WQmJn652iPC5Y4TBzC9l+5OMOXlyTTA+SmVUPm0HQUwpD5Jqw==} - dev: true + cookiejar@2.1.4: {} - /cookies@0.8.0: - resolution: {integrity: sha512-8aPsApQfebXnuI+537McwYsDtjVxGm8gTIzQI3FDW6t5t/DAhERxtnbEPN/8RX+uZthoz4eCOgloXaE5cYyNow==} - engines: {node: '>= 0.8'} + cookies@0.8.0: dependencies: depd: 2.0.0 keygrip: 1.1.0 - /cookies@0.9.1: - resolution: {integrity: sha512-TG2hpqe4ELx54QER/S3HQ9SRVnQnGBtKUz5bLQWtYAQ+o6GpgMs6sYUvaiJjVxb+UXwhRhAEP3m7LbsIZ77Hmw==} - engines: {node: '>= 0.8'} + cookies@0.9.1: dependencies: depd: 2.0.0 keygrip: 1.1.0 - dev: false - /core-js-compat@3.37.0: - resolution: {integrity: sha512-vYq4L+T8aS5UuFg4UwDhc7YNRWVeVZwltad9C/jV3R2LgVOpS9BDr7l/WL6BN0dbV3k1XejPTHqqEzJgsa0frA==} + core-js-compat@3.37.0: dependencies: browserslist: 4.23.0 - dev: true - /core-js@3.34.0: - resolution: {integrity: sha512-aDdvlDder8QmY91H88GzNi9EtQi2TjvQhpCX6B1v/dAZHU1AuLgHvRh54RiOerpEhEW46Tkf+vgAViB/CWC0ag==} - requiresBuild: true - dev: true + core-js@3.34.0: {} - /cosmiconfig-typescript-loader@5.0.0(@types/node@20.12.7)(cosmiconfig@8.3.6)(typescript@5.0.2): - resolution: {integrity: sha512-+8cK7jRAReYkMwMiG+bxhcNKiHJDM6bR9FD/nGBXOWdMLuYawjF5cGrtLilJ+LGd3ZjCXnJjR5DkfWPoIVlqJA==} - engines: {node: '>=v16'} - peerDependencies: - '@types/node': '*' - cosmiconfig: '>=8.2' - typescript: '>=4' + cosmiconfig-typescript-loader@5.0.0(@types/node@20.12.7)(cosmiconfig@8.3.6)(typescript@5.0.2): dependencies: '@types/node': 20.12.7 cosmiconfig: 8.3.6(typescript@5.0.2) jiti: 1.21.0 typescript: 5.0.2 - dev: true - /cosmiconfig@7.1.0: - resolution: {integrity: sha512-AdmX6xUzdNASswsFtmwSt7Vj8po9IuqXm0UXz7QKPuEUmPB4XyjGfaAr2PSuELMwkRMVH1EpIkX5bTZGRB3eCA==} - engines: {node: '>=10'} + cosmiconfig@7.1.0: dependencies: '@types/parse-json': 4.0.0 import-fresh: 3.3.0 parse-json: 5.2.0 path-type: 4.0.0 yaml: 1.10.2 - dev: true - /cosmiconfig@8.3.6(typescript@5.0.2): - resolution: {integrity: sha512-kcZ6+W5QzcJ3P1Mt+83OUv/oHFqZHIx8DuxG6eZ5RGMERoLqp4BuGjhHLYGK+Kf5XVkQvqBSmAy/nGWN3qDgEA==} - engines: {node: '>=14'} - peerDependencies: - typescript: '>=4.9.5' - peerDependenciesMeta: - typescript: - optional: true + cosmiconfig@8.3.6(typescript@5.0.2): dependencies: import-fresh: 3.3.0 js-yaml: 4.1.0 parse-json: 5.2.0 path-type: 4.0.0 typescript: 5.0.2 - dev: true - /cosmiconfig@8.3.6(typescript@5.3.3): - resolution: {integrity: sha512-kcZ6+W5QzcJ3P1Mt+83OUv/oHFqZHIx8DuxG6eZ5RGMERoLqp4BuGjhHLYGK+Kf5XVkQvqBSmAy/nGWN3qDgEA==} - engines: {node: '>=14'} - peerDependencies: - typescript: '>=4.9.5' - peerDependenciesMeta: - typescript: - optional: true + cosmiconfig@8.3.6(typescript@5.3.3): dependencies: import-fresh: 3.3.0 js-yaml: 4.1.0 parse-json: 5.2.0 path-type: 4.0.0 typescript: 5.3.3 - dev: true - /cosmiconfig@9.0.0(typescript@5.3.3): - resolution: {integrity: sha512-itvL5h8RETACmOTFc4UfIyB2RfEHi71Ax6E/PivVxq9NseKbOWpeyHEOIbmAw1rs8Ak0VursQNww7lf7YtUwzg==} - engines: {node: '>=14'} - peerDependencies: - typescript: '>=4.9.5' - peerDependenciesMeta: - typescript: - optional: true + cosmiconfig@9.0.0(typescript@5.3.3): dependencies: env-paths: 2.2.1 import-fresh: 3.3.0 js-yaml: 4.1.0 parse-json: 5.2.0 typescript: 5.3.3 - dev: true - /create-eslint-index@1.0.0: - resolution: {integrity: sha512-nXvJjnfDytOOaPOonX0h0a1ggMoqrhdekGeZkD6hkcWYvlCWhU719tKFVh8eU04CnMwu3uwe1JjwuUF2C3k2qg==} - engines: {node: '>=4.0.0'} + create-eslint-index@1.0.0: dependencies: - lodash.get: 4.4.2 - dev: true - - /create-jest@29.7.0(@types/node@20.10.4): - resolution: {integrity: sha512-Adz2bdH0Vq3F53KEMJOoftQFutWCukm6J24wbPWRO4k1kMY7gS7ds/uoJkNuV8wDCtWWnuwGcJwpWcih+zEW1Q==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - hasBin: true + lodash.get: 4.4.2 + + create-jest@29.7.0(@types/node@20.10.4): dependencies: '@jest/types': 29.6.3 chalk: 4.1.2 @@ -11663,12 +17784,8 @@ packages: - babel-plugin-macros - supports-color - ts-node - dev: true - /create-jest@29.7.0(@types/node@20.12.7)(ts-node@10.9.2): - resolution: {integrity: sha512-Adz2bdH0Vq3F53KEMJOoftQFutWCukm6J24wbPWRO4k1kMY7gS7ds/uoJkNuV8wDCtWWnuwGcJwpWcih+zEW1Q==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - hasBin: true + create-jest@29.7.0(@types/node@20.12.7)(ts-node@10.9.2): dependencies: '@jest/types': 29.6.3 chalk: 4.1.2 @@ -11682,727 +17799,416 @@ packages: - babel-plugin-macros - supports-color - ts-node - dev: true - /create-require@1.1.1: - resolution: {integrity: sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==} - dev: true + create-require@1.1.1: {} - /cross-env@7.0.3: - resolution: {integrity: sha512-+/HKd6EgcQCJGh2PSjZuUitQBQynKor4wrFbRg4DtAgS1aWO+gU52xpH7M9ScGgXSYmAVS9bIJ8EzuaGw0oNAw==} - engines: {node: '>=10.14', npm: '>=6', yarn: '>=1'} - hasBin: true + cross-env@7.0.3: dependencies: cross-spawn: 7.0.3 - dev: true - /cross-fetch@4.0.0: - resolution: {integrity: sha512-e4a5N8lVvuLgAWgnCrLr2PP0YyDOTHa9H/Rj54dirp61qXnNq46m82bRhNqIA5VccJtWBvPTFRV3TtvHUKPB1g==} + cross-fetch@4.0.0: dependencies: node-fetch: 2.7.0 transitivePeerDependencies: - encoding - dev: false - /cross-spawn@5.1.0: - resolution: {integrity: sha512-pTgQJ5KC0d2hcY8eyL1IzlBPYjTkyH72XRZPnLyKus2mBfNjQs3klqbJU2VILqZryAZUt9JOb3h/mWMy23/f5A==} + cross-spawn@5.1.0: dependencies: lru-cache: 4.1.5 shebang-command: 1.2.0 which: 1.3.1 - dev: true - /cross-spawn@7.0.3: - resolution: {integrity: sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==} - engines: {node: '>= 8'} + cross-spawn@7.0.3: dependencies: path-key: 3.1.1 shebang-command: 2.0.0 which: 2.0.2 - /css-functions-list@3.2.1: - resolution: {integrity: sha512-Nj5YcaGgBtuUmn1D7oHqPW0c9iui7xsTsj5lIX8ZgevdfhmjFfKB3r8moHJtNJnctnYXJyYX5I1pp90HM4TPgQ==} - engines: {node: '>=12 || >=16'} - dev: true + css-functions-list@3.2.1: {} - /css-select@4.3.0: - resolution: {integrity: sha512-wPpOYtnsVontu2mODhA19JrqWxNsfdatRKd64kmpRbQgh1KtItko5sTnEpPdpSaJszTOhEMlF/RPz28qj4HqhQ==} + css-select@4.3.0: dependencies: boolbase: 1.0.0 css-what: 6.1.0 domhandler: 4.3.1 domutils: 2.8.0 nth-check: 2.1.1 - dev: true - /css-tree@1.1.3: - resolution: {integrity: sha512-tRpdppF7TRazZrjJ6v3stzv93qxRcSsFmW6cX0Zm2NVKpxE1WV1HblnghVv9TreireHkqI/VDEsfolRF1p6y7Q==} - engines: {node: '>=8.0.0'} + css-tree@1.1.3: dependencies: mdn-data: 2.0.14 source-map: 0.6.1 - dev: true - /css-tree@2.3.1: - resolution: {integrity: sha512-6Fv1DV/TYw//QF5IzQdqsNDjx/wc8TrMBZsqjL9eW01tWb7R7k/mq+/VXfJCl7SoD5emsJop9cOByJZfs8hYIw==} - engines: {node: ^10 || ^12.20.0 || ^14.13.0 || >=15.0.0} + css-tree@2.3.1: dependencies: mdn-data: 2.0.30 source-map-js: 1.2.0 - dev: true - /css-unit-converter@1.1.2: - resolution: {integrity: sha512-IiJwMC8rdZE0+xiEZHeru6YoONC4rfPMqGm2W85jMIbkFvv5nFTwJVFHam2eFrN6txmoUYFAFXiv8ICVeTO0MA==} - dev: true + css-unit-converter@1.1.2: {} - /css-what@6.1.0: - resolution: {integrity: sha512-HTUrgRJ7r4dsZKU6GjmpfRK1O76h97Z8MfS1G0FozR+oF2kG6Vfe8JE6zwrkbxigziPHinCJ+gCPjA9EaBDtRw==} - engines: {node: '>= 6'} - dev: true + css-what@6.1.0: {} - /cssesc@3.0.0: - resolution: {integrity: sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==} - engines: {node: '>=4'} - hasBin: true - dev: true + cssesc@3.0.0: {} - /csso@4.2.0: - resolution: {integrity: sha512-wvlcdIbf6pwKEk7vHj8/Bkc0B4ylXZruLvOgs9doS5eOsOpuodOV2zJChSpkp+pRpYQLQMeF04nr3Z68Sta9jA==} - engines: {node: '>=8.0.0'} + csso@4.2.0: dependencies: css-tree: 1.1.3 - dev: true - /cssom@0.3.8: - resolution: {integrity: sha512-b0tGHbfegbhPJpxpiBPU2sCkigAqtM9O121le6bbOlgyV+NyGyCmVfJ6QW9eRjz8CpNfWEOYBIMIGRYkLwsIYg==} - dev: true + cssom@0.3.8: {} - /cssom@0.5.0: - resolution: {integrity: sha512-iKuQcq+NdHqlAcwUY0o/HL69XQrUaQdMjmStJ8JFmUaiiQErlhrmuigkg/CU4E2J0IyUKUrMAgl36TvN67MqTw==} - dev: true + cssom@0.5.0: {} - /cssstyle@2.3.0: - resolution: {integrity: sha512-AZL67abkUzIuvcHqk7c09cezpGNcxUxU4Ioi/05xHk4DQeTkWmGYftIE6ctU6AEt+Gn4n1lDStOtj7FKycP71A==} - engines: {node: '>=8'} + cssstyle@2.3.0: dependencies: cssom: 0.3.8 - dev: true - /csstype@3.0.11: - resolution: {integrity: sha512-sa6P2wJ+CAbgyy4KFssIb/JNMLxFvKF1pCYCSXS8ZMuqZnMsrxqI2E5sPyoTpxoPU/gVZMzr2zjOfg8GIZOMsw==} - dev: true + csstype@3.0.11: {} - /csv-generate@3.4.3: - resolution: {integrity: sha512-w/T+rqR0vwvHqWs/1ZyMDWtHHSJaN06klRqJXBEpDJaM/+dZkso0OKh1VcuuYvK3XM53KysVNq8Ko/epCK8wOw==} - dev: true + csv-generate@3.4.3: {} - /csv-parse@4.16.3: - resolution: {integrity: sha512-cO1I/zmz4w2dcKHVvpCr7JVRu8/FymG5OEpmvsZYlccYolPBLoVGKUHgNoc4ZGkFeFlWGEDmMyBM+TTqRdW/wg==} - dev: true + csv-parse@4.16.3: {} - /csv-stringify@5.6.5: - resolution: {integrity: sha512-PjiQ659aQ+fUTQqSrd1XEDnOr52jh30RBurfzkscaE2tPaFsDH5wOAHJiw8XAHphRknCwMUE9KRayc4K/NbO8A==} - dev: true + csv-stringify@5.6.5: {} - /csv@5.5.3: - resolution: {integrity: sha512-QTaY0XjjhTQOdguARF0lGKm5/mEq9PD9/VhZZegHDIBq2tQwgNpHc3dneD4mGo2iJs+fTKv5Bp0fZ+BRuY3Z0g==} - engines: {node: '>= 0.1.90'} + csv@5.5.3: dependencies: csv-generate: 3.4.3 csv-parse: 4.16.3 csv-stringify: 5.6.5 stream-transform: 2.1.3 - dev: true - /cwd@0.10.0: - resolution: {integrity: sha512-YGZxdTTL9lmLkCUTpg4j0zQ7IhRB5ZmqNBbGCl3Tg6MP/d5/6sY7L5mmTjzbc6JKgVZYiqTQTNhPFsbXNGlRaA==} - engines: {node: '>=0.8'} + cwd@0.10.0: dependencies: find-pkg: 0.1.2 fs-exists-sync: 0.1.0 - dev: true - /d3-array@2.12.1: - resolution: {integrity: sha512-B0ErZK/66mHtEsR1TkPEEkwdy+WDesimkM5gpZr5Dsg54BiTA5RXtYW5qTLIAcekaS9xfZrzBLF/OAkB3Qn1YQ==} + d3-array@2.12.1: dependencies: internmap: 1.0.1 - dev: true - /d3-color@2.0.0: - resolution: {integrity: sha512-SPXi0TSKPD4g9tw0NMZFnR95XVgUZiBH+uUTqQuDu1OsE2zomHU7ho0FISciaPvosimixwHFl3WHLGabv6dDgQ==} - dev: true + d3-color@2.0.0: {} - /d3-format@2.0.0: - resolution: {integrity: sha512-Ab3S6XuE/Q+flY96HXT0jOXcM4EAClYFnRGY5zsjRGNy6qCYrQsMffs7cV5Q9xejb35zxW5hf/guKw34kvIKsA==} - dev: true + d3-format@2.0.0: {} - /d3-interpolate@3.0.1: - resolution: {integrity: sha512-3bYs1rOD33uo8aqJfKP3JWPAibgw8Zm2+L9vBKEHJ2Rg+viTR7o5Mmv5mZcieN+FRYaAOWX5SJATX6k1PWz72g==} - engines: {node: '>=12'} + d3-interpolate@3.0.1: dependencies: d3-color: 2.0.0 - dev: true - /d3-path@2.0.0: - resolution: {integrity: sha512-ZwZQxKhBnv9yHaiWd6ZU4x5BtCQ7pXszEV9CU6kRgwIQVQGLMv1oiL4M+MK/n79sYzsj+gcgpPQSctJUsLN7fA==} - dev: true + d3-path@2.0.0: {} - /d3-scale@4.0.2: - resolution: {integrity: sha512-GZW464g1SH7ag3Y7hXjf8RoUuAFIqklOAq3MRl4OaWabTFJY9PN/E1YklhXLh+OQ3fM9yS2nOkCoS+WLZ6kvxQ==} - engines: {node: '>=12'} + d3-scale@4.0.2: dependencies: d3-array: 2.12.1 d3-format: 2.0.0 d3-interpolate: 3.0.1 d3-time: 2.1.1 d3-time-format: 3.0.0 - dev: true - /d3-shape@3.1.0: - resolution: {integrity: sha512-tGDh1Muf8kWjEDT/LswZJ8WF85yDZLvVJpYU9Nq+8+yW1Z5enxrmXOhTArlkaElU+CTn0OTVNli+/i+HP45QEQ==} - engines: {node: '>=12'} + d3-shape@3.1.0: dependencies: d3-path: 2.0.0 - dev: true - /d3-time-format@3.0.0: - resolution: {integrity: sha512-UXJh6EKsHBTjopVqZBhFysQcoXSv/5yLONZvkQ5Kk3qbwiUYkdX17Xa1PT6U1ZWXGGfB1ey5L8dKMlFq2DO0Ag==} + d3-time-format@3.0.0: dependencies: d3-time: 2.1.1 - dev: true - /d3-time@2.1.1: - resolution: {integrity: sha512-/eIQe/eR4kCQwq7yxi7z4c6qEXf2IYGcjoWB5OOQy4Tq9Uv39/947qlDcN2TLkiTzQWzvnsuYPB9TrWaNfipKQ==} + d3-time@2.1.1: dependencies: d3-array: 2.12.1 - dev: true - /damerau-levenshtein@1.0.8: - resolution: {integrity: sha512-sdQSFB7+llfUcQHUQO3+B8ERRj0Oa4w9POWMI/puGtuf7gFywGmkaLCElnudfTiKZV+NvHqL0ifzdrI8Ro7ESA==} - dev: true + damerau-levenshtein@1.0.8: {} - /dargs@8.1.0: - resolution: {integrity: sha512-wAV9QHOsNbwnWdNW2FYvE1P56wtgSbM+3SZcdGiWQILwVjACCXDCI3Ai8QlCjMDB8YK5zySiXZYBiwGmNY3lnw==} - engines: {node: '>=12'} - dev: true + dargs@8.1.0: {} - /data-uri-to-buffer@5.0.1: - resolution: {integrity: sha512-a9l6T1qqDogvvnw0nKlfZzqsyikEBZBClF39V3TFoKhDtGBqHu2HkuomJc02j5zft8zrUaXEuoicLeW54RkzPg==} - engines: {node: '>= 14'} - dev: true + data-uri-to-buffer@5.0.1: {} - /data-urls@3.0.2: - resolution: {integrity: sha512-Jy/tj3ldjZJo63sVAvg6LHt2mHvl4V6AgRAmNDtLdm7faqtsx+aJG42rsyCo9JCoRVKwPFzKlIPx3DIibwSIaQ==} - engines: {node: '>=12'} + data-urls@3.0.2: dependencies: abab: 2.0.6 whatwg-mimetype: 3.0.0 whatwg-url: 11.0.0 - dev: true - /data-view-buffer@1.0.1: - resolution: {integrity: sha512-0lht7OugA5x3iJLOWFhWK/5ehONdprk0ISXqVFn/NFrDu+cuc8iADFrGQz5BnRK7LLU3JmkbXSxaqX+/mXYtUA==} - engines: {node: '>= 0.4'} + data-view-buffer@1.0.1: dependencies: call-bind: 1.0.7 es-errors: 1.3.0 is-data-view: 1.0.1 - dev: true - /data-view-byte-length@1.0.1: - resolution: {integrity: sha512-4J7wRJD3ABAzr8wP+OcIcqq2dlUKp4DVflx++hs5h5ZKydWMI6/D/fAot+yh6g2tHh8fLFTvNOaVN357NvSrOQ==} - engines: {node: '>= 0.4'} + data-view-byte-length@1.0.1: dependencies: call-bind: 1.0.7 es-errors: 1.3.0 is-data-view: 1.0.1 - dev: true - /data-view-byte-offset@1.0.0: - resolution: {integrity: sha512-t/Ygsytq+R995EJ5PZlD4Cu56sWa8InXySaViRzw9apusqsOO2bQP+SbYzAhR0pFKoB+43lYy8rWban9JSuXnA==} - engines: {node: '>= 0.4'} + data-view-byte-offset@1.0.0: dependencies: call-bind: 1.0.7 es-errors: 1.3.0 is-data-view: 1.0.1 - dev: true - /date-fns@2.29.3: - resolution: {integrity: sha512-dDCnyH2WnnKusqvZZ6+jA1O51Ibt8ZMRNkDZdyAyK4YfbDwa/cEmuztzG5pk6hqlp9aSBPYcjOlktquahGwGeA==} - engines: {node: '>=0.11'} + date-fns@2.29.3: {} - /dayjs@1.11.6: - resolution: {integrity: sha512-zZbY5giJAinCG+7AGaw0wIhNZ6J8AhWuSXKvuc1KAyMiRsvGQWqh4L+MomvhdAYjN+lqvVCMq1I41e3YHvXkyQ==} + dayjs@1.11.6: {} - /debug@3.2.7(supports-color@5.5.0): - resolution: {integrity: sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==} - peerDependencies: - supports-color: '*' - peerDependenciesMeta: - supports-color: - optional: true + debug@3.2.7(supports-color@5.5.0): dependencies: ms: 2.1.3 supports-color: 5.5.0 - dev: true - /debug@4.3.4: - resolution: {integrity: sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==} - engines: {node: '>=6.0'} - peerDependencies: - supports-color: '*' - peerDependenciesMeta: - supports-color: - optional: true + debug@4.3.4: dependencies: ms: 2.1.2 - /decamelize-keys@1.1.1: - resolution: {integrity: sha512-WiPxgEirIV0/eIOMcnFBA3/IJZAZqKnwAwWyvvdi4lsr1WCN22nhdf/3db3DoZcUjTV2SqfzIwNyp6y2xs3nmg==} - engines: {node: '>=0.10.0'} + decamelize-keys@1.1.1: dependencies: decamelize: 1.2.0 map-obj: 1.0.1 - dev: true - /decamelize@1.2.0: - resolution: {integrity: sha512-z2S+W9X73hAUUki+N+9Za2lBlun89zigOyGrsax+KUQ6wKW4ZoWpEYBkGhQjwAjjDCkWxhY0VKEhk8wzY7F5cA==} - engines: {node: '>=0.10.0'} + decamelize@1.2.0: {} - /decamelize@5.0.1: - resolution: {integrity: sha512-VfxadyCECXgQlkoEAjeghAr5gY3Hf+IKjKb+X8tGVDtveCjN+USwprd2q3QXBR9T1+x2DG0XZF5/w+7HAtSaXA==} - engines: {node: '>=10'} - dev: true + decamelize@5.0.1: {} - /decamelize@6.0.0: - resolution: {integrity: sha512-Fv96DCsdOgB6mdGl67MT5JaTNKRzrzill5OH5s8bjYJXVlcXyPYGyPsUkWyGV5p1TXI5esYIYMMeDJL0hEIwaA==} - engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} - dev: false + decamelize@6.0.0: {} - /decimal.js-light@2.5.1: - resolution: {integrity: sha512-qIMFpTMZmny+MMIitAB6D7iVPEorVw6YQRWkvarTkT4tBeSLLiHzcwj6q0MmYSFCiVpiqPJTJEYIrpcPzVEIvg==} - dev: true + decimal.js-light@2.5.1: {} - /decimal.js@10.4.2: - resolution: {integrity: sha512-ic1yEvwT6GuvaYwBLLY6/aFFgjZdySKTE8en/fkU3QICTmRtgtSlFn0u0BXN06InZwtfCelR7j8LRiDI/02iGA==} - dev: true + decimal.js@10.4.2: {} - /decode-named-character-reference@1.0.1: - resolution: {integrity: sha512-YV/0HQHreRwKb7uBopyIkLG17jG6Sv2qUchk9qSoVJ2f+flwRsPNBO0hAnjt6mTNYUT+vw9Gy2ihXg4sUWPi2w==} + decode-named-character-reference@1.0.1: dependencies: character-entities: 2.0.1 - dev: true - /decode-uri-component@0.4.1: - resolution: {integrity: sha512-+8VxcR21HhTy8nOt6jf20w0c9CADrw1O8d+VZ/YzzCt4bJ3uBjw+D1q2osAB8RnpwwaeYBxy0HyKQxD5JBMuuQ==} - engines: {node: '>=14.16'} - dev: false + decode-uri-component@0.4.1: {} - /decompress-response@6.0.0: - resolution: {integrity: sha512-aW35yZM6Bb/4oJlZncMH2LCoZtJXTRxES17vE3hoRiowU2kWHaJKFkSBDnDR+cm9J+9QhXmREyIfv0pji9ejCQ==} - engines: {node: '>=10'} + decompress-response@6.0.0: dependencies: mimic-response: 3.1.0 - dev: false - /dedent@1.5.1: - resolution: {integrity: sha512-+LxW+KLWxu3HW3M2w2ympwtqPrqYRzU8fqi6Fhd18fBALe15blJPI/I4+UHveMVG6lJqB4JNd4UG0S5cnVHwIg==} - peerDependencies: - babel-plugin-macros: ^3.1.0 - peerDependenciesMeta: - babel-plugin-macros: - optional: true - dev: true + dedent@1.5.1: {} - /deep-eql@4.1.3: - resolution: {integrity: sha512-WaEtAOpRA1MQ0eohqZjpGD8zdI0Ovsm8mmFhaDN8dvDZzyoUMcYDnf5Y6iu7HTXxf8JDS23qWa4a+hKCDyOPzw==} - engines: {node: '>=6'} + deep-eql@4.1.3: dependencies: type-detect: 4.0.8 - dev: true - /deep-equal@1.0.1: - resolution: {integrity: sha1-9dJgKStmDghO/0zbyfCK0yR0SLU=} + deep-equal@1.0.1: {} - /deep-is@0.1.4: - resolution: {integrity: sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==} - dev: true + deep-is@0.1.4: {} - /deep-object-diff@1.1.9: - resolution: {integrity: sha512-Rn+RuwkmkDwCi2/oXOFS9Gsr5lJZu/yTGpK7wAaAIE75CC+LCGEZHpY6VQJa/RoJcrmaA/docWJZvYohlNkWPA==} - dev: true + deep-object-diff@1.1.9: {} - /deepmerge@4.2.2: - resolution: {integrity: sha512-FJ3UgI4gIl+PHZm53knsuSFpE+nESMr7M4v9QcgB7S63Kj/6WqMiFQJpBBYz1Pt+66bZpP3Q7Lye0Oo9MPKEdg==} - engines: {node: '>=0.10.0'} + deepmerge@4.2.2: {} - /deepmerge@4.3.1: - resolution: {integrity: sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==} - engines: {node: '>=0.10.0'} + deepmerge@4.3.1: {} - /defaults@1.0.4: - resolution: {integrity: sha512-eFuaLoy/Rxalv2kr+lqMlUnrDWV+3j4pljOIJgLIhI058IQfWJ7vXhyEIHu+HtC738klGALYxOKDO0bQP3tg8A==} + defaults@1.0.4: dependencies: clone: 1.0.4 - /defer-to-connect@2.0.1: - resolution: {integrity: sha512-4tvttepXG1VaYGrRibk5EwJd1t4udunSOVMdLSAL6mId1ix438oPwPZMALY41FCijukO1L0twNcGsdzS7dHgDg==} - engines: {node: '>=10'} - dev: false + defer-to-connect@2.0.1: {} - /define-data-property@1.1.4: - resolution: {integrity: sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==} - engines: {node: '>= 0.4'} + define-data-property@1.1.4: dependencies: es-define-property: 1.0.0 es-errors: 1.3.0 gopd: 1.0.1 - /define-properties@1.1.4: - resolution: {integrity: sha512-uckOqKcfaVvtBdsVkdPv3XjveQJsNQqmhXgRi8uhvWWuPYZCNlzT8qAyblUgNoXdHdjMTzAqeGjAoli8f+bzPA==} - engines: {node: '>= 0.4'} + define-properties@1.1.4: dependencies: has-property-descriptors: 1.0.0 object-keys: 1.1.1 - /define-properties@1.2.1: - resolution: {integrity: sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg==} - engines: {node: '>= 0.4'} + define-properties@1.2.1: dependencies: define-data-property: 1.1.4 has-property-descriptors: 1.0.2 object-keys: 1.1.1 - dev: true - /degenerator@5.0.1: - resolution: {integrity: sha512-TllpMR/t0M5sqCXfj85i4XaAzxmS5tVA16dqvdkMwGmzI+dXLXnw3J+3Vdv7VKw+ThlTMboK6i9rnZ6Nntj5CQ==} - engines: {node: '>= 14'} + degenerator@5.0.1: dependencies: ast-types: 0.13.4 escodegen: 2.1.0 esprima: 4.0.1 - dev: true - /delayed-stream@1.0.0: - resolution: {integrity: sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==} - engines: {node: '>=0.4.0'} + delayed-stream@1.0.0: {} - /delegates@1.0.0: - resolution: {integrity: sha1-hMbhWbgZBP3KWaDvRM2HDTElD5o=} + delegates@1.0.0: {} - /depd@1.1.2: - resolution: {integrity: sha512-7emPTl6Dpo6JRXOXjLRxck+FlLRX5847cLKEn00PLAgc3g2hTZZgr+e4c2v6QpSmLeFP3n5yUo7ft6avBK/5jQ==} - engines: {node: '>= 0.6'} + depd@1.1.2: {} - /depd@2.0.0: - resolution: {integrity: sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==} - engines: {node: '>= 0.8'} + depd@2.0.0: {} - /dequal@2.0.3: - resolution: {integrity: sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA==} - engines: {node: '>=6'} - dev: true + dequal@2.0.3: {} - /destroy@1.0.4: - resolution: {integrity: sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA=} + destroy@1.0.4: {} - /destroy@1.2.0: - resolution: {integrity: sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==} - engines: {node: '>= 0.8', npm: 1.2.8000 || >= 1.4.16} - dev: false + destroy@1.2.0: {} - /detab@2.0.4: - resolution: {integrity: sha512-8zdsQA5bIkoRECvCrNKPla84lyoR7DSAyf7p0YgXzBO9PDJx8KntPUay7NS6yp+KdxdVtiE5SpHKtbp2ZQyA9g==} + detab@2.0.4: dependencies: repeat-string: 1.6.1 - dev: true - /detect-indent@6.1.0: - resolution: {integrity: sha512-reYkTUJAZb9gUuZ2RvVCNhVHdg62RHnJ7WJl8ftMi4diZ6NWlciOzQN88pUhSELEwflJht4oQDv0F0BMlwaYtA==} - engines: {node: '>=8'} - dev: true + detect-indent@6.1.0: {} - /detect-libc@1.0.3: - resolution: {integrity: sha512-pGjwhsmsp4kL2RTz08wcOlGN83otlqHeD/Z5T8GXZB+/YcpQ/dgo+lbU8ZsGxV0HIvqqxo9l7mqYwyYMD9bKDg==} - engines: {node: '>=0.10'} - hasBin: true - dev: true + detect-libc@1.0.3: {} - /detect-libc@2.0.2: - resolution: {integrity: sha512-UX6sGumvvqSaXgdKGUsgZWqcUyIXZ/vZTrlRT/iobiKhGL0zL4d3osHj3uqllWJK+i+sixDS/3COVEOFbupFyw==} - engines: {node: '>=8'} - requiresBuild: true - dev: false + detect-libc@2.0.2: optional: true - /detect-newline@3.1.0: - resolution: {integrity: sha512-TLz+x/vEXm/Y7P7wn1EJFNLxYpUD4TgMosxY6fAVJUnJMbupHBOncxyWUG9OpTaH9EBD7uFI5LfEgmMOc54DsA==} - engines: {node: '>=8'} - dev: true + detect-newline@3.1.0: {} - /devlop@1.1.0: - resolution: {integrity: sha512-RWmIqhcFf1lRYBvNmr7qTNuyCt/7/ns2jbpp1+PalgE/rDQcBT0fioSMUpJ93irlUhC5hrg4cYqe6U+0ImW0rA==} + devlop@1.1.0: dependencies: dequal: 2.0.3 - dev: true - /devtools-protocol@0.0.1262051: - resolution: {integrity: sha512-YJe4CT5SA8on3Spa+UDtNhEqtuV6Epwz3OZ4HQVLhlRccpZ9/PAYk0/cy/oKxFKRrZPBUPyxympQci4yWNWZ9g==} - dev: true + devtools-protocol@0.0.1262051: {} - /dezalgo@1.0.4: - resolution: {integrity: sha512-rXSP0bf+5n0Qonsb+SVVfNfIsimO4HEtmnIpPHY8Q1UCzKlQrDMfdobr8nJOOsRgWCyMRqeSBQzmWUMq7zvVig==} + dezalgo@1.0.4: dependencies: asap: 2.0.6 wrappy: 1.0.2 - /diagnostic-channel-publishers@1.0.8(diagnostic-channel@1.1.1): - resolution: {integrity: sha512-HmSm9hXxSPxA9BaLGY98QU1zsdjeCk113KjAYGPCen1ZP6mhVaTPzHd6UYv5r21DnWANi+f+NyPOHruGT9jpqQ==} - peerDependencies: - diagnostic-channel: '*' + diagnostic-channel-publishers@1.0.8(diagnostic-channel@1.1.1): dependencies: diagnostic-channel: 1.1.1 - dev: false - /diagnostic-channel@1.1.1: - resolution: {integrity: sha512-r2HV5qFkUICyoaKlBEpLKHjxMXATUf/l+h8UZPGBHGLy4DDiY2sOLcIctax4eRnTw5wH2jTMExLntGPJ8eOJxw==} + diagnostic-channel@1.1.1: dependencies: semver: 7.6.0 - dev: false - /diff-sequences@29.6.3: - resolution: {integrity: sha512-EjePK1srD3P08o2j4f0ExnylqRs5B9tJjcp9t1krH2qRi8CCdsYfwe9JgSLurFBWwq4uOlipzfk5fHNvwFKr8Q==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - dev: true + diff-sequences@29.6.3: {} - /diff@4.0.2: - resolution: {integrity: sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==} - engines: {node: '>=0.3.1'} - dev: true + diff@4.0.2: {} - /diff@5.1.0: - resolution: {integrity: sha512-D+mk+qE8VC/PAUrlAU34N+VfXev0ghe5ywmpqrawphmVZc1bEfn56uo9qpyGp1p4xpzOHkSW4ztBd6L7Xx4ACw==} - engines: {node: '>=0.3.1'} - dev: true + diff@5.1.0: {} - /dijkstrajs@1.0.3: - resolution: {integrity: sha512-qiSlmBq9+BCdCA/L46dw8Uy93mloxsPSbwnm5yrKn2vMPiy8KyAskTF6zuV/j5BMsmOGZDPs7KjU+mjb670kfA==} - dev: false + dijkstrajs@1.0.3: {} - /dir-glob@3.0.1: - resolution: {integrity: sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==} - engines: {node: '>=8'} + dir-glob@3.0.1: dependencies: path-type: 4.0.0 - dev: true - /dnd-core@16.0.0: - resolution: {integrity: sha512-8cGtybb5LBjG2euYgVv3amk49F+9dH3l5TuuGQf0mhFr+KWIPE1qPxB8VpPDov74ZevUAxVDxadL2zN7I0oQ1Q==} + dnd-core@16.0.0: dependencies: '@react-dnd/asap': 5.0.0 '@react-dnd/invariant': 4.0.0 redux: 4.1.2 - dev: true - /doctrine@2.1.0: - resolution: {integrity: sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==} - engines: {node: '>=0.10.0'} + doctrine@2.1.0: dependencies: esutils: 2.0.3 - dev: true - /doctrine@3.0.0: - resolution: {integrity: sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==} - engines: {node: '>=6.0.0'} + doctrine@3.0.0: dependencies: esutils: 2.0.3 - dev: true - /dom-accessibility-api@0.5.10: - resolution: {integrity: sha512-Xu9mD0UjrJisTmv7lmVSDMagQcU9R5hwAbxsaAE/35XPnPLJobbuREfV/rraiSaEj/UOvgrzQs66zyTWTlyd+g==} - dev: true + dom-accessibility-api@0.5.10: {} - /dom-helpers@3.4.0: - resolution: {integrity: sha512-LnuPJ+dwqKDIyotW1VzmOZ5TONUN7CwkCR5hrgawTUbkBGYdeoNLZo6nNfGkCrjtE1nXXaj7iMMpDa8/d9WoIA==} + dom-helpers@3.4.0: dependencies: '@babel/runtime': 7.21.0 - dev: true - /dom-serializer@1.4.1: - resolution: {integrity: sha512-VHwB3KfrcOOkelEG2ZOfxqLZdfkil8PtJi4P8N2MMXucZq2yLp75ClViUlOVwyoHEDjYU433Aq+5zWP61+RGag==} + dom-serializer@1.4.1: dependencies: domelementtype: 2.3.0 domhandler: 4.3.1 entities: 2.2.0 - dev: true - /domelementtype@2.3.0: - resolution: {integrity: sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw==} - dev: true + domelementtype@2.3.0: {} - /domexception@4.0.0: - resolution: {integrity: sha512-A2is4PLG+eeSfoTMA95/s4pvAoSo2mKtiM5jlHkAVewmiO8ISFTFKZjH7UAM1Atli/OT/7JHOrJRJiMKUZKYBw==} - engines: {node: '>=12'} + domexception@4.0.0: dependencies: webidl-conversions: 7.0.0 - dev: true - /domhandler@4.3.1: - resolution: {integrity: sha512-GrwoxYN+uWlzO8uhUXRl0P+kHE4GtVPfYzVLcUxPL7KNdHKj66vvlhiweIHqYYXWlw+T8iLMp42Lm67ghw4WMQ==} - engines: {node: '>= 4'} + domhandler@4.3.1: dependencies: domelementtype: 2.3.0 - dev: true - /domutils@2.8.0: - resolution: {integrity: sha512-w96Cjofp72M5IIhpjgobBimYEfoPjx1Vx0BSX9P30WBdZW2WIKU0T1Bd0kz2eNZ9ikjKgHbEyKx8BB6H1L3h3A==} + domutils@2.8.0: dependencies: dom-serializer: 1.4.1 domelementtype: 2.3.0 domhandler: 4.3.1 - dev: true - /dot-case@3.0.4: - resolution: {integrity: sha512-Kv5nKlh6yRrdrGvxeJ2e5y2eRUpkUosIW4A2AS38zwSz27zu7ufDwQPi5Jhs3XAlGNetl3bmnGhQsMtkKJnj3w==} + dot-case@3.0.4: dependencies: no-case: 3.0.4 tslib: 2.6.2 - dev: false - /dot-prop@5.3.0: - resolution: {integrity: sha512-QM8q3zDe58hqUqjraQOmzZ1LIH9SWQJTlEKCH4kJ2oQvLZk7RbQXvtDM2XEq3fwkV9CCvvH4LA0AV+ogFsBM2Q==} - engines: {node: '>=8'} + dot-prop@5.3.0: dependencies: is-obj: 2.0.0 - dev: true - /dotenv-expand@5.1.0: - resolution: {integrity: sha512-YXQl1DSa4/PQyRfgrv6aoNjhasp/p4qs9FjJ4q4cQk+8m4r6k4ZSiEyytKG8f8W9gi8WsQtIObNmKd+tMzNTmA==} - dev: true + dotenv-expand@5.1.0: {} - /dotenv@16.0.0: - resolution: {integrity: sha512-qD9WU0MPM4SWLPJy/r2Be+2WgQj8plChsyrCNQzW/0WjvcJQiKQJ9mH3ZgB3fxbUUxgc/11ZJ0Fi5KiimWGz2Q==} - engines: {node: '>=12'} + dotenv@16.0.0: {} - /dotenv@7.0.0: - resolution: {integrity: sha512-M3NhsLbV1i6HuGzBUH8vXrtxOk+tWmzWKDMbAVSUp3Zsjm7ywFeuwrUXhmhQyRK1q5B5GGy7hcXPbj3bnfZg2g==} - engines: {node: '>=6'} - dev: true + dotenv@7.0.0: {} - /duplexer@0.1.2: - resolution: {integrity: sha512-jtD6YG370ZCIi/9GTaJKQxWTZD045+4R4hTk/x1UyoqadyJ9x9CgSi1RlVDQF8U2sxLLSnFkCaMihqljHIWgMg==} - dev: true + duplexer@0.1.2: {} - /duplexify@4.1.3: - resolution: {integrity: sha512-M3BmBhwJRZsSx38lZyhE53Csddgzl5R7xGJNk7CVddZD6CcmwMCH8J+7AprIrQKH7TonKxaCjcv27Qmf+sQ+oA==} + duplexify@4.1.3: dependencies: end-of-stream: 1.4.4 inherits: 2.0.4 readable-stream: 3.6.2 stream-shift: 1.0.3 - dev: false - /eastasianwidth@0.2.0: - resolution: {integrity: sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==} + eastasianwidth@0.2.0: {} - /ecdsa-sig-formatter@1.0.11: - resolution: {integrity: sha512-nagl3RYrbNv6kQkeJIpt6NJZy8twLB/2vtz6yN9Z4vRKHN4/QZJIEbqohALSgwKdnksuY3k5Addp5lg8sVoVcQ==} + ecdsa-sig-formatter@1.0.11: dependencies: safe-buffer: 5.2.1 - dev: false - /ee-first@1.1.1: - resolution: {integrity: sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0=} + ee-first@1.1.1: {} - /electron-to-chromium@1.4.281: - resolution: {integrity: sha512-yer0w5wCYdFoZytfmbNhwiGI/3cW06+RV7E23ln4490DVMxs7PvYpbsrSmAiBn/V6gode8wvJlST2YfWgvzWIg==} - dev: true + electron-to-chromium@1.4.281: {} - /electron-to-chromium@1.4.738: - resolution: {integrity: sha512-lwKft2CLFztD+vEIpesrOtCrko/TFnEJlHFdRhazU7Y/jx5qc4cqsocfVrBg4So4gGe9lvxnbLIoev47WMpg+A==} - dev: true + electron-to-chromium@1.4.738: {} - /emitter-listener@1.1.2: - resolution: {integrity: sha512-Bt1sBAGFHY9DKY+4/2cV6izcKJUf5T7/gkdmkxzX/qv9CcGH8xSwVRW5mtX03SWJtRTWSOpzCuWN9rBFYZepZQ==} + emitter-listener@1.1.2: dependencies: shimmer: 1.2.1 - dev: false - /emittery@0.13.1: - resolution: {integrity: sha512-DeWwawk6r5yR9jFgnDKYt4sLS0LmHJJi3ZOnb5/JdbYwj3nW+FxQnHIjhBKz8YLC7oRNPVM9NQ47I3CVx34eqQ==} - engines: {node: '>=12'} - dev: true + emittery@0.13.1: {} - /emoji-regex@10.3.0: - resolution: {integrity: sha512-QpLs9D9v9kArv4lfDEgg1X/gN5XLnf/A6l9cs8SPZLRZR3ZkY9+kwIQTxm+fsSej5UMYGE8fdoaZVIBlqG0XTw==} - dev: false + emoji-regex@10.3.0: {} - /emoji-regex@8.0.0: - resolution: {integrity: sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==} + emoji-regex@8.0.0: {} - /emoji-regex@9.2.2: - resolution: {integrity: sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==} + emoji-regex@9.2.2: {} - /encode-utf8@1.0.3: - resolution: {integrity: sha512-ucAnuBEhUK4boH2HjVYG5Q2mQyPorvv0u/ocS+zhdw0S8AlHYY+GOFhP1Gio5z4icpP2ivFSvhtFjQi8+T9ppw==} - dev: false + encode-utf8@1.0.3: {} - /encodeurl@1.0.2: - resolution: {integrity: sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k=} - engines: {node: '>= 0.8'} + encodeurl@1.0.2: {} - /end-of-stream@1.4.4: - resolution: {integrity: sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==} + end-of-stream@1.4.4: dependencies: once: 1.4.0 - /enhanced-resolve@5.16.0: - resolution: {integrity: sha512-O+QWCviPNSSLAD9Ucn8Awv+poAkqn3T1XY5/N7kR7rQO9yfSGWkYZDwpJ+iKF7B8rxaQKWngSqACpgzeapSyoA==} - engines: {node: '>=10.13.0'} + enhanced-resolve@5.16.0: dependencies: graceful-fs: 4.2.11 tapable: 2.2.1 - dev: true - /enquirer@2.3.6: - resolution: {integrity: sha512-yjNnPr315/FjS4zIsUxYguYUPP2e1NK4d7E7ZOLiyYCcbFBiTMyID+2wvm2w6+pZ/odMA7cRkjhsPbltwBOrLg==} - engines: {node: '>=8.6'} + enquirer@2.3.6: dependencies: ansi-colors: 4.1.3 - dev: true - /ent@2.2.0: - resolution: {integrity: sha512-GHrMyVZQWvTIdDtpiEXdHZnFQKzeO09apj8Cbl4pKWy4i0Oprcq17usfDt5aO63swf0JOeMWjWQE/LzgSRuWpA==} - dev: false + ent@2.2.0: {} - /entities@2.2.0: - resolution: {integrity: sha512-p92if5Nz619I0w+akJrLZH0MX0Pb5DX39XOwQTtXSdQQOaYH03S1uIQp4mhOZtAXrxq4ViO67YTiLBo2638o9A==} - dev: true + entities@2.2.0: {} - /entities@3.0.1: - resolution: {integrity: sha512-WiyBqoomrwMdFG1e0kqvASYfnlb0lp8M5o5Fw2OFq1hNZxxcNk8Ik0Xm7LxzBhuidnZB/UtBqVCgUz3kBOP51Q==} - engines: {node: '>=0.12'} - dev: true + entities@3.0.1: {} - /entities@4.4.0: - resolution: {integrity: sha512-oYp7156SP8LkeGD0GF85ad1X9Ai79WtRsZ2gxJqtBuzH+98YUV6jkHEKlZkMbcrjJjIVJNIDP/3WL9wQkoPbWA==} - engines: {node: '>=0.12'} - dev: true + entities@4.4.0: {} - /env-paths@2.2.1: - resolution: {integrity: sha512-+h1lkLKhZMTYjog1VEpJNG7NZJWcuc2DDk/qsqSTRRCOXiLjeQ1d1/udrUGhqMxUgAlwKNZ0cf2uqan5GLuS2A==} - engines: {node: '>=6'} - dev: true + env-paths@2.2.1: {} - /error-ex@1.3.2: - resolution: {integrity: sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==} + error-ex@1.3.2: dependencies: is-arrayish: 0.2.1 - dev: true - /es-abstract@1.20.4: - resolution: {integrity: sha512-0UtvRN79eMe2L+UNEF1BwRe364sj/DXhQ/k5FmivgoSdpM90b8Jc0mDzKMGo7QS0BVbOP/bTwBKNnDc9rNzaPA==} - engines: {node: '>= 0.4'} + es-abstract@1.20.4: dependencies: call-bind: 1.0.7 es-to-primitive: 1.2.1 @@ -12428,11 +18234,8 @@ packages: string.prototype.trimend: 1.0.5 string.prototype.trimstart: 1.0.5 unbox-primitive: 1.0.2 - dev: true - /es-abstract@1.23.3: - resolution: {integrity: sha512-e+HfNH61Bj1X9/jLc5v1owaLYuHdeHHSQlkhCBiTK8rBvKaULl/beGMxwrMXjpYrv4pz22BlY570vVePA2ho4A==} - engines: {node: '>= 0.4'} + es-abstract@1.23.3: dependencies: array-buffer-byte-length: 1.0.1 arraybuffer.prototype.slice: 1.0.3 @@ -12480,21 +18283,14 @@ packages: typed-array-length: 1.0.6 unbox-primitive: 1.0.2 which-typed-array: 1.1.15 - dev: true - /es-define-property@1.0.0: - resolution: {integrity: sha512-jxayLKShrEqqzJ0eumQbVhTYQM27CfT1T35+gCgDFoL82JLsXqTJ76zv6A0YLOgEnLUMvLzsDsGIrl8NFpT2gQ==} - engines: {node: '>= 0.4'} + es-define-property@1.0.0: dependencies: get-intrinsic: 1.2.4 - /es-errors@1.3.0: - resolution: {integrity: sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==} - engines: {node: '>= 0.4'} + es-errors@1.3.0: {} - /es-iterator-helpers@1.0.18: - resolution: {integrity: sha512-scxAJaewsahbqTYrGKJihhViaM6DDZDDoucfvzNbK0pOren1g/daDQ3IAhzn+1G14rBG7w+i5N+qul60++zlKA==} - engines: {node: '>= 0.4'} + es-iterator-helpers@1.0.18: dependencies: call-bind: 1.0.7 define-properties: 1.2.1 @@ -12510,50 +18306,32 @@ packages: internal-slot: 1.0.7 iterator.prototype: 1.1.2 safe-array-concat: 1.1.2 - dev: true - /es-object-atoms@1.0.0: - resolution: {integrity: sha512-MZ4iQ6JwHOBQjahnjwaC1ZtIBH+2ohjamzAO3oaHcXYup7qxjF2fixyH+Q71voWHeOkI2q/TnJao/KfXYIZWbw==} - engines: {node: '>= 0.4'} + es-object-atoms@1.0.0: dependencies: es-errors: 1.3.0 - dev: true - /es-set-tostringtag@2.0.3: - resolution: {integrity: sha512-3T8uNMC3OQTHkFUsFq8r/BwAXLHvU/9O9mE0fBc/MY5iq/8H7ncvO947LmYA6ldWw9Uh8Yhf25zu6n7nML5QWQ==} - engines: {node: '>= 0.4'} + es-set-tostringtag@2.0.3: dependencies: get-intrinsic: 1.2.4 has-tostringtag: 1.0.2 hasown: 2.0.2 - dev: true - /es-shim-unscopables@1.0.0: - resolution: {integrity: sha512-Jm6GPcCdC30eMLbZ2x8z2WuRwAws3zTBBKuusffYVUrNj/GVSUAZ+xKMaUpfNDR5IbyNA5LJbaecoUVbmUcB1w==} + es-shim-unscopables@1.0.0: dependencies: has: 1.0.3 - dev: true - /es-shim-unscopables@1.0.2: - resolution: {integrity: sha512-J3yBRXCzDu4ULnQwxyToo/OjdMx6akgVC7K6few0a7F/0wLtmKKN7I73AH5T2836UuXRqN7Qg+IIUw/+YJksRw==} + es-shim-unscopables@1.0.2: dependencies: hasown: 2.0.2 - dev: true - /es-to-primitive@1.2.1: - resolution: {integrity: sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==} - engines: {node: '>= 0.4'} + es-to-primitive@1.2.1: dependencies: is-callable: 1.2.7 is-date-object: 1.0.5 is-symbol: 1.0.4 - dev: true - /esbuild@0.20.2: - resolution: {integrity: sha512-WdOOppmUNU+IbZ0PaDiTst80zjnrOkyJNHoKupIcVyU8Lvla3Ugx94VzkQ32Ijqd7UhHJy75gNWDMUekcrSJ6g==} - engines: {node: '>=12'} - hasBin: true - requiresBuild: true + esbuild@0.20.2: optionalDependencies: '@esbuild/aix-ppc64': 0.20.2 '@esbuild/android-arm': 0.20.2 @@ -12578,37 +18356,20 @@ packages: '@esbuild/win32-arm64': 0.20.2 '@esbuild/win32-ia32': 0.20.2 '@esbuild/win32-x64': 0.20.2 - dev: true - /escalade@3.1.1: - resolution: {integrity: sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==} - engines: {node: '>=6'} + escalade@3.1.1: {} - /escape-html@1.0.3: - resolution: {integrity: sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg=} + escape-html@1.0.3: {} - /escape-string-regexp@1.0.5: - resolution: {integrity: sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==} - engines: {node: '>=0.8.0'} + escape-string-regexp@1.0.5: {} - /escape-string-regexp@2.0.0: - resolution: {integrity: sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==} - engines: {node: '>=8'} - dev: true + escape-string-regexp@2.0.0: {} - /escape-string-regexp@4.0.0: - resolution: {integrity: sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==} - engines: {node: '>=10'} - dev: true + escape-string-regexp@4.0.0: {} - /escape-string-regexp@5.0.0: - resolution: {integrity: sha512-/veY75JbMK4j1yjvuUxuVsiS/hr/4iHs9FTT6cgTexxdE0Ly/glccBAkloH/DofkjRbZU3bnoj38mOmhkZ0lHw==} - engines: {node: '>=12'} + escape-string-regexp@5.0.0: {} - /escodegen@2.0.0: - resolution: {integrity: sha512-mmHKys/C8BFUGI+MAWNcSYoORYLMdPzjrknd2Vc+bUsjN5bXcr8EhrNB+UTqfL1y3I9c4fw2ihgtMPQLBRiQxw==} - engines: {node: '>=6.0'} - hasBin: true + escodegen@2.0.0: dependencies: esprima: 4.0.1 estraverse: 5.3.0 @@ -12616,101 +18377,56 @@ packages: optionator: 0.8.3 optionalDependencies: source-map: 0.6.1 - dev: true - /escodegen@2.1.0: - resolution: {integrity: sha512-2NlIDTwUWJN0mRPQOdtQBzbUHvdGY2P1VXSyU83Q3xKxM7WHX2Ql8dKq782Q9TgQUNOLEzEYu9bzLNj1q88I5w==} - engines: {node: '>=6.0'} - hasBin: true + escodegen@2.1.0: dependencies: esprima: 4.0.1 estraverse: 5.3.0 esutils: 2.0.3 optionalDependencies: source-map: 0.6.1 - dev: true - /eslint-ast-utils@1.1.0: - resolution: {integrity: sha512-otzzTim2/1+lVrlH19EfQQJEhVJSu0zOb9ygb3iapN6UlyaDtyRq4b5U1FuW0v1lRa9Fp/GJyHkSwm6NqABgCA==} - engines: {node: '>=4'} + eslint-ast-utils@1.1.0: dependencies: lodash.get: 4.4.2 lodash.zip: 4.2.0 - dev: true - /eslint-compat-utils@0.5.0(eslint@8.57.0): - resolution: {integrity: sha512-dc6Y8tzEcSYZMHa+CMPLi/hyo1FzNeonbhJL7Ol0ccuKQkwopJcJBA9YL/xmMTLU1eKigXo9vj9nALElWYSowg==} - engines: {node: '>=12'} - peerDependencies: - eslint: '>=6.0.0' + eslint-compat-utils@0.5.0(eslint@8.57.0): dependencies: eslint: 8.57.0 semver: 7.6.0 - dev: true - /eslint-config-prettier@9.1.0(eslint@8.57.0): - resolution: {integrity: sha512-NSWl5BFQWEPi1j4TjVNItzYV7dZXZ+wP6I6ZhrBGpChQhZRUaElihE9uRRkcbRnNb76UMKDF3r+WTmNcGPKsqw==} - hasBin: true - peerDependencies: - eslint: '>=7.0.0' + eslint-config-prettier@9.1.0(eslint@8.57.0): dependencies: eslint: 8.57.0 - dev: true - /eslint-config-xo-react@0.27.0(eslint-plugin-react-hooks@4.6.0)(eslint-plugin-react@7.34.1)(eslint@8.57.0): - resolution: {integrity: sha512-wiV215xQIn71XZyyVfaOXHaFpR1B14IJttwOjMi/eqUK1s+ojJdHr7eHqTLaGUfh6FKgWha1QNwePlIXx7mBUg==} - engines: {node: '>=12'} - peerDependencies: - eslint: '>=8.6.0' - eslint-plugin-react: '>=7.29.0' - eslint-plugin-react-hooks: '>=4.3.0' + eslint-config-xo-react@0.27.0(eslint-plugin-react-hooks@4.6.0)(eslint-plugin-react@7.34.1)(eslint@8.57.0): dependencies: eslint: 8.57.0 eslint-plugin-react: 7.34.1(eslint@8.57.0) eslint-plugin-react-hooks: 4.6.0(eslint@8.57.0) - dev: true - /eslint-config-xo-typescript@4.0.0(@typescript-eslint/eslint-plugin@7.7.0)(@typescript-eslint/parser@7.7.0)(eslint@8.57.0)(typescript@5.3.3): - resolution: {integrity: sha512-pmSWzVpvzEjZHG7S/rN34cFXAoe6YbvWFBQSitEXD5CcT2SULfykYl8hcYXss37r5N3SmJYAiO6VlcfkPiDRxg==} - engines: {node: '>=18'} - peerDependencies: - '@typescript-eslint/eslint-plugin': '>=7.0.2' - '@typescript-eslint/parser': '>=7.0.2' - eslint: '>=8.56.0' - typescript: '>=5.0.0' + eslint-config-xo-typescript@4.0.0(@typescript-eslint/eslint-plugin@7.7.0)(@typescript-eslint/parser@7.7.0)(eslint@8.57.0)(typescript@5.3.3): dependencies: '@typescript-eslint/eslint-plugin': 7.7.0(@typescript-eslint/parser@7.7.0)(eslint@8.57.0)(typescript@5.3.3) '@typescript-eslint/parser': 7.7.0(eslint@8.57.0)(typescript@5.3.3) eslint: 8.57.0 typescript: 5.3.3 - dev: true - /eslint-config-xo@0.44.0(eslint@8.57.0): - resolution: {integrity: sha512-YG4gdaor0mJJi8UBeRJqDPO42MedTWYMaUyucF5bhm2pi/HS98JIxfFQmTLuyj6hGpQlAazNfyVnn7JuDn+Sew==} - engines: {node: '>=18'} - peerDependencies: - eslint: '>=8.56.0' + eslint-config-xo@0.44.0(eslint@8.57.0): dependencies: confusing-browser-globals: 1.0.11 eslint: 8.57.0 - dev: true - /eslint-import-resolver-node@0.3.9: - resolution: {integrity: sha512-WFj2isz22JahUv+B788TlO3N6zL3nNJGU8CcZbPZvVEkBPaJdCV4vy5wyghty5ROFbCRnm132v8BScu5/1BQ8g==} + eslint-import-resolver-node@0.3.9: dependencies: debug: 3.2.7(supports-color@5.5.0) is-core-module: 2.13.1 resolve: 1.22.8 transitivePeerDependencies: - supports-color - dev: true - /eslint-import-resolver-typescript@3.6.1(@typescript-eslint/parser@7.7.0)(eslint-plugin-import@2.29.1)(eslint@8.57.0): - resolution: {integrity: sha512-xgdptdoi5W3niYeuQxKmzVDTATvLYqhpwmykwsh7f6HIOStGWEIL9iqZgQDF9u9OEzrRwR8no5q2VT+bjAujTg==} - engines: {node: ^14.18.0 || >=16.0.0} - peerDependencies: - eslint: '*' - eslint-plugin-import: '*' + eslint-import-resolver-typescript@3.6.1(@typescript-eslint/parser@7.7.0)(eslint-plugin-import@2.29.1)(eslint@8.57.0): dependencies: debug: 4.3.4 enhanced-resolve: 5.16.0 @@ -12726,28 +18442,8 @@ packages: - eslint-import-resolver-node - eslint-import-resolver-webpack - supports-color - dev: true - /eslint-module-utils@2.8.1(@typescript-eslint/parser@7.7.0)(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.1)(eslint@8.57.0): - resolution: {integrity: sha512-rXDXR3h7cs7dy9RNpUlQf80nX31XWJEyGq1tRMo+6GsO5VmTe4UTwtmonAD4ZkAsrfMVDA2wlGJ3790Ys+D49Q==} - engines: {node: '>=4'} - peerDependencies: - '@typescript-eslint/parser': '*' - eslint: '*' - eslint-import-resolver-node: '*' - eslint-import-resolver-typescript: '*' - eslint-import-resolver-webpack: '*' - peerDependenciesMeta: - '@typescript-eslint/parser': - optional: true - eslint: - optional: true - eslint-import-resolver-node: - optional: true - eslint-import-resolver-typescript: - optional: true - eslint-import-resolver-webpack: - optional: true + eslint-module-utils@2.8.1(@typescript-eslint/parser@7.7.0)(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.1)(eslint@8.57.0): dependencies: '@typescript-eslint/parser': 7.7.0(eslint@8.57.0)(typescript@5.3.3) debug: 3.2.7(supports-color@5.5.0) @@ -12756,48 +18452,26 @@ packages: eslint-import-resolver-typescript: 3.6.1(@typescript-eslint/parser@7.7.0)(eslint-plugin-import@2.29.1)(eslint@8.57.0) transitivePeerDependencies: - supports-color - dev: true - /eslint-plugin-consistent-default-export-name@0.0.15: - resolution: {integrity: sha512-gqW7dnJbWMxI5H6/Pyz6Sl/vBMwOktePMI2iuuKPb4N82uvemUkfaWhsRZCKndSzpIVaCZ9wdspCVO1tm0wXJQ==} - engines: {node: '>=0.10.0'} + eslint-plugin-consistent-default-export-name@0.0.15: dependencies: lodash: 4.17.21 pkg-dir: 5.0.0 - dev: true - /eslint-plugin-es-x@7.6.0(eslint@8.57.0): - resolution: {integrity: sha512-I0AmeNgevgaTR7y2lrVCJmGYF0rjoznpDvqV/kIkZSZbZ8Rw3eu4cGlvBBULScfkSOCzqKbff5LR4CNrV7mZHA==} - engines: {node: ^14.18.0 || >=16.0.0} - peerDependencies: - eslint: '>=8' + eslint-plugin-es-x@7.6.0(eslint@8.57.0): dependencies: '@eslint-community/eslint-utils': 4.4.0(eslint@8.57.0) '@eslint-community/regexpp': 4.10.0 eslint: 8.57.0 eslint-compat-utils: 0.5.0(eslint@8.57.0) - dev: true - /eslint-plugin-eslint-comments@3.2.0(eslint@8.57.0): - resolution: {integrity: sha512-0jkOl0hfojIHHmEHgmNdqv4fmh7300NdpA9FFpF7zaoLvB/QeXOGNLIo86oAveJFrfB1p05kC8hpEMHM8DwWVQ==} - engines: {node: '>=6.5.0'} - peerDependencies: - eslint: '>=4.19.1' + eslint-plugin-eslint-comments@3.2.0(eslint@8.57.0): dependencies: escape-string-regexp: 1.0.5 eslint: 8.57.0 ignore: 5.3.1 - dev: true - /eslint-plugin-import@2.29.1(@typescript-eslint/parser@7.7.0)(eslint-import-resolver-typescript@3.6.1)(eslint@8.57.0): - resolution: {integrity: sha512-BbPC0cuExzhiMo4Ff1BTVwHpjjv28C5R+btTOGaCRC7UEz801up0JadwkeSk5Ued6TG34uaczuVuH6qyy5YUxw==} - engines: {node: '>=4'} - peerDependencies: - '@typescript-eslint/parser': '*' - eslint: ^2 || ^3 || ^4 || ^5 || ^6 || ^7.2.0 || ^8 - peerDependenciesMeta: - '@typescript-eslint/parser': - optional: true + eslint-plugin-import@2.29.1(@typescript-eslint/parser@7.7.0)(eslint-import-resolver-typescript@3.6.1)(eslint@8.57.0): dependencies: '@typescript-eslint/parser': 7.7.0(eslint@8.57.0)(typescript@5.3.3) array-includes: 3.1.8 @@ -12822,13 +18496,8 @@ packages: - eslint-import-resolver-typescript - eslint-import-resolver-webpack - supports-color - dev: true - /eslint-plugin-jsx-a11y@6.8.0(eslint@8.57.0): - resolution: {integrity: sha512-Hdh937BS3KdwwbBaKd5+PLCOmYY6U4f2h9Z2ktwtNKvIdIEu137rjYbcb9ApSbVJfWxANNuiKTD/9tOKjK9qOA==} - engines: {node: '>=4.0'} - peerDependencies: - eslint: ^3 || ^4 || ^5 || ^6 || ^7 || ^8 + eslint-plugin-jsx-a11y@6.8.0(eslint@8.57.0): dependencies: '@babel/runtime': 7.24.4 aria-query: 5.3.0 @@ -12847,13 +18516,8 @@ packages: minimatch: 3.1.2 object.entries: 1.1.8 object.fromentries: 2.0.8 - dev: true - /eslint-plugin-n@17.2.1(eslint@8.57.0): - resolution: {integrity: sha512-uW1+df2bo06kR7ix6nB614RUlvjRPrYxlaX832O6e1MCJp4V7YozEdvMgCYuvn4ltnjPu1FVYhQ2KRrmTNoJfg==} - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - peerDependencies: - eslint: '>=8.23.0' + eslint-plugin-n@17.2.1(eslint@8.57.0): dependencies: '@eslint-community/eslint-utils': 4.4.0(eslint@8.57.0) enhanced-resolve: 5.16.0 @@ -12864,62 +18528,31 @@ packages: ignore: 5.3.1 minimatch: 9.0.4 semver: 7.6.0 - dev: true - /eslint-plugin-no-use-extend-native@0.5.0: - resolution: {integrity: sha512-dBNjs8hor8rJgeXLH4HTut5eD3RGWf9JUsadIfuL7UosVQ/dnvOKwxEcRrXrFxrMZ8llUVWT+hOimxJABsAUzQ==} - engines: {node: '>=6.0.0'} + eslint-plugin-no-use-extend-native@0.5.0: dependencies: is-get-set-prop: 1.0.0 is-js-type: 2.0.0 is-obj-prop: 1.0.0 is-proto-prop: 2.0.0 - dev: true - /eslint-plugin-prettier@5.1.3(eslint-config-prettier@9.1.0)(eslint@8.57.0)(prettier@3.0.0): - resolution: {integrity: sha512-C9GCVAs4Eq7ZC/XFQHITLiHJxQngdtraXaM+LoUFoFp/lHNl2Zn8f3WQbe9HvTBBQ9YnKFB0/2Ajdqwo5D1EAw==} - engines: {node: ^14.18.0 || >=16.0.0} - peerDependencies: - '@types/eslint': '>=8.0.0' - eslint: '>=8.0.0' - eslint-config-prettier: '*' - prettier: '>=3.0.0' - peerDependenciesMeta: - '@types/eslint': - optional: true - eslint-config-prettier: - optional: true + eslint-plugin-prettier@5.1.3(eslint-config-prettier@9.1.0)(eslint@8.57.0)(prettier@3.0.0): dependencies: eslint: 8.57.0 eslint-config-prettier: 9.1.0(eslint@8.57.0) prettier: 3.0.0 prettier-linter-helpers: 1.0.0 synckit: 0.8.8 - dev: true - /eslint-plugin-promise@6.1.1(eslint@8.57.0): - resolution: {integrity: sha512-tjqWDwVZQo7UIPMeDReOpUgHCmCiH+ePnVT+5zVapL0uuHnegBUs2smM13CzOs2Xb5+MHMRFTs9v24yjba4Oig==} - engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} - peerDependencies: - eslint: ^7.0.0 || ^8.0.0 + eslint-plugin-promise@6.1.1(eslint@8.57.0): dependencies: eslint: 8.57.0 - dev: true - /eslint-plugin-react-hooks@4.6.0(eslint@8.57.0): - resolution: {integrity: sha512-oFc7Itz9Qxh2x4gNHStv3BqJq54ExXmfC+a1NjAta66IAN87Wu0R/QArgIS9qKzX3dXKPI9H5crl9QchNMY9+g==} - engines: {node: '>=10'} - peerDependencies: - eslint: ^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0-0 + eslint-plugin-react-hooks@4.6.0(eslint@8.57.0): dependencies: eslint: 8.57.0 - dev: true - /eslint-plugin-react@7.34.1(eslint@8.57.0): - resolution: {integrity: sha512-N97CxlouPT1AHt8Jn0mhhN2RrADlUAsk1/atcT2KyA/l9Q/E6ll7OIGwNumFmWfZ9skV3XXccYS19h80rHtgkw==} - engines: {node: '>=4'} - peerDependencies: - eslint: ^3 || ^4 || ^5 || ^6 || ^7 || ^8 + eslint-plugin-react@7.34.1(eslint@8.57.0): dependencies: array-includes: 3.1.8 array.prototype.findlast: 1.2.5 @@ -12940,13 +18573,8 @@ packages: resolve: 2.0.0-next.5 semver: 6.3.1 string.prototype.matchall: 4.0.11 - dev: true - /eslint-plugin-sql@2.1.0(eslint@8.57.0): - resolution: {integrity: sha512-UPapPPhK1ADgQDTogpApiSAh6bYjrt2daYkKCdApHm5KPbq9qR4ca4TPyYod06bAnLgswbri6Z9gEPAy0R+B1A==} - engines: {node: '>=12'} - peerDependencies: - eslint: '>=8.1.0' + eslint-plugin-sql@2.1.0(eslint@8.57.0): dependencies: astring: 1.8.3 debug: 4.3.4 @@ -12956,13 +18584,8 @@ packages: sql-parse: 0.1.5 transitivePeerDependencies: - supports-color - dev: true - /eslint-plugin-unicorn@52.0.0(eslint@8.57.0): - resolution: {integrity: sha512-1Yzm7/m+0R4djH0tjDjfVei/ju2w3AzUGjG6q8JnuNIL5xIwsflyCooW5sfBvQp2pMYQFSWWCFONsjCax1EHng==} - engines: {node: '>=16'} - peerDependencies: - eslint: '>=8.56.0' + eslint-plugin-unicorn@52.0.0(eslint@8.57.0): dependencies: '@babel/helper-validator-identifier': 7.22.20 '@eslint-community/eslint-utils': 4.4.0(eslint@8.57.0) @@ -12983,50 +18606,25 @@ packages: strip-indent: 3.0.0 transitivePeerDependencies: - supports-color - dev: true - /eslint-plugin-unused-imports@3.1.0(@typescript-eslint/eslint-plugin@7.7.0)(eslint@8.57.0): - resolution: {integrity: sha512-9l1YFCzXKkw1qtAru1RWUtG2EVDZY0a0eChKXcL+EZ5jitG7qxdctu4RnvhOJHv4xfmUf7h+JJPINlVpGhZMrw==} - engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} - peerDependencies: - '@typescript-eslint/eslint-plugin': 6 - 7 - eslint: '8' - peerDependenciesMeta: - '@typescript-eslint/eslint-plugin': - optional: true + eslint-plugin-unused-imports@3.1.0(@typescript-eslint/eslint-plugin@7.7.0)(eslint@8.57.0): dependencies: '@typescript-eslint/eslint-plugin': 7.7.0(@typescript-eslint/parser@7.7.0)(eslint@8.57.0)(typescript@5.3.3) eslint: 8.57.0 eslint-rule-composer: 0.3.0 - dev: true - /eslint-rule-composer@0.3.0: - resolution: {integrity: sha512-bt+Sh8CtDmn2OajxvNO+BX7Wn4CIWMpTRm3MaiKPCQcnnlm0CS2mhui6QaoeQugs+3Kj2ESKEEGJUdVafwhiCg==} - engines: {node: '>=4.0.0'} - dev: true + eslint-rule-composer@0.3.0: {} - /eslint-scope@7.2.2: - resolution: {integrity: sha512-dOt21O7lTMhDM+X9mB4GX+DZrZtCUJPL/wlcTqxyrx5IvO0IYtILdtrQGQp+8n5S0gwSVmOf9NQrjMOgfQZlIg==} - engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + eslint-scope@7.2.2: dependencies: esrecurse: 4.3.0 estraverse: 5.3.0 - dev: true - /eslint-visitor-keys@3.4.1: - resolution: {integrity: sha512-pZnmmLwYzf+kWaM/Qgrvpen51upAktaaiI01nsJD/Yr3lMOdNtq0cxkrrg16w64VtisN6okbs7Q8AfGqj4c9fA==} - engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} - dev: true + eslint-visitor-keys@3.4.1: {} - /eslint-visitor-keys@3.4.3: - resolution: {integrity: sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==} - engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} - dev: true + eslint-visitor-keys@3.4.3: {} - /eslint@8.57.0: - resolution: {integrity: sha512-dZ6+mexnaTIbSBZWgou51U6OmzIhYM2VcNdtiTtI7qPNZm35Akpr0f6vtw3w1Kmn5PYo+tZVfh13WrhpS6oLqQ==} - engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} - hasBin: true + eslint@8.57.0: dependencies: '@eslint-community/eslint-utils': 4.4.0(eslint@8.57.0) '@eslint-community/regexpp': 4.10.0 @@ -13068,95 +18666,52 @@ packages: text-table: 0.2.0 transitivePeerDependencies: - supports-color - dev: true - /espree@9.6.0: - resolution: {integrity: sha512-1FH/IiruXZ84tpUlm0aCUEwMl2Ho5ilqVh0VvQXw+byAz/4SAciyHLlfmL5WYqsvD38oymdUwBss0LtK8m4s/A==} - engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + espree@9.6.0: dependencies: acorn: 8.10.0 acorn-jsx: 5.3.2(acorn@8.10.0) eslint-visitor-keys: 3.4.1 - dev: true - /espree@9.6.1: - resolution: {integrity: sha512-oruZaFkjorTpF32kDSI5/75ViwGeZginGGy2NoOSg3Q9bnwlnmDm4HLnkl0RE3n+njDXR037aY1+x58Z/zFdwQ==} - engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + espree@9.6.1: dependencies: acorn: 8.11.3 acorn-jsx: 5.3.2(acorn@8.11.3) eslint-visitor-keys: 3.4.3 - dev: true - /esprima@4.0.1: - resolution: {integrity: sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==} - engines: {node: '>=4'} - hasBin: true - dev: true + esprima@4.0.1: {} - /esquery@1.5.0: - resolution: {integrity: sha512-YQLXUplAwJgCydQ78IMJywZCceoqk1oH01OERdSAJc/7U2AylwjhSCLDEtqwg811idIS/9fIU5GjG73IgjKMVg==} - engines: {node: '>=0.10'} + esquery@1.5.0: dependencies: estraverse: 5.3.0 - dev: true - /esrecurse@4.3.0: - resolution: {integrity: sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==} - engines: {node: '>=4.0'} + esrecurse@4.3.0: dependencies: estraverse: 5.3.0 - dev: true - /estraverse@5.3.0: - resolution: {integrity: sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==} - engines: {node: '>=4.0'} - dev: true + estraverse@5.3.0: {} - /estree-walker@2.0.2: - resolution: {integrity: sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==} - dev: true + estree-walker@2.0.2: {} - /estree-walker@3.0.3: - resolution: {integrity: sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g==} + estree-walker@3.0.3: dependencies: '@types/estree': 1.0.5 - dev: true - /esutils@2.0.3: - resolution: {integrity: sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==} - engines: {node: '>=0.10.0'} - dev: true + esutils@2.0.3: {} - /eta@3.4.0: - resolution: {integrity: sha512-tCsc7WXTjrTx4ZjYLplcqrI3o4mYJ+Z6YspeuGL8tbt/hHoMchwBwtKfwM09svEY86iRapY93vUqQttcNuIO5Q==} - engines: {node: '>=6.0.0'} - dev: false + eta@3.4.0: {} - /etag@1.8.1: - resolution: {integrity: sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==} - engines: {node: '>= 0.6'} - dev: false + etag@1.8.1: {} - /event-target-shim@5.0.1: - resolution: {integrity: sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ==} - engines: {node: '>=6'} - dev: false + event-target-shim@5.0.1: {} - /eventemitter3@4.0.7: - resolution: {integrity: sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw==} + eventemitter3@4.0.7: {} - /eventemitter3@5.0.1: - resolution: {integrity: sha512-GWkBvjiSZK87ELrYOSESUYeVIc9mvLLf/nXalMOS5dYrgZq9o5OVkbZAVM06CVxYsCwH9BDZFPlQTlPA1j4ahA==} + eventemitter3@5.0.1: {} - /events@3.3.0: - resolution: {integrity: sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==} - engines: {node: '>=0.8.x'} - dev: false + events@3.3.0: {} - /execa@5.1.1: - resolution: {integrity: sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==} - engines: {node: '>=10'} + execa@5.1.1: dependencies: cross-spawn: 7.0.3 get-stream: 6.0.1 @@ -13167,11 +18722,8 @@ packages: onetime: 5.1.2 signal-exit: 3.0.7 strip-final-newline: 2.0.0 - dev: true - /execa@8.0.1: - resolution: {integrity: sha512-VyhnebXciFV2DESc+p6B+y0LjSm0krU4OgJN44qFAhBY0TJ+1V61tYD2+wHusZ6F9n5K+vl8k0sTy7PEfV4qpg==} - engines: {node: '>=16.17'} + execa@8.0.1: dependencies: cross-spawn: 7.0.3 get-stream: 8.0.1 @@ -13182,59 +18734,36 @@ packages: onetime: 6.0.0 signal-exit: 4.1.0 strip-final-newline: 3.0.0 - dev: true - /exenv@1.2.2: - resolution: {integrity: sha512-Z+ktTxTwv9ILfgKCk32OX3n/doe+OcLTRtqK9pcL+JsP3J1/VW8Uvl4ZjLlKqeW4rzK4oesDOGMEMRIZqtP4Iw==} - dev: true + exenv@1.2.2: {} - /exit@0.1.2: - resolution: {integrity: sha512-Zk/eNKV2zbjpKzrsQ+n1G6poVbErQxJ0LBOJXaKZ1EViLzH+hrLu9cdXI4zw9dBQJslwBEpbQ2P1oS7nDxs6jQ==} - engines: {node: '>= 0.8.0'} - dev: true + exit@0.1.2: {} - /expand-tilde@1.2.2: - resolution: {integrity: sha512-rtmc+cjLZqnu9dSYosX9EWmSJhTwpACgJQTfj4hgg2JjOD/6SIQalZrt4a3aQeh++oNxkazcaxrhPUj6+g5G/Q==} - engines: {node: '>=0.10.0'} + expand-tilde@1.2.2: dependencies: os-homedir: 1.0.2 - dev: true - /expect-puppeteer@10.0.0: - resolution: {integrity: sha512-E7sE6nVdEbrnpDOBMmcLgyqLJKt876AlBg1A+gsu5R8cWx+SLafreOgJAgzXg5Qko7Tk0cW5oZdRbHQLU738dg==} - engines: {node: '>=16'} - dev: true + expect-puppeteer@10.0.0: {} - /expect@29.7.0: - resolution: {integrity: sha512-2Zks0hf1VLFYI1kbh0I5jP3KHHyCHpkfyHBzsSXRFgl/Bg9mWYfMW8oD+PdMPlEwy5HNsR9JutYy6pMeOh61nw==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + expect@29.7.0: dependencies: '@jest/expect-utils': 29.7.0 jest-get-type: 29.6.3 jest-matcher-utils: 29.7.0 jest-message-util: 29.7.0 jest-util: 29.7.0 - dev: true - /extend@3.0.2: - resolution: {integrity: sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==} + extend@3.0.2: {} - /extendable-error@0.1.7: - resolution: {integrity: sha512-UOiS2in6/Q0FK0R0q6UY9vYpQ21mr/Qn1KOnte7vsACuNJf514WvCCUHSRCPcgjPT2bAhNIJdlE6bVap1GKmeg==} - dev: true + extendable-error@0.1.7: {} - /external-editor@3.1.0: - resolution: {integrity: sha512-hMQ4CX1p1izmuLYyZqLMO/qGNw10wSv9QDCPfzXfyFrOaCSSoRfqE1Kf1s5an66J5JZC62NewG+mK49jOCtQew==} - engines: {node: '>=4'} + external-editor@3.1.0: dependencies: chardet: 0.7.0 iconv-lite: 0.4.24 tmp: 0.0.33 - /extract-zip@2.0.1: - resolution: {integrity: sha512-GDhU9ntwuKyGXdZBUgTIe+vXnWj0fppUEtMDL0+idd5Sta8TGpHssn/eusA9mrPr9qNDym6SxAYZjNvCn/9RBg==} - engines: {node: '>= 10.17.0'} - hasBin: true + extract-zip@2.0.1: dependencies: debug: 4.3.4 get-stream: 5.2.0 @@ -13243,368 +18772,225 @@ packages: '@types/yauzl': 2.10.3 transitivePeerDependencies: - supports-color - dev: true - /fast-deep-equal@3.1.3: - resolution: {integrity: sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==} + fast-deep-equal@3.1.3: {} - /fast-diff@1.2.0: - resolution: {integrity: sha512-xJuoT5+L99XlZ8twedaRf6Ax2TgQVxvgZOYoPKqZufmJib0tL2tegPBOZb1pVNgIhlqDlA0eO0c3wBvQcmzx4w==} - dev: true + fast-diff@1.2.0: {} - /fast-equals@2.0.4: - resolution: {integrity: sha512-caj/ZmjHljPrZtbzJ3kfH5ia/k4mTJe/qSiXAGzxZWRZgsgDV0cvNaQULqUX8t0/JVlzzEdYOwCN5DmzTxoD4w==} - dev: true + fast-equals@2.0.4: {} - /fast-fifo@1.3.2: - resolution: {integrity: sha512-/d9sfos4yxzpwkDkuN7k2SqFKtYNmCTzgfEpz82x34IM9/zc8KGxQoXg1liNC/izpRM/MBdt44Nmx41ZWqk+FQ==} - dev: true + fast-fifo@1.3.2: {} - /fast-glob@3.3.2: - resolution: {integrity: sha512-oX2ruAFQwf/Orj8m737Y5adxDQO0LAB7/S5MnxCdTNDd4p6BsyIVsv9JQsATbTSq8KHRpLwIHbVlUNatxd+1Ow==} - engines: {node: '>=8.6.0'} + fast-glob@3.3.2: dependencies: '@nodelib/fs.stat': 2.0.5 '@nodelib/fs.walk': 1.2.8 glob-parent: 5.1.2 merge2: 1.4.1 micromatch: 4.0.5 - dev: true - /fast-json-stable-stringify@2.1.0: - resolution: {integrity: sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==} + fast-json-stable-stringify@2.1.0: {} - /fast-json-stringify@2.7.12: - resolution: {integrity: sha512-4hjwZDPmgj/ZUKXhEWovGPciE/5mWtAIQQxN+2VBDFun7DRTk2oOItbu9ZZp6kqj+eZ/u7z+dgBgM74cfGRnBQ==} - engines: {node: '>= 10.0.0'} + fast-json-stringify@2.7.12: dependencies: ajv: 6.12.6 deepmerge: 4.3.1 rfdc: 1.3.0 string-similarity: 4.0.4 - /fast-levenshtein@2.0.6: - resolution: {integrity: sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==} - dev: true + fast-levenshtein@2.0.6: {} - /fast-printf@1.6.9: - resolution: {integrity: sha512-FChq8hbz65WMj4rstcQsFB0O7Cy++nmbNfLYnD9cYv2cRn8EG6k/MGn9kO/tjO66t09DLDugj3yL+V2o6Qftrg==} - engines: {node: '>=10.0'} + fast-printf@1.6.9: dependencies: boolean: 3.1.4 - /fast-safe-stringify@2.1.1: - resolution: {integrity: sha512-W+KJc2dmILlPplD/H4K9l9LcAHAfPtP6BY84uVLXQ6Evcz9Lcg33Y2z1IVblT6xdY54PXYVHEv+0Wpq8Io6zkA==} + fast-safe-stringify@2.1.1: {} - /fast-xml-parser@4.2.5: - resolution: {integrity: sha512-B9/wizE4WngqQftFPmdaMYlXoJlJOYxGQOanC77fq9k8+Z0v5dDSVh+3glErdIROP//s/jgb7ZuxKfB8nVyo0g==} - hasBin: true + fast-xml-parser@4.2.5: dependencies: strnum: 1.0.5 - dev: false - /fast-xml-parser@4.3.6: - resolution: {integrity: sha512-M2SovcRxD4+vC493Uc2GZVcZaj66CCJhWurC4viynVSTvrpErCShNcDz1lAho6n9REQKvL/ll4A4/fw6Y9z8nw==} - hasBin: true + fast-xml-parser@4.3.6: dependencies: strnum: 1.0.5 - dev: false - /fastest-levenshtein@1.0.16: - resolution: {integrity: sha512-eRnCtTTtGZFpQCwhJiUOuxPQWRXVKYDn0b2PeHfXL6/Zi53SLAzAHfVhVWK2AryC/WH05kGfxhFIPvTF0SXQzg==} - engines: {node: '>= 4.9.1'} - dev: true + fastest-levenshtein@1.0.16: {} - /fastq@1.13.0: - resolution: {integrity: sha512-YpkpUnK8od0o1hmeSc7UUs/eB/vIPWJYjKck2QKIzAf71Vm1AAQ3EbuZB3g2JIy+pg+ERD0vqI79KyZiB2e2Nw==} + fastq@1.13.0: dependencies: reusify: 1.0.4 - dev: true - /fault@1.0.4: - resolution: {integrity: sha512-CJ0HCB5tL5fYTEA7ToAq5+kTwd++Borf1/bifxd9iT70QcXr4MRrO3Llf8Ifs70q+SJcGHFtnIE/Nw6giCtECA==} + fault@1.0.4: dependencies: format: 0.2.2 - dev: true - /fb-watchman@2.0.2: - resolution: {integrity: sha512-p5161BqbuCaSnB8jIbzQHOlpgsPmK5rJVDfDKO91Axs5NC1uu3HRQm6wt9cd9/+GtQQIO53JdGXXoyDpTAsgYA==} + fb-watchman@2.0.2: dependencies: bser: 2.1.1 - dev: true - /fd-slicer@1.1.0: - resolution: {integrity: sha512-cE1qsB/VwyQozZ+q1dGxR8LBYNZeofhEdUNGSMbQD3Gw2lAzX9Zb3uIU6Ebc/Fmyjo9AWWfnn0AUCHqtevs/8g==} + fd-slicer@1.1.0: dependencies: pend: 1.2.0 - dev: true - /figures@5.0.0: - resolution: {integrity: sha512-ej8ksPF4x6e5wvK9yevct0UCXh8TTFlWGVLlgjZuoBH1HwjIfKE/IdL5mq89sFA7zELi1VhKpmtDnrs7zWyeyg==} - engines: {node: '>=14'} + figures@5.0.0: dependencies: escape-string-regexp: 5.0.0 is-unicode-supported: 1.3.0 - dev: false - /file-entry-cache@6.0.1: - resolution: {integrity: sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==} - engines: {node: ^10.12.0 || >=12.0.0} + file-entry-cache@6.0.1: dependencies: flat-cache: 3.0.4 - dev: true - /file-entry-cache@7.0.2: - resolution: {integrity: sha512-TfW7/1iI4Cy7Y8L6iqNdZQVvdXn0f8B4QcIXmkIbtTIe/Okm/nSlHb4IwGzRVOd3WfSieCgvf5cMzEfySAIl0g==} - engines: {node: '>=12.0.0'} + file-entry-cache@7.0.2: dependencies: flat-cache: 3.2.0 - dev: true - /file-selector@0.6.0: - resolution: {integrity: sha512-QlZ5yJC0VxHxQQsQhXvBaC7VRJ2uaxTf+Tfpu4Z/OcVQJVpZO+DGU0rkoVW5ce2SccxugvpBJoMvUs59iILYdw==} - engines: {node: '>= 12'} + file-selector@0.6.0: dependencies: tslib: 2.5.0 - dev: true - /fill-range@7.0.1: - resolution: {integrity: sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==} - engines: {node: '>=8'} + fill-range@7.0.1: dependencies: to-regex-range: 5.0.1 - dev: true - /filter-obj@5.1.0: - resolution: {integrity: sha512-qWeTREPoT7I0bifpPUXtxkZJ1XJzxWtfoWWkdVGqa+eCr3SHW/Ocp89o8vLvbUuQnadybJpjOKu4V+RwO6sGng==} - engines: {node: '>=14.16'} - dev: false + filter-obj@5.1.0: {} - /find-file-up@0.1.3: - resolution: {integrity: sha512-mBxmNbVyjg1LQIIpgO8hN+ybWBgDQK8qjht+EbrTCGmmPV/sc7RF1i9stPTD6bpvXZywBdrwRYxhSdJv867L6A==} - engines: {node: '>=0.10.0'} + find-file-up@0.1.3: dependencies: fs-exists-sync: 0.1.0 resolve-dir: 0.1.1 - dev: true - /find-pkg@0.1.2: - resolution: {integrity: sha512-0rnQWcFwZr7eO0513HahrWafsc3CTFioEB7DRiEYCUM/70QXSY8f3mCST17HXLcPvEhzH/Ty/Bxd72ZZsr/yvw==} - engines: {node: '>=0.10.0'} + find-pkg@0.1.2: dependencies: find-file-up: 0.1.3 - dev: true - /find-process@1.4.7: - resolution: {integrity: sha512-/U4CYp1214Xrp3u3Fqr9yNynUrr5Le4y0SsJh2lMDDSbpwYSz3M2SMWQC+wqcx79cN8PQtHQIL8KnuY9M66fdg==} - hasBin: true + find-process@1.4.7: dependencies: chalk: 4.1.2 commander: 5.1.0 debug: 4.3.4 transitivePeerDependencies: - supports-color - dev: true - /find-up@4.1.0: - resolution: {integrity: sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==} - engines: {node: '>=8'} + find-up@4.1.0: dependencies: locate-path: 5.0.0 path-exists: 4.0.0 - /find-up@5.0.0: - resolution: {integrity: sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==} - engines: {node: '>=10'} + find-up@5.0.0: dependencies: locate-path: 6.0.0 path-exists: 4.0.0 - dev: true - /find-up@7.0.0: - resolution: {integrity: sha512-YyZM99iHrqLKjmt4LJDj58KI+fYyufRLBSYcqycxf//KpBk9FoewoGX0450m9nB44qrZnovzC2oeP5hUibxc/g==} - engines: {node: '>=18'} + find-up@7.0.0: dependencies: locate-path: 7.2.0 path-exists: 5.0.0 unicorn-magic: 0.1.0 - /find-yarn-workspace-root2@1.2.16: - resolution: {integrity: sha512-hr6hb1w8ePMpPVUK39S4RlwJzi+xPLuVuG8XlwXU3KD5Yn3qgBWVfy3AzNlDhWvE1EORCE65/Qm26rFQt3VLVA==} + find-yarn-workspace-root2@1.2.16: dependencies: micromatch: 4.0.5 pkg-dir: 4.2.0 - dev: true - /flat-cache@3.0.4: - resolution: {integrity: sha512-dm9s5Pw7Jc0GvMYbshN6zchCA9RgQlzzEZX3vylR9IqFfS8XciblUXOKfW6SiuJ0e13eDYZoZV5wdrev7P3Nwg==} - engines: {node: ^10.12.0 || >=12.0.0} + flat-cache@3.0.4: dependencies: flatted: 3.2.7 rimraf: 3.0.2 - dev: true - /flat-cache@3.2.0: - resolution: {integrity: sha512-CYcENa+FtcUKLmhhqyctpclsq7QF38pKjZHsGNiSQF5r4FtoKDWabFDl3hzaEQMvT1LHEysw5twgLvpYYb4vbw==} - engines: {node: ^10.12.0 || >=12.0.0} + flat-cache@3.2.0: dependencies: flatted: 3.3.1 keyv: 4.5.4 rimraf: 3.0.2 - dev: true - /flatted@3.2.7: - resolution: {integrity: sha512-5nqDSxl8nn5BSNxyR3n4I6eDmbolI6WT+QqR547RwxQapgjQBmtktdP+HTBb/a/zLsbzERTONyUB5pefh5TtjQ==} - dev: true + flatted@3.2.7: {} - /flatted@3.3.1: - resolution: {integrity: sha512-X8cqMLLie7KsNUDSdzeN8FYK9rEt4Dt67OsG/DNGnYTSDBG4uFAJFBnUeiV+zCVAvwFy56IjM9sH51jVaEhNxw==} - dev: true + flatted@3.3.1: {} - /follow-redirects@1.15.6: - resolution: {integrity: sha512-wWN62YITEaOpSK584EZXJafH1AGpO8RVgElfkuXbTOrPX4fIfOyEpW/CsiNd8JdYrAoOvafRTOEnvsO++qCqFA==} - engines: {node: '>=4.0'} - peerDependencies: - debug: '*' - peerDependenciesMeta: - debug: - optional: true + follow-redirects@1.15.6: {} - /for-each@0.3.3: - resolution: {integrity: sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw==} + for-each@0.3.3: dependencies: is-callable: 1.2.7 - dev: true - /foreground-child@3.1.1: - resolution: {integrity: sha512-TMKDUnIte6bfb5nWv7V/caI169OHgvwjb7V4WkeUvbQQdjr5rWKqHFiKWb/fcOwB+CzBT+qbWjvj+DVwRskpIg==} - engines: {node: '>=14'} + foreground-child@3.1.1: dependencies: cross-spawn: 7.0.3 signal-exit: 4.1.0 - dev: false - /form-data-encoder@2.1.4: - resolution: {integrity: sha512-yDYSgNMraqvnxiEXO4hi88+YZxaHC6QKzb5N84iRCTDeRO7ZALpir/lVmf/uXUhnwUr2O4HU8s/n6x+yNjQkHw==} - engines: {node: '>= 14.17'} - dev: false + form-data-encoder@2.1.4: {} - /form-data-encoder@4.0.2: - resolution: {integrity: sha512-KQVhvhK8ZkWzxKxOr56CPulAhH3dobtuQ4+hNQ+HekH/Wp5gSOafqRAeTphQUJAIk0GBvHZgJ2ZGRWd5kphMuw==} - engines: {node: '>= 18'} - dev: false + form-data-encoder@4.0.2: {} - /form-data@2.5.1: - resolution: {integrity: sha512-m21N3WOmEEURgk6B9GLOE4RuWOFf28Lhh9qGYeNlGq4VDXUlJy2th2slBNU8Gp8EzloYZOibZJ7t5ecIrFSjVA==} - engines: {node: '>= 0.12'} + form-data@2.5.1: dependencies: asynckit: 0.4.0 combined-stream: 1.0.8 mime-types: 2.1.35 - dev: false - /form-data@3.0.1: - resolution: {integrity: sha512-RHkBKtLWUVwd7SqRIvCZMEvAMoGUp0XU+seQiZejj0COz3RI3hWP4sCv3gZWWLjJTd7rGwcsF5eKZGii0r/hbg==} - engines: {node: '>= 6'} + form-data@3.0.1: dependencies: asynckit: 0.4.0 combined-stream: 1.0.8 mime-types: 2.1.35 - dev: false - /form-data@4.0.0: - resolution: {integrity: sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==} - engines: {node: '>= 6'} + form-data@4.0.0: dependencies: asynckit: 0.4.0 combined-stream: 1.0.8 mime-types: 2.1.35 - /format@0.2.2: - resolution: {integrity: sha1-1hcBB+nv3E7TDJ3DkBbflCtctYs=} - engines: {node: '>=0.4.x'} - dev: true + format@0.2.2: {} - /formidable@3.5.1: - resolution: {integrity: sha512-WJWKelbRHN41m5dumb0/k8TeAx7Id/y3a+Z7QfhxP/htI9Js5zYaEDtG8uMgG0vM0lOlqnmjE99/kfpOYi/0Og==} + formidable@3.5.1: dependencies: dezalgo: 1.0.4 hexoid: 1.0.0 once: 1.4.0 - /fresh@0.5.2: - resolution: {integrity: sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac=} - engines: {node: '>= 0.6'} - - /fs-exists-sync@0.1.0: - resolution: {integrity: sha512-cR/vflFyPZtrN6b38ZyWxpWdhlXrzZEBawlpBQMq7033xVY7/kg0GDMBK5jg8lDYQckdJ5x/YC88lM3C7VMsLg==} - engines: {node: '>=0.10.0'} - dev: true + fresh@0.5.2: {} - /fs-extra@7.0.1: - resolution: {integrity: sha512-YJDaCJZEnBmcbw13fvdAM9AwNOJwOzrE4pqMqBq5nFiEqXUqHwlK4B+3pUw6JNvfSPtX05xFHtYy/1ni01eGCw==} - engines: {node: '>=6 <7 || >=8'} + fs-exists-sync@0.1.0: {} + + fs-extra@7.0.1: dependencies: graceful-fs: 4.2.11 jsonfile: 4.0.0 universalify: 0.1.2 - dev: true - /fs-extra@8.1.0: - resolution: {integrity: sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==} - engines: {node: '>=6 <7 || >=8'} + fs-extra@8.1.0: dependencies: graceful-fs: 4.2.11 jsonfile: 4.0.0 universalify: 0.1.2 - dev: true - /fs.realpath@1.0.0: - resolution: {integrity: sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==} - dev: true + fs.realpath@1.0.0: {} - /fsevents@2.3.3: - resolution: {integrity: sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==} - engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0} - os: [darwin] - requiresBuild: true - dev: true + fsevents@2.3.3: optional: true - /function-bind@1.1.1: - resolution: {integrity: sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==} - dev: true + function-bind@1.1.1: {} - /function-bind@1.1.2: - resolution: {integrity: sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==} + function-bind@1.1.2: {} - /function.prototype.name@1.1.5: - resolution: {integrity: sha512-uN7m/BzVKQnCUF/iW8jYea67v++2u7m5UgENbHRtdDVclOUP+FMPlCNdmk0h/ysGyo2tavMJEDqJAkJdRa1vMA==} - engines: {node: '>= 0.4'} + function.prototype.name@1.1.5: dependencies: call-bind: 1.0.7 define-properties: 1.1.4 es-abstract: 1.20.4 functions-have-names: 1.2.3 - dev: true - /function.prototype.name@1.1.6: - resolution: {integrity: sha512-Z5kx79swU5P27WEayXM1tBi5Ze/lbIyiNgU3qyXUOf9b2rgXYyF9Dy9Cx+IQv/Lc8WCG6L82zwUPpSS9hGehIg==} - engines: {node: '>= 0.4'} + function.prototype.name@1.1.6: dependencies: call-bind: 1.0.7 define-properties: 1.2.1 es-abstract: 1.23.3 functions-have-names: 1.2.3 - dev: true - /functions-have-names@1.2.3: - resolution: {integrity: sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ==} - dev: true + functions-have-names@1.2.3: {} - /gaxios@6.1.1: - resolution: {integrity: sha512-bw8smrX+XlAoo9o1JAksBwX+hi/RG15J+NTSxmNPIclKC3ZVK6C2afwY8OSdRvOK0+ZLecUJYtj2MmjOt3Dm0w==} - engines: {node: '>=14'} + gaxios@6.1.1: dependencies: extend: 3.0.2 https-proxy-agent: 7.0.4 @@ -13613,51 +18999,30 @@ packages: transitivePeerDependencies: - encoding - supports-color - dev: false - /gcp-metadata@6.1.0: - resolution: {integrity: sha512-Jh/AIwwgaxan+7ZUUmRLCjtchyDiqh4KjBJ5tW3plBZb5iL/BPcso8A5DlzeD9qlw0duCamnNdpFjxwaT0KyKg==} - engines: {node: '>=14'} + gcp-metadata@6.1.0: dependencies: gaxios: 6.1.1 json-bigint: 1.0.0 transitivePeerDependencies: - encoding - supports-color - dev: false - /generic-names@4.0.0: - resolution: {integrity: sha512-ySFolZQfw9FoDb3ed9d80Cm9f0+r7qj+HJkWjeD9RBfpxEVTlVhol+gvaQB/78WbwYfbnNh8nWHHBSlg072y6A==} + generic-names@4.0.0: dependencies: loader-utils: 3.2.0 - dev: true - /generic-pool@3.9.0: - resolution: {integrity: sha512-hymDOu5B53XvN4QT9dBmZxPX4CWhBPPLguTZ9MMFeFa/Kg0xWVfylOVNlJji/E7yTZWFd/q9GO5TxDLq156D7g==} - engines: {node: '>= 4'} - dev: false + generic-pool@3.9.0: {} - /gensync@1.0.0-beta.2: - resolution: {integrity: sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==} - engines: {node: '>=6.9.0'} - dev: true + gensync@1.0.0-beta.2: {} - /get-caller-file@2.0.5: - resolution: {integrity: sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==} - engines: {node: 6.* || 8.* || >= 10.*} + get-caller-file@2.0.5: {} - /get-east-asian-width@1.2.0: - resolution: {integrity: sha512-2nk+7SIVb14QrgXFHcm84tD4bKQz0RxPuMT8Ag5KPOq7J5fEmAg0UbXdTOSHqNuHSU28k55qnceesxXRZGzKWA==} - engines: {node: '>=18'} - dev: false + get-east-asian-width@1.2.0: {} - /get-func-name@2.0.2: - resolution: {integrity: sha512-8vXOvuE167CtIc3OyItco7N/dpRtBbYOsPsXCz7X/PMnlGjYjSGuZJgM1Y7mmew7BKf9BqvLX2tnOVy1BBUsxQ==} - dev: true + get-func-name@2.0.2: {} - /get-intrinsic@1.2.4: - resolution: {integrity: sha512-5uYhsJH8VJBTv7oslg4BznJYhDoRI6waYCxMmCdnTrcCrHA/fCFKoTFz2JKKE0HdDFUF7/oQuhzumXJK7paBRQ==} - engines: {node: '>= 0.4'} + get-intrinsic@1.2.4: dependencies: es-errors: 1.3.0 function-bind: 1.1.2 @@ -13665,69 +19030,41 @@ packages: has-symbols: 1.0.3 hasown: 2.0.2 - /get-package-type@0.1.0: - resolution: {integrity: sha512-pjzuKtY64GYfWizNAJ0fr9VqttZkNiK2iS430LtIHzjBEr6bX8Am2zm4sW4Ro5wjWW5cAlRL1qAMTcXbjNAO2Q==} - engines: {node: '>=8.0.0'} - dev: true + get-package-type@0.1.0: {} - /get-port@4.2.0: - resolution: {integrity: sha512-/b3jarXkH8KJoOMQc3uVGHASwGLPq3gSFJ7tgJm2diza+bydJPTGOibin2steecKeOylE8oY2JERlVWkAJO6yw==} - engines: {node: '>=6'} - dev: true + get-port@4.2.0: {} - /get-set-props@0.1.0: - resolution: {integrity: sha512-7oKuKzAGKj0ag+eWZwcGw2fjiZ78tXnXQoBgY0aU7ZOxTu4bB7hSuQSDgtKy978EDH062P5FmD2EWiDpQS9K9Q==} - engines: {node: '>=0.10.0'} - dev: true + get-set-props@0.1.0: {} - /get-stack-trace@2.1.1: - resolution: {integrity: sha512-dhqSDD9lHU/6FvIZ9KbXGmVK6IKr9ZskZtNOUvhlCiONlnqatu4FmAeRbxCfJJVuQ0NWfz6dAbibKQg19B7AmQ==} - engines: {node: '>=8.0'} + get-stack-trace@2.1.1: dependencies: bluebird: 3.7.2 source-map: 0.8.0-beta.0 - /get-stream@5.2.0: - resolution: {integrity: sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==} - engines: {node: '>=8'} + get-stream@5.2.0: dependencies: pump: 3.0.0 - dev: true - /get-stream@6.0.1: - resolution: {integrity: sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==} - engines: {node: '>=10'} + get-stream@6.0.1: {} - /get-stream@8.0.1: - resolution: {integrity: sha512-VaUJspBffn/LMCJVoMvSAdmscJyS1auj5Zulnn5UoYcY531UWmdwhRWkcGKnGU93m5HSXP9LP2usOryrBtQowA==} - engines: {node: '>=16'} + get-stream@8.0.1: {} - /get-symbol-description@1.0.0: - resolution: {integrity: sha512-2EmdH1YvIQiZpltCNgkuiUnyukzxM/R6NDJX31Ke3BG1Nq5b0S2PhX59UKi9vZpPDQVdqn+1IcaAwnzTT5vCjw==} - engines: {node: '>= 0.4'} + get-symbol-description@1.0.0: dependencies: call-bind: 1.0.7 get-intrinsic: 1.2.4 - dev: true - /get-symbol-description@1.0.2: - resolution: {integrity: sha512-g0QYk1dZBxGwk+Ngc+ltRH2IBp2f7zBkBMBJZCDerh6EhlhSR6+9irMCuT/09zD6qkarHUSn529sK/yL4S27mg==} - engines: {node: '>= 0.4'} + get-symbol-description@1.0.2: dependencies: call-bind: 1.0.7 es-errors: 1.3.0 get-intrinsic: 1.2.4 - dev: true - /get-tsconfig@4.7.3: - resolution: {integrity: sha512-ZvkrzoUA0PQZM6fy6+/Hce561s+faD1rsNwhnO5FelNjyy7EMGJ3Rz1AQ8GYDWjhRs/7dBLOEJvhK8MiEJOAFg==} + get-tsconfig@4.7.3: dependencies: resolve-pkg-maps: 1.0.0 - dev: true - /get-uri@6.0.1: - resolution: {integrity: sha512-7ZqONUVqaabogsYNWlYj0t3YZaL6dhuEueZXGF+/YVmf6dHmaFg8/6psJKqhx9QykIDKzpGcy2cn4oV4YC7V/Q==} - engines: {node: '>= 14'} + get-uri@6.0.1: dependencies: basic-ftp: 5.0.3 data-uri-to-buffer: 5.0.1 @@ -13735,46 +19072,30 @@ packages: fs-extra: 8.1.0 transitivePeerDependencies: - supports-color - dev: true - /git-raw-commits@4.0.0: - resolution: {integrity: sha512-ICsMM1Wk8xSGMowkOmPrzo2Fgmfo4bMHLNX6ytHjajRJUqvHOw/TFapQ+QG75c3X/tTDDhOSRPGC52dDbNM8FQ==} - engines: {node: '>=16'} - hasBin: true + git-raw-commits@4.0.0: dependencies: dargs: 8.1.0 meow: 12.1.1 split2: 4.2.0 - dev: true - /glob-parent@5.1.2: - resolution: {integrity: sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==} - engines: {node: '>= 6'} + glob-parent@5.1.2: dependencies: is-glob: 4.0.3 - dev: true - /glob-parent@6.0.2: - resolution: {integrity: sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==} - engines: {node: '>=10.13.0'} + glob-parent@6.0.2: dependencies: is-glob: 4.0.3 - dev: true - /glob@10.3.12: - resolution: {integrity: sha512-TCNv8vJ+xz4QiqTpfOJA7HvYv+tNIRHKfUWw/q+v2jdgN4ebz+KY9tGx5J4rHP0o84mNP+ApH66HRX8us3Khqg==} - engines: {node: '>=16 || 14 >=14.17'} - hasBin: true + glob@10.3.12: dependencies: foreground-child: 3.1.1 jackspeak: 2.3.6 minimatch: 9.0.4 minipass: 7.0.4 path-scurry: 1.10.2 - dev: false - /glob@7.2.3: - resolution: {integrity: sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==} + glob@7.2.3: dependencies: fs.realpath: 1.0.0 inflight: 1.0.6 @@ -13782,93 +19103,58 @@ packages: minimatch: 3.1.2 once: 1.4.0 path-is-absolute: 1.0.1 - dev: true - /glob@8.1.0: - resolution: {integrity: sha512-r8hpEjiQEYlF2QU0df3dS+nxxSIreXQS1qRhMJM0Q5NDdR386C7jb7Hwwod8Fgiuex+k0GFjgft18yvxm5XoCQ==} - engines: {node: '>=12'} + glob@8.1.0: dependencies: fs.realpath: 1.0.0 inflight: 1.0.6 inherits: 2.0.4 minimatch: 5.1.6 once: 1.4.0 - dev: true - /global-directory@4.0.1: - resolution: {integrity: sha512-wHTUcDUoZ1H5/0iVqEudYW4/kAlN5cZ3j/bXn0Dpbizl9iaUVeWSHqiOjsgk6OW2bkLclbBjzewBz6weQ1zA2Q==} - engines: {node: '>=18'} + global-directory@4.0.1: dependencies: ini: 4.1.1 - dev: true - /global-modules@0.2.3: - resolution: {integrity: sha512-JeXuCbvYzYXcwE6acL9V2bAOeSIGl4dD+iwLY9iUx2VBJJ80R18HCn+JCwHM9Oegdfya3lEkGCdaRkSyc10hDA==} - engines: {node: '>=0.10.0'} + global-modules@0.2.3: dependencies: global-prefix: 0.1.5 is-windows: 0.2.0 - dev: true - /global-modules@2.0.0: - resolution: {integrity: sha512-NGbfmJBp9x8IxyJSd1P+otYK8vonoJactOogrVfFRIAEY1ukil8RSKDz2Yo7wh1oihl51l/r6W4epkeKJHqL8A==} - engines: {node: '>=6'} + global-modules@2.0.0: dependencies: global-prefix: 3.0.0 - dev: true - /global-prefix@0.1.5: - resolution: {integrity: sha512-gOPiyxcD9dJGCEArAhF4Hd0BAqvAe/JzERP7tYumE4yIkmIedPUVXcJFWbV3/p/ovIIvKjkrTk+f1UVkq7vvbw==} - engines: {node: '>=0.10.0'} + global-prefix@0.1.5: dependencies: homedir-polyfill: 1.0.3 ini: 1.3.8 is-windows: 0.2.0 which: 1.3.1 - dev: true - /global-prefix@3.0.0: - resolution: {integrity: sha512-awConJSVCHVGND6x3tmMaKcQvwXLhjdkmomy2W+Goaui8YPgYgXJZewhg3fWC+DlfqqQuWg8AwqjGTD2nAPVWg==} - engines: {node: '>=6'} + global-prefix@3.0.0: dependencies: ini: 1.3.8 kind-of: 6.0.3 which: 1.3.1 - dev: true - /globals@11.12.0: - resolution: {integrity: sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==} - engines: {node: '>=4'} - dev: true + globals@11.12.0: {} - /globals@13.20.0: - resolution: {integrity: sha512-Qg5QtVkCy/kv3FUSlu4ukeZDVf9ee0iXLAUYX13gbR17bnejFTzr4iS9bY7kwCf1NztRNm1t91fjOiyx4CSwPQ==} - engines: {node: '>=8'} + globals@13.20.0: dependencies: type-fest: 0.20.2 - dev: true - /globals@14.0.0: - resolution: {integrity: sha512-oahGvuMGQlPw/ivIYBjVSrWAfWLBeku5tpPE2fOPLi+WHffIWbuh2tCjhyQhTBPMf5E9jDEH4FOmTYgYwbKwtQ==} - engines: {node: '>=18'} - dev: true + globals@14.0.0: {} - /globalthis@1.0.2: - resolution: {integrity: sha512-ZQnSFO1la8P7auIOQECnm0sSuoMeaSq0EEdXMBFF2QJO4uNcwbyhSgG3MruWNbFTqCLmxVwGOl7LZ9kASvHdeQ==} - engines: {node: '>= 0.4'} + globalthis@1.0.2: dependencies: define-properties: 1.1.4 - /globalthis@1.0.3: - resolution: {integrity: sha512-sFdI5LyBiNTHjRd7cGPWapiHWMOXKyuBNX/cWJ3NfzrZQVa8GI/8cofCl74AOVqq9W5kNmguTIzJ/1s2gyI9wA==} - engines: {node: '>= 0.4'} + globalthis@1.0.3: dependencies: define-properties: 1.2.1 - dev: true - /globby@11.1.0: - resolution: {integrity: sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==} - engines: {node: '>=10'} + globby@11.1.0: dependencies: array-union: 2.1.0 dir-glob: 3.0.1 @@ -13876,23 +19162,14 @@ packages: ignore: 5.3.1 merge2: 1.4.1 slash: 3.0.0 - dev: true - /globjoin@0.1.4: - resolution: {integrity: sha512-xYfnw62CKG8nLkZBfWbhWwDw02CHty86jfPcc2cr3ZfeuK9ysoVPPEUxf21bAD/rWAgk52SuBrLJlefNy8mvFg==} - dev: true + globjoin@0.1.4: {} - /goober@2.1.8(csstype@3.0.11): - resolution: {integrity: sha512-S0C85gCzcfFCMSdjD/CxyQMt1rbf2qEg6hmDzxk2FfD7+7Ogk55m8ZFUMtqNaZM4VVX/qaU9AzSORG+Gf4ZpAQ==} - peerDependencies: - csstype: ^3.0.10 + goober@2.1.8(csstype@3.0.11): dependencies: csstype: 3.0.11 - dev: true - /google-auth-library@9.8.0: - resolution: {integrity: sha512-TJJXFzMlVGRlIH27gYZ6XXyPf5Y3OItsKFfefsDAafNNywYRTkei83nEO29IrYj8GtdHWU78YnW+YZdaZaXIJA==} - engines: {node: '>=14'} + google-auth-library@9.8.0: dependencies: base64-js: 1.5.1 ecdsa-sig-formatter: 1.0.11 @@ -13903,16 +19180,12 @@ packages: transitivePeerDependencies: - encoding - supports-color - dev: false - /gopd@1.0.1: - resolution: {integrity: sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==} + gopd@1.0.1: dependencies: get-intrinsic: 1.2.4 - /got@13.0.0: - resolution: {integrity: sha512-XfBk1CxOOScDcMr9O1yKkNaQyy865NbYs+F7dr4H0LZMVgCj2Le59k6PqbNHoL5ToeaEQUYh6c6yMfVcc6SJxA==} - engines: {node: '>=16'} + got@13.0.0: dependencies: '@sindresorhus/is': 5.4.0 '@szmarczak/http-timer': 5.0.1 @@ -13925,11 +19198,8 @@ packages: lowercase-keys: 3.0.0 p-cancelable: 3.0.0 responselike: 3.0.0 - dev: false - /got@14.0.0: - resolution: {integrity: sha512-X01vTgaX9SwaMq5DfImvS+3GMQFFs5HtrrlS9CuzUSzkxAf/tWGEyynuI+Qy7BjciMczZGjyVSmawYbP4eYhYA==} - engines: {node: '>=20'} + got@14.0.0: dependencies: '@sindresorhus/is': 6.1.0 '@szmarczak/http-timer': 5.0.1 @@ -13942,114 +19212,68 @@ packages: lowercase-keys: 3.0.0 p-cancelable: 4.0.1 responselike: 3.0.0 - dev: false - /graceful-fs@4.2.10: - resolution: {integrity: sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA==} - dev: true + graceful-fs@4.2.10: {} - /graceful-fs@4.2.11: - resolution: {integrity: sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==} - dev: true + graceful-fs@4.2.11: {} - /grapheme-splitter@1.0.4: - resolution: {integrity: sha512-bzh50DW9kTPM00T8y4o8vQg89Di9oLJVLW/KaOGIXJWP/iqCN6WKYkbNOF04vFLJhwcpYUh9ydh/+5vpOqV4YQ==} - dev: true + grapheme-splitter@1.0.4: {} - /graphemer@1.4.0: - resolution: {integrity: sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==} - dev: true + graphemer@1.4.0: {} - /gtoken@7.0.1: - resolution: {integrity: sha512-KcFVtoP1CVFtQu0aSk3AyAt2og66PFhZAlkUOuWKwzMLoulHXG5W5wE5xAnHb+yl3/wEFoqGW7/cDGMU8igDZQ==} - engines: {node: '>=14.0.0'} + gtoken@7.0.1: dependencies: gaxios: 6.1.1 jws: 4.0.0 transitivePeerDependencies: - encoding - supports-color - dev: false - /gzip-size@7.0.0: - resolution: {integrity: sha512-O1Ld7Dr+nqPnmGpdhzLmMTQ4vAsD+rHwMm1NLUmoUFFymBOMKxCCrtDxqdBRYXdeEPEi3SyoR4TizJLQrnKBNA==} - engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + gzip-size@7.0.0: dependencies: duplexer: 0.1.2 - dev: true - /hard-rejection@2.1.0: - resolution: {integrity: sha512-VIZB+ibDhx7ObhAe7OVtoEbuP4h/MuOTHJ+J8h/eBXotJYl0fBgR72xDFCKgIh22OJZIOVNxBMWuhAr10r8HdA==} - engines: {node: '>=6'} - dev: true + hard-rejection@2.1.0: {} - /harmony-reflect@1.6.2: - resolution: {integrity: sha512-HIp/n38R9kQjDEziXyDTuW3vvoxxyxjxFzXLrBr18uB47GnSt+G9D29fqrpM5ZkspMcPICud3XsBJQ4Y2URg8g==} - dev: true + harmony-reflect@1.6.2: {} - /has-bigints@1.0.2: - resolution: {integrity: sha512-tSvCKtBr9lkF0Ex0aQiP9N+OpV4zi2r/Nee5VkRDbaqv35RLYMzbwQfFSZZH0kR+Rd6302UJZ2p/bJCEoR3VoQ==} - dev: true + has-bigints@1.0.2: {} - /has-flag@3.0.0: - resolution: {integrity: sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==} - engines: {node: '>=4'} + has-flag@3.0.0: {} - /has-flag@4.0.0: - resolution: {integrity: sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==} - engines: {node: '>=8'} - dev: true + has-flag@4.0.0: {} - /has-property-descriptors@1.0.0: - resolution: {integrity: sha512-62DVLZGoiEBDHQyqG4w9xCuZ7eJEwNmJRWw2VY84Oedb7WFcA27fiEVe8oUQx9hAUJ4ekurquucTGwsyO1XGdQ==} + has-property-descriptors@1.0.0: dependencies: get-intrinsic: 1.2.4 - /has-property-descriptors@1.0.2: - resolution: {integrity: sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==} + has-property-descriptors@1.0.2: dependencies: es-define-property: 1.0.0 - /has-proto@1.0.3: - resolution: {integrity: sha512-SJ1amZAJUiZS+PhsVLf5tGydlaVB8EdFpaSO4gmiUKUOxk8qzn5AIy4ZeJUmh22znIdk/uMAUT2pl3FxzVUH+Q==} - engines: {node: '>= 0.4'} + has-proto@1.0.3: {} - /has-symbols@1.0.3: - resolution: {integrity: sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==} - engines: {node: '>= 0.4'} + has-symbols@1.0.3: {} - /has-tostringtag@1.0.0: - resolution: {integrity: sha512-kFjcSNhnlGV1kyoGk7OXKSawH5JOb/LzUc5w9B02hOTO0dfFRjbHQKvg1d6cf3HbeUmtU9VbbV3qzZ2Teh97WQ==} - engines: {node: '>= 0.4'} + has-tostringtag@1.0.0: dependencies: has-symbols: 1.0.3 - /has-tostringtag@1.0.2: - resolution: {integrity: sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==} - engines: {node: '>= 0.4'} + has-tostringtag@1.0.2: dependencies: has-symbols: 1.0.3 - dev: true - /has@1.0.3: - resolution: {integrity: sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==} - engines: {node: '>= 0.4.0'} + has@1.0.3: dependencies: function-bind: 1.1.1 - dev: true - /hash-wasm@4.9.0: - resolution: {integrity: sha512-7SW7ejyfnRxuOc7ptQHSf4LDoZaWOivfzqw+5rpcQku0nHfmicPKE51ra9BiRLAmT8+gGLestr1XroUkqdjL6w==} - dev: false + hash-wasm@4.9.0: {} - /hasown@2.0.2: - resolution: {integrity: sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==} - engines: {node: '>= 0.4'} + hasown@2.0.2: dependencies: function-bind: 1.1.2 - /hast-to-hyperscript@9.0.1: - resolution: {integrity: sha512-zQgLKqF+O2F72S1aa4y2ivxzSlko3MAvxkwG8ehGmNiqd98BIN3JM1rAJPmplEyLmGLO2QZYJtIneOSZ2YbJuA==} + hast-to-hyperscript@9.0.1: dependencies: '@types/unist': 2.0.6 comma-separated-tokens: 1.0.8 @@ -14058,10 +19282,8 @@ packages: style-to-object: 0.3.0 unist-util-is: 4.1.0 web-namespaces: 1.1.4 - dev: true - /hast-util-from-parse5@6.0.1: - resolution: {integrity: sha512-jeJUWiN5pSxW12Rh01smtVkZgZr33wBokLzKLwinYOUfSzm1Nl/c3GUGebDyOKjdsRgMvoVbV0VpAcpjF4NrJA==} + hast-util-from-parse5@6.0.1: dependencies: '@types/parse5': 5.0.3 hastscript: 6.0.0 @@ -14069,14 +19291,10 @@ packages: vfile: 4.2.1 vfile-location: 3.2.0 web-namespaces: 1.1.4 - dev: true - /hast-util-parse-selector@2.2.5: - resolution: {integrity: sha512-7j6mrk/qqkSehsM92wQjdIgWM2/BW61u/53G6xmC8i1OmEdKLHbk419QKQUjz6LglWsfqoiHmyMRkP1BGjecNQ==} - dev: true + hast-util-parse-selector@2.2.5: {} - /hast-util-raw@6.0.1: - resolution: {integrity: sha512-ZMuiYA+UF7BXBtsTBNcLBF5HzXzkyE6MLzJnL605LKE8GJylNjGc4jjxazAHUtcwT5/CEt6afRKViYB4X66dig==} + hast-util-raw@6.0.1: dependencies: '@types/hast': 2.3.4 hast-util-from-parse5: 6.0.1 @@ -14088,10 +19306,8 @@ packages: web-namespaces: 1.1.4 xtend: 4.0.2 zwitch: 1.0.5 - dev: true - /hast-util-to-jsx-runtime@2.2.0: - resolution: {integrity: sha512-wSlp23N45CMjDg/BPW8zvhEi3R+8eRE1qFbjEyAUzMCzu2l1Wzwakq+Tlia9nkCtEl5mDxa7nKHsvYJ6Gfn21A==} + hast-util-to-jsx-runtime@2.2.0: dependencies: '@types/hast': 3.0.1 '@types/unist': 3.0.0 @@ -14102,189 +19318,104 @@ packages: style-to-object: 0.4.2 unist-util-position: 5.0.0 vfile-message: 4.0.2 - dev: true - /hast-util-to-parse5@6.0.0: - resolution: {integrity: sha512-Lu5m6Lgm/fWuz8eWnrKezHtVY83JeRGaNQ2kn9aJgqaxvVkFCZQBEhgodZUDUvoodgyROHDb3r5IxAEdl6suJQ==} + hast-util-to-parse5@6.0.0: dependencies: hast-to-hyperscript: 9.0.1 property-information: 5.6.0 web-namespaces: 1.1.4 xtend: 4.0.2 zwitch: 1.0.5 - dev: true - /hast-util-whitespace@3.0.0: - resolution: {integrity: sha512-88JUN06ipLwsnv+dVn+OIYOvAuvBMy/Qoi6O7mQHxdPXpjy+Cd6xRkWwux7DKO+4sYILtLBRIKgsdpS2gQc7qw==} + hast-util-whitespace@3.0.0: dependencies: '@types/hast': 3.0.1 - dev: true - /hastscript@6.0.0: - resolution: {integrity: sha512-nDM6bvd7lIqDUiYEiu5Sl/+6ReP0BMk/2f4U/Rooccxkj0P5nm+acM5PrGJ/t5I8qPGiqZSE6hVAwZEdZIvP4w==} + hastscript@6.0.0: dependencies: '@types/hast': 2.3.4 comma-separated-tokens: 1.0.8 hast-util-parse-selector: 2.2.5 property-information: 5.6.0 space-separated-tokens: 1.1.5 - dev: true - /helmet@7.0.0: - resolution: {integrity: sha512-MsIgYmdBh460ZZ8cJC81q4XJknjG567wzEmv46WOBblDb6TUd3z8/GhgmsM9pn8g2B80tAJ4m5/d3Bi1KrSUBQ==} - engines: {node: '>=16.0.0'} - dev: false + helmet@7.0.0: {} - /hexoid@1.0.0: - resolution: {integrity: sha512-QFLV0taWQOZtvIRIAdBChesmogZrtuXvVWsFHZTk2SU+anspqZ2vMnoLg7IE1+Uk16N19APic1BuF8bC8c2m5g==} - engines: {node: '>=8'} + hexoid@1.0.0: {} - /highlight.js@10.7.3: - resolution: {integrity: sha512-tzcUFauisWKNHaRkN4Wjl/ZA07gENAjFl3J/c480dprkGTg5EQstgaNFqBfUqCq54kZRIEcreTsAgF/m2quD7A==} - dev: true + highlight.js@10.7.3: {} - /history@5.3.0: - resolution: {integrity: sha512-ZqaKwjjrAYUYfLG+htGaIIZ4nioX2L70ZUMIFysS3xvBsSG4x/n1V6TXV3N8ZYNuFGlDirFg32T7B6WOUPDYcQ==} + history@5.3.0: dependencies: '@babel/runtime': 7.19.4 - dev: true - /hoist-non-react-statics@3.3.2: - resolution: {integrity: sha512-/gGivxi8JPKWNm/W0jSmzcMPpfpPLc3dY/6GxhX2hQ9iGj3aDfklV4ET7NjKpSinLpJ5vafa9iiGIEZg10SfBw==} + hoist-non-react-statics@3.3.2: dependencies: react-is: 16.13.1 - dev: true - /homedir-polyfill@1.0.3: - resolution: {integrity: sha512-eSmmWE5bZTK2Nou4g0AI3zZ9rswp7GRKoKXS1BLUkvPviOqs4YTN1djQIqrXy9k5gEtdLPy86JjRwsNM9tnDcA==} - engines: {node: '>=0.10.0'} + homedir-polyfill@1.0.3: dependencies: parse-passwd: 1.0.0 - dev: true - /hosted-git-info@2.8.9: - resolution: {integrity: sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw==} - dev: true + hosted-git-info@2.8.9: {} - /hosted-git-info@4.1.0: - resolution: {integrity: sha512-kyCuEOWjJqZuDbRHzL8V93NzQhwIB71oFWSyzVo+KPZI+pnQPPxucdkrOZvkLRnrf5URsQM+IJ09Dw29cRALIA==} - engines: {node: '>=10'} + hosted-git-info@4.1.0: dependencies: lru-cache: 6.0.0 - dev: true - /hpagent@1.2.0: - resolution: {integrity: sha512-A91dYTeIB6NoXG+PxTQpCCDDnfHsW9kc06Lvpu1TEe9gnd6ZFeiBoRO9JvzEv6xK7EX97/dUE8g/vBMTqTS3CA==} - engines: {node: '>=14'} - dev: false + hpagent@1.2.0: {} - /html-encoding-sniffer@3.0.0: - resolution: {integrity: sha512-oWv4T4yJ52iKrufjnyZPkrN0CH3QnrUqdB6In1g5Fe1mia8GmF36gnfNySxoZtxD5+NmYw1EElVXiBk93UeskA==} - engines: {node: '>=12'} + html-encoding-sniffer@3.0.0: dependencies: whatwg-encoding: 2.0.0 - dev: true - /html-escaper@2.0.2: - resolution: {integrity: sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==} - dev: true + html-escaper@2.0.2: {} - /html-parse-stringify@3.0.1: - resolution: {integrity: sha512-KknJ50kTInJ7qIScF3jeaFRpMpE8/lfiTdzf/twXyPBLAGrLRTmkz3AdTnKeh40X8k9L2fdYwEp/42WGXIRGcg==} + html-parse-stringify@3.0.1: dependencies: void-elements: 3.1.0 - dev: true - /html-tags@3.3.1: - resolution: {integrity: sha512-ztqyC3kLto0e9WbNp0aeP+M3kTt+nbaIveGmUxAtZa+8iFgKLUOD4YKM5j+f3QD89bra7UeumolZHKuOXnTmeQ==} - engines: {node: '>=8'} - dev: true + html-tags@3.3.1: {} - /html-url-attributes@3.0.0: - resolution: {integrity: sha512-/sXbVCWayk6GDVg3ctOX6nxaVj7So40FcFAnWlWGNAB1LpYKcV5Cd10APjPjW80O7zYW2MsjBV4zZ7IZO5fVow==} - dev: true + html-url-attributes@3.0.0: {} - /html-void-elements@1.0.5: - resolution: {integrity: sha512-uE/TxKuyNIcx44cIWnjr/rfIATDH7ZaOMmstu0CwhFG1Dunhlp4OC6/NMbhiwoq5BpW0ubi303qnEk/PZj614w==} - dev: true + html-void-elements@1.0.5: {} - /htmlnano@2.0.3(postcss@8.4.31)(svgo@2.8.0): - resolution: {integrity: sha512-S4PGGj9RbdgW8LhbILNK7W9JhmYP8zmDY7KDV/8eCiJBQJlbmltp5I0gv8c5ntLljfdxxfmJ+UJVSqyH4mb41A==} - peerDependencies: - cssnano: ^5.0.11 - postcss: ^8.3.11 - purgecss: ^5.0.0 - relateurl: ^0.2.7 - srcset: 4.0.0 - svgo: ^2.8.0 - terser: ^5.10.0 - uncss: ^0.17.3 - peerDependenciesMeta: - cssnano: - optional: true - postcss: - optional: true - purgecss: - optional: true - relateurl: - optional: true - srcset: - optional: true - svgo: - optional: true - terser: - optional: true - uncss: - optional: true + htmlnano@2.0.3(postcss@8.4.31)(svgo@2.8.0): dependencies: cosmiconfig: 7.1.0 postcss: 8.4.31 posthtml: 0.16.6 svgo: 2.8.0 timsort: 0.3.0 - dev: true - /htmlparser2@7.2.0: - resolution: {integrity: sha512-H7MImA4MS6cw7nbyURtLPO1Tms7C5H602LRETv95z1MxO/7CP7rDVROehUYeYBUYEON94NXXDEPmZuq+hX4sog==} + htmlparser2@7.2.0: dependencies: domelementtype: 2.3.0 domhandler: 4.3.1 domutils: 2.8.0 entities: 3.0.1 - dev: true - /http-assert@1.5.0: - resolution: {integrity: sha512-uPpH7OKX4H25hBmU6G1jWNaqJGpTXxey+YOUizJUAgu0AjLUeC8D73hTrhvDS5D+GJN1DN1+hhc/eF/wpxtp0w==} - engines: {node: '>= 0.8'} + http-assert@1.5.0: dependencies: deep-equal: 1.0.1 http-errors: 1.8.1 - /http-cache-semantics@4.1.1: - resolution: {integrity: sha512-er295DKPVsV82j5kw1Gjt+ADA/XYHsajl82cGNQG2eyoPkvgUhX+nDIyelzhIWbbsXP39EHcI6l5tYs2FYqYXQ==} - dev: false + http-cache-semantics@4.1.1: {} - /http-errors@1.4.0: - resolution: {integrity: sha512-oLjPqve1tuOl5aRhv8GK5eHpqP1C9fb+Ol+XTLjKfLltE44zdDbEdjPSbU7Ch5rSNsVFqZn97SrMmZLdu1/YMw==} - engines: {node: '>= 0.6'} + http-errors@1.4.0: dependencies: inherits: 2.0.1 statuses: 1.5.0 - dev: false - /http-errors@1.6.3: - resolution: {integrity: sha512-lks+lVC8dgGyh97jxvxeYTWQFvh4uw4yC12gVl63Cg30sjPX4wuGcdkICVXDAESr6OJGjqGA8Iz5mkeN6zlD7A==} - engines: {node: '>= 0.6'} + http-errors@1.6.3: dependencies: depd: 1.1.2 inherits: 2.0.3 setprototypeof: 1.1.0 statuses: 1.5.0 - dev: false - /http-errors@1.8.1: - resolution: {integrity: sha512-Kpk9Sm7NmI+RHhnj6OIWDI1d6fIoFAtFt9RLaTMRlg/8w49juAStsrBgp0Dp4OdxdVbRIeKhtCUvoi/RuAhO4g==} - engines: {node: '>= 0.6'} + http-errors@1.8.1: dependencies: depd: 1.1.2 inherits: 2.0.4 @@ -14292,20 +19423,15 @@ packages: statuses: 1.5.0 toidentifier: 1.0.1 - /http-errors@2.0.0: - resolution: {integrity: sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==} - engines: {node: '>= 0.8'} + http-errors@2.0.0: dependencies: depd: 2.0.0 inherits: 2.0.4 setprototypeof: 1.2.0 statuses: 2.0.1 toidentifier: 1.0.1 - dev: false - /http-proxy-agent@5.0.0: - resolution: {integrity: sha512-n2hY8YdoRE1i7r6M0w9DIw5GgZN0G25P8zLCRQ8rjXtTU3vsNFBI/vWK/UIeE6g5MUUz6avwAPXmL6Fy9D/90w==} - engines: {node: '>= 6'} + http-proxy-agent@5.0.0: dependencies: '@tootallnate/once': 2.0.0 agent-base: 6.0.2 @@ -14313,230 +19439,133 @@ packages: transitivePeerDependencies: - supports-color - /http-proxy-agent@7.0.2: - resolution: {integrity: sha512-T1gkAiYYDWYx3V5Bmyu7HcfcvL7mUrTWiM6yOfa3PIphViJ/gFPbvidQ+veqSOHci/PxBcDabeUNCzpOODJZig==} - engines: {node: '>= 14'} + http-proxy-agent@7.0.2: dependencies: agent-base: 7.1.0 debug: 4.3.4 transitivePeerDependencies: - supports-color - dev: true - /http-proxy@1.18.1: - resolution: {integrity: sha512-7mz/721AbnJwIVbnaSv1Cz3Am0ZLT/UBwkC92VlxhXv/k/BBQfM2fXElQNC27BVGr0uwUpplYPQM9LnaBMR5NQ==} - engines: {node: '>=8.0.0'} + http-proxy@1.18.1: dependencies: eventemitter3: 4.0.7 follow-redirects: 1.15.6 requires-port: 1.0.0 transitivePeerDependencies: - debug - dev: false - /http2-wrapper@2.2.1: - resolution: {integrity: sha512-V5nVw1PAOgfI3Lmeaj2Exmeg7fenjhRUgz1lPSezy1CuhPYbgQtbQj4jZfEAEMlaL+vupsvhjqCyjzob0yxsmQ==} - engines: {node: '>=10.19.0'} + http2-wrapper@2.2.1: dependencies: quick-lru: 5.1.1 resolve-alpn: 1.2.1 - dev: false - /https-proxy-agent@5.0.1: - resolution: {integrity: sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA==} - engines: {node: '>= 6'} + https-proxy-agent@5.0.1: dependencies: agent-base: 6.0.2 debug: 4.3.4 transitivePeerDependencies: - supports-color - /https-proxy-agent@7.0.4: - resolution: {integrity: sha512-wlwpilI7YdjSkWaQ/7omYBMTliDcmCN8OLihO6I9B86g06lMyAoqgoDpV0XqoaPOKj+0DIdAvnsWfyAAhmimcg==} - engines: {node: '>= 14'} + https-proxy-agent@7.0.4: dependencies: agent-base: 7.1.0 debug: 4.3.4 transitivePeerDependencies: - supports-color - /human-id@1.0.2: - resolution: {integrity: sha512-UNopramDEhHJD+VR+ehk8rOslwSfByxPIZyJRfV739NDhN5LF1fa1MqnzKm2lGTQRjNrjK19Q5fhkgIfjlVUKw==} - dev: true + human-id@1.0.2: {} - /human-signals@2.1.0: - resolution: {integrity: sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==} - engines: {node: '>=10.17.0'} - dev: true + human-signals@2.1.0: {} - /human-signals@5.0.0: - resolution: {integrity: sha512-AXcZb6vzzrFAUE61HnN4mpLqd/cSIwNQjtNWR0euPm6y0iqx3G4gOXaIDdtdDwZmhwe82LA6+zinmW4UBWVePQ==} - engines: {node: '>=16.17.0'} - dev: true + human-signals@5.0.0: {} - /humanize-number@0.0.2: - resolution: {integrity: sha1-EcCvakcWQ2M1iFiASPF5lUFInBg=} - dev: false + humanize-number@0.0.2: {} - /husky@9.0.7: - resolution: {integrity: sha512-vWdusw+y12DUEeoZqW1kplOFqk3tedGV8qlga8/SF6a3lOiWLqGZZQvfWvY0fQYdfiRi/u1DFNpudTSV9l1aCg==} - engines: {node: '>=18'} - hasBin: true - dev: true + husky@9.0.7: {} - /i18next-browser-languagedetector@7.0.1: - resolution: {integrity: sha512-Pa5kFwaczXJAeHE56CHG2aWzFBMJNUNghf0Pm4SwSrEMps/PTKqW90EYWlIvhuYStf3Sn1K0vw+gH3+TLdkH1g==} + i18next-browser-languagedetector@7.0.1: dependencies: '@babel/runtime': 7.21.0 - dev: true - /i18next@22.4.15: - resolution: {integrity: sha512-yYudtbFrrmWKLEhl6jvKUYyYunj4bTBCe2qIUYAxbXoPusY7YmdwPvOE6fx6UIfWvmlbCWDItr7wIs8KEBZ5Zg==} + i18next@22.4.15: dependencies: '@babel/runtime': 7.21.0 - /iconv-lite@0.4.24: - resolution: {integrity: sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==} - engines: {node: '>=0.10.0'} + iconv-lite@0.4.24: dependencies: safer-buffer: 2.1.2 - /iconv-lite@0.6.3: - resolution: {integrity: sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==} - engines: {node: '>=0.10.0'} + iconv-lite@0.6.3: dependencies: safer-buffer: 2.1.2 - /icss-replace-symbols@1.1.0: - resolution: {integrity: sha1-Bupvg2ead0njhs/h/oEq5dsiPe0=} - dev: true + icss-replace-symbols@1.1.0: {} - /icss-utils@5.1.0(postcss@8.4.31): - resolution: {integrity: sha512-soFhflCVWLfRNOPU3iv5Z9VUdT44xFRbzjLsEzSr5AQmgqPMTHdU3PMT1Cf1ssx8fLNJDA1juftYl+PUcv3MqA==} - engines: {node: ^10 || ^12 || >= 14} - peerDependencies: - postcss: ^8.1.0 + icss-utils@5.1.0(postcss@8.4.31): dependencies: postcss: 8.4.31 - dev: true - /identity-obj-proxy@3.0.0: - resolution: {integrity: sha512-00n6YnVHKrinT9t0d9+5yZC6UBNJANpYEQvL2LlX6Ab9lnmxzIRcEmTPuyGScvl1+jKuCICX1Z0Ab1pPKKdikA==} - engines: {node: '>=4'} + identity-obj-proxy@3.0.0: dependencies: harmony-reflect: 1.6.2 - dev: true - /ieee754@1.2.1: - resolution: {integrity: sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==} + ieee754@1.2.1: {} - /ignore-by-default@1.0.1: - resolution: {integrity: sha512-Ius2VYcGNk7T90CppJqcIkS5ooHUZyIQK+ClZfMfMNFEF9VSE73Fq+906u/CWu92x4gzZMWOwfFYckPObzdEbA==} - dev: true + ignore-by-default@1.0.1: {} - /ignore@5.3.1: - resolution: {integrity: sha512-5Fytz/IraMjqpwfd34ke28PTVMjZjJG2MPn5t7OE4eUCUNf8BAa7b5WUS9/Qvr6mwOQS7Mk6vdsMno5he+T8Xw==} - engines: {node: '>= 4'} - dev: true + ignore@5.3.1: {} - /immutable@4.1.0: - resolution: {integrity: sha512-oNkuqVTA8jqG1Q6c+UglTOD1xhC1BtjKI7XkCXRkZHrN5m18/XsnUp8Q89GkQO/z+0WjonSvl0FLhDYftp46nQ==} - dev: true + immutable@4.1.0: {} - /import-fresh@3.3.0: - resolution: {integrity: sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==} - engines: {node: '>=6'} + import-fresh@3.3.0: dependencies: parent-module: 1.0.1 resolve-from: 4.0.0 - dev: true - /import-in-the-middle@1.4.2: - resolution: {integrity: sha512-9WOz1Yh/cvO/p69sxRmhyQwrIGGSp7EIdcb+fFNVi7CzQGQB8U1/1XrKVSbEd/GNOAeM0peJtmi7+qphe7NvAw==} + import-in-the-middle@1.4.2: dependencies: acorn: 8.11.3 acorn-import-assertions: 1.9.0(acorn@8.11.3) cjs-module-lexer: 1.2.2 module-details-from-path: 1.0.3 - dev: false - /import-lazy@4.0.0: - resolution: {integrity: sha512-rKtvo6a868b5Hu3heneU+L4yEQ4jYKLtjpnPeUdK7h0yzXGmyBTypknlkCvHFBqfX9YlorEiMM6Dnq/5atfHkw==} - engines: {node: '>=8'} - dev: true + import-lazy@4.0.0: {} - /import-local@3.1.0: - resolution: {integrity: sha512-ASB07uLtnDs1o6EHjKpX34BKYDSqnFerfTOJL2HvMqF70LnxpjkzDB8J44oT9pu4AMPkQwf8jl6szgvNd2tRIg==} - engines: {node: '>=8'} - hasBin: true + import-local@3.1.0: dependencies: pkg-dir: 4.2.0 resolve-cwd: 3.0.0 - dev: true - /import-meta-resolve@4.0.0: - resolution: {integrity: sha512-okYUR7ZQPH+efeuMJGlq4f8ubUgO50kByRPyt/Cy1Io4PSRsPjxME+YlVaCOx+NIToW7hCsZNFJyTPFFKepRSA==} - dev: true + import-meta-resolve@4.0.0: {} - /import-modules@2.1.0: - resolution: {integrity: sha512-8HEWcnkbGpovH9yInoisxaSoIg9Brbul+Ju3Kqe2UsYDUBJD/iQjSgEj0zPcTDPKfPp2fs5xlv1i+JSye/m1/A==} - engines: {node: '>=8'} - dev: true + import-modules@2.1.0: {} - /imurmurhash@0.1.4: - resolution: {integrity: sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==} - engines: {node: '>=0.8.19'} - dev: true + imurmurhash@0.1.4: {} - /indent-string@4.0.0: - resolution: {integrity: sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==} - engines: {node: '>=8'} - dev: true + indent-string@4.0.0: {} - /indent-string@5.0.0: - resolution: {integrity: sha512-m6FAo/spmsW2Ab2fU35JTYwtOKa2yAwXSwgjSv1TJzh4Mh7mC3lzAOVLBprb72XsTrgkEIsl7YrFNAiDiRhIGg==} - engines: {node: '>=12'} - dev: true + indent-string@5.0.0: {} - /inflation@2.0.0: - resolution: {integrity: sha512-m3xv4hJYR2oXw4o4Y5l6P5P16WYmazYof+el6Al3f+YlggGj6qT9kImBAnzDelRALnP5d3h4jGBPKzYCizjZZw==} - engines: {node: '>= 0.8.0'} - dev: false + inflation@2.0.0: {} - /inflight@1.0.6: - resolution: {integrity: sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==} + inflight@1.0.6: dependencies: once: 1.4.0 wrappy: 1.0.2 - dev: true - /inherits@2.0.1: - resolution: {integrity: sha512-8nWq2nLTAwd02jTqJExUYFSD/fKq6VH9Y/oG2accc/kdI0V98Bag8d5a4gi3XHz73rDWa2PvTtvcWYquKqSENA==} - dev: false + inherits@2.0.1: {} - /inherits@2.0.3: - resolution: {integrity: sha512-x00IRNXNy63jwGkJmzPigoySHbaqpNuzKbBOmzK+g2OdZpQ9w+sxCN+VSB3ja7IAge2OP2qpfxTjeNcyjmW1uw==} - dev: false + inherits@2.0.3: {} - /inherits@2.0.4: - resolution: {integrity: sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==} + inherits@2.0.4: {} - /ini@1.3.8: - resolution: {integrity: sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==} - dev: true + ini@1.3.8: {} - /ini@4.1.1: - resolution: {integrity: sha512-QQnnxNyfvmHFIsj7gkPcYymR8Jdw/o7mp5ZFihxn6h8Ci6fh3Dx4E1gPjpQEpIuPo9XVNY/ZUwh4BPMjGyL01g==} - engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} - dev: true + ini@4.1.1: {} - /inline-style-parser@0.1.1: - resolution: {integrity: sha512-7NXolsK4CAS5+xvdj5OMMbI962hU/wvwoxk+LWR9Ek9bVtyuuYScDN6eS0rUm6TxApFpw7CX1o4uJzcd4AyD3Q==} - dev: true + inline-style-parser@0.1.1: {} - /inquirer@9.1.4: - resolution: {integrity: sha512-9hiJxE5gkK/cM2d1mTEnuurGTAoHebbkX0BYl3h7iEg7FYfuNIom+nDfBCSWtvSnoSrWCeBxqqBZu26xdlJlXA==} - engines: {node: '>=12.0.0'} + inquirer@9.1.4: dependencies: ansi-escapes: 6.0.0 chalk: 5.1.2 @@ -14553,437 +19582,240 @@ packages: strip-ansi: 7.0.1 through: 2.3.8 wrap-ansi: 8.0.1 - dev: false - /internal-slot@1.0.3: - resolution: {integrity: sha512-O0DB1JC/sPyZl7cIo78n5dR7eUSwwpYPiXRhTzNxZVAMUuB8vlnRFyLxdrVToks6XPLVnFfbzaVd5WLjhgg+vA==} - engines: {node: '>= 0.4'} + internal-slot@1.0.3: dependencies: get-intrinsic: 1.2.4 has: 1.0.3 side-channel: 1.0.6 - dev: true - /internal-slot@1.0.7: - resolution: {integrity: sha512-NGnrKwXzSms2qUUih/ILZ5JBqNTSa1+ZmP6flaIp6KmSElgE9qdndzS3cqjrDovwFdmwsGsLdeFgB6suw+1e9g==} - engines: {node: '>= 0.4'} + internal-slot@1.0.7: dependencies: es-errors: 1.3.0 hasown: 2.0.2 side-channel: 1.0.6 - dev: true - /internmap@1.0.1: - resolution: {integrity: sha512-lDB5YccMydFBtasVtxnZ3MRBHuaoE8GKsppq+EchKL2U4nK/DmEpPHNH8MZe5HkMtpSiTSOZwfN0tzYjO/lJEw==} - dev: true + internmap@1.0.1: {} - /ip@1.1.9: - resolution: {integrity: sha512-cyRxvOEpNHNtchU3Ln9KC/auJgup87llfQpQ+t5ghoC/UhL16SWzbueiCsdTnWmqAWl7LadfuwhlqmtOaqMHdQ==} - dev: true + ip@1.1.9: {} - /ip@2.0.1: - resolution: {integrity: sha512-lJUL9imLTNi1ZfXT+DU6rBBdbiKGBuay9B6xGSPVjUeQwaH1RIGqef8RZkUtHioLmSNpPR5M4HVKJGm1j8FWVQ==} - dev: true + ip@2.0.1: {} - /ipaddr.js@2.1.0: - resolution: {integrity: sha512-LlbxQ7xKzfBusov6UMi4MFpEg0m+mAm9xyNGEduwXMEDuf4WfzB/RZwMVYEd7IKGvh4IUkEXYxtAVu9T3OelJQ==} - engines: {node: '>= 10'} - dev: false + ipaddr.js@2.1.0: {} - /is-alphabetical@1.0.4: - resolution: {integrity: sha512-DwzsA04LQ10FHTZuL0/grVDk4rFoVH1pjAToYwBrHSxcrBIGQuXrQMtD5U1b0U2XVgKZCTLLP8u2Qxqhy3l2Vg==} - dev: true + is-alphabetical@1.0.4: {} - /is-alphanumerical@1.0.4: - resolution: {integrity: sha512-UzoZUr+XfVz3t3v4KyGEniVL9BDRoQtY7tOyrRybkVNjDFWyo1yhXNGrrBTQxp3ib9BLAWs7k2YKBQsFRkZG9A==} + is-alphanumerical@1.0.4: dependencies: is-alphabetical: 1.0.4 is-decimal: 1.0.4 - dev: true - /is-array-buffer@3.0.4: - resolution: {integrity: sha512-wcjaerHw0ydZwfhiKbXJWLDY8A7yV7KhjQOpb83hGgGfId/aQa4TOvwyzn2PuswW2gPCYEL/nEAiSVpdOj1lXw==} - engines: {node: '>= 0.4'} + is-array-buffer@3.0.4: dependencies: call-bind: 1.0.7 get-intrinsic: 1.2.4 - dev: true - /is-arrayish@0.2.1: - resolution: {integrity: sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==} - dev: true + is-arrayish@0.2.1: {} - /is-arrayish@0.3.2: - resolution: {integrity: sha512-eVRqCvVlZbuw3GrM63ovNSNAeA1K16kaR/LRY/92w0zxQ5/1YzwblUX652i4Xs9RwAGjW9d9y6X88t8OaAJfWQ==} + is-arrayish@0.3.2: {} - /is-async-function@2.0.0: - resolution: {integrity: sha512-Y1JXKrfykRJGdlDwdKlLpLyMIiWqWvuSd17TvZk68PLAOGOoF4Xyav1z0Xhoi+gCYjZVeC5SI+hYFOfvXmGRCA==} - engines: {node: '>= 0.4'} + is-async-function@2.0.0: dependencies: has-tostringtag: 1.0.2 - dev: true - /is-bigint@1.0.4: - resolution: {integrity: sha512-zB9CruMamjym81i2JZ3UMn54PKGsQzsJeo6xvN3HJJ4CAsQNB6iRutp2To77OfCNuoxspsIhzaPoO1zyCEhFOg==} + is-bigint@1.0.4: dependencies: has-bigints: 1.0.2 - dev: true - /is-binary-path@2.1.0: - resolution: {integrity: sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==} - engines: {node: '>=8'} + is-binary-path@2.1.0: dependencies: binary-extensions: 2.2.0 - dev: true - /is-boolean-object@1.1.2: - resolution: {integrity: sha512-gDYaKHJmnj4aWxyj6YHyXVpdQawtVLHU5cb+eztPGczf6cjuTdwve5ZIEfgXqH4e57An1D1AKf8CZ3kYrQRqYA==} - engines: {node: '>= 0.4'} + is-boolean-object@1.1.2: dependencies: call-bind: 1.0.7 has-tostringtag: 1.0.0 - dev: true - /is-buffer@2.0.5: - resolution: {integrity: sha512-i2R6zNFDwgEHJyQUtJEk0XFi1i0dPFn/oqjK3/vPCcDeJvW5NQ83V8QbicfF1SupOaB0h8ntgBC2YiE7dfyctQ==} - engines: {node: '>=4'} - dev: true + is-buffer@2.0.5: {} - /is-builtin-module@3.2.1: - resolution: {integrity: sha512-BSLE3HnV2syZ0FK0iMA/yUGplUeMmNz4AW5fnTunbCIqZi4vG3WjJT9FHMy5D69xmAYBHXQhJdALdpwVxV501A==} - engines: {node: '>=6'} + is-builtin-module@3.2.1: dependencies: builtin-modules: 3.3.0 - dev: true - /is-callable@1.2.7: - resolution: {integrity: sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==} - engines: {node: '>= 0.4'} - dev: true + is-callable@1.2.7: {} - /is-ci@3.0.1: - resolution: {integrity: sha512-ZYvCgrefwqoQ6yTyYUbQu64HsITZ3NfKX1lzaEYdkTDcfKzzCI/wthRRYKkdjHKFVgNiXKAKm65Zo1pk2as/QQ==} - hasBin: true + is-ci@3.0.1: dependencies: ci-info: 3.8.0 - dev: true - /is-core-module@2.12.1: - resolution: {integrity: sha512-Q4ZuBAe2FUsKtyQJoQHlvP8OvBERxO3jEmy1I7hcRXcJBGGHFh/aJBswbXuS9sgrDH2QUO8ilkwNPHvHMd8clg==} + is-core-module@2.12.1: dependencies: has: 1.0.3 - dev: true - /is-core-module@2.13.1: - resolution: {integrity: sha512-hHrIjvZsftOsvKSn2TRYl63zvxsgE0K+0mYMoH6gD4omR5IWB2KynivBQczo3+wF1cCkjzvptnI9Q0sPU66ilw==} + is-core-module@2.13.1: dependencies: hasown: 2.0.2 - /is-data-view@1.0.1: - resolution: {integrity: sha512-AHkaJrsUVW6wq6JS8y3JnM/GJF/9cf+k20+iDzlSaJrinEo5+7vRiteOSwBhHRiAyQATN1AmY4hwzxJKPmYf+w==} - engines: {node: '>= 0.4'} + is-data-view@1.0.1: dependencies: is-typed-array: 1.1.13 - dev: true - /is-date-object@1.0.5: - resolution: {integrity: sha512-9YQaSxsAiSwcvS33MBk3wTCVnWK+HhF8VZR2jRxehM16QcVOdHqPn4VPHmRK4lSr38n9JriurInLcP90xsYNfQ==} - engines: {node: '>= 0.4'} + is-date-object@1.0.5: dependencies: has-tostringtag: 1.0.0 - dev: true - /is-decimal@1.0.4: - resolution: {integrity: sha512-RGdriMmQQvZ2aqaQq3awNA6dCGtKpiDFcOzrTWrDAT2MiWrKQVPmxLGHl7Y2nNu6led0kEyoX0enY0qXYsv9zw==} - dev: true + is-decimal@1.0.4: {} - /is-extglob@2.1.1: - resolution: {integrity: sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==} - engines: {node: '>=0.10.0'} - dev: true + is-extglob@2.1.1: {} - /is-finalizationregistry@1.0.2: - resolution: {integrity: sha512-0by5vtUJs8iFQb5TYUHHPudOR+qXYIMKtiUzvLIZITZUjknFmziyBJuLhVRc+Ds0dREFlskDNJKYIdIzu/9pfw==} + is-finalizationregistry@1.0.2: dependencies: call-bind: 1.0.7 - dev: true - /is-fullwidth-code-point@3.0.0: - resolution: {integrity: sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==} - engines: {node: '>=8'} + is-fullwidth-code-point@3.0.0: {} - /is-fullwidth-code-point@4.0.0: - resolution: {integrity: sha512-O4L094N2/dZ7xqVdrXhh9r1KODPJpFms8B5sGdJLPy664AgvXsreZUyCQQNItZRDlYug4xStLjNp/sz3HvBowQ==} - engines: {node: '>=12'} - dev: true + is-fullwidth-code-point@4.0.0: {} - /is-generator-fn@2.1.0: - resolution: {integrity: sha512-cTIB4yPYL/Grw0EaSzASzg6bBy9gqCofvWN8okThAYIxKJZC+udlRAmGbM0XLeniEJSs8uEgHPGuHSe1XsOLSQ==} - engines: {node: '>=6'} - dev: true + is-generator-fn@2.1.0: {} - /is-generator-function@1.0.10: - resolution: {integrity: sha512-jsEjy9l3yiXEQ+PsXdmBwEPcOxaXWLspKdplFUVI9vq1iZgIekeC0L167qeu86czQaxed3q/Uzuw0swL0irL8A==} - engines: {node: '>= 0.4'} + is-generator-function@1.0.10: dependencies: has-tostringtag: 1.0.0 - /is-get-set-prop@1.0.0: - resolution: {integrity: sha512-DvAYZ1ZgGUz4lzxKMPYlt08qAUqyG9ckSg2pIjfvcQ7+pkVNUHk8yVLXOnCLe5WKXhLop8oorWFBJHpwWQpszQ==} + is-get-set-prop@1.0.0: dependencies: get-set-props: 0.1.0 lowercase-keys: 1.0.1 - dev: true - /is-glob@4.0.3: - resolution: {integrity: sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==} - engines: {node: '>=0.10.0'} + is-glob@4.0.3: dependencies: is-extglob: 2.1.1 - dev: true - /is-hexadecimal@1.0.4: - resolution: {integrity: sha512-gyPJuv83bHMpocVYoqof5VDiZveEoGoFL8m3BXNb2VW8Xs+rz9kqO8LOQ5DH6EsuvilT1ApazU0pyl+ytbPtlw==} - dev: true + is-hexadecimal@1.0.4: {} - /is-interactive@2.0.0: - resolution: {integrity: sha512-qP1vozQRI+BMOPcjFzrjXuQvdak2pHNUMZoeG2eRbiSqyvbEf/wQtEOTOX1guk6E3t36RkaqiSt8A/6YElNxLQ==} - engines: {node: '>=12'} - dev: false + is-interactive@2.0.0: {} - /is-js-type@2.0.0: - resolution: {integrity: sha512-Aj13l47+uyTjlQNHtXBV8Cji3jb037vxwMWCgopRR8h6xocgBGW3qG8qGlIOEmbXQtkKShKuBM9e8AA1OeQ+xw==} + is-js-type@2.0.0: dependencies: js-types: 1.0.0 - dev: true - /is-json@2.0.1: - resolution: {integrity: sha512-6BEnpVn1rcf3ngfmViLM6vjUjGErbdrL4rwlv+u1NO1XO8kqT4YGL8+19Q+Z/bas8tY90BTWMk2+fW1g6hQjbA==} - dev: true + is-json@2.0.1: {} - /is-map@2.0.3: - resolution: {integrity: sha512-1Qed0/Hr2m+YqxnM09CjA2d/i6YZNfF6R2oRAOj36eUdS6qIV/huPJNSEpKbupewFs+ZsJlxsjjPbc0/afW6Lw==} - engines: {node: '>= 0.4'} - dev: true + is-map@2.0.3: {} - /is-module@1.0.0: - resolution: {integrity: sha512-51ypPSPCoTEIN9dy5Oy+h4pShgJmPCygKfyRCISBI+JoWT/2oJvK8QPxmwv7b/p239jXrm9M1mlQbyKJ5A152g==} - dev: true + is-module@1.0.0: {} - /is-negative-zero@2.0.2: - resolution: {integrity: sha512-dqJvarLawXsFbNDeJW7zAz8ItJ9cd28YufuuFzh0G8pNHjJMnY08Dv7sYX2uF5UpQOwieAeOExEYAWWfu7ZZUA==} - engines: {node: '>= 0.4'} - dev: true + is-negative-zero@2.0.2: {} - /is-negative-zero@2.0.3: - resolution: {integrity: sha512-5KoIu2Ngpyek75jXodFvnafB6DJgr3u8uuK0LEZJjrU19DrMD3EVERaR8sjz8CCGgpZvxPl9SuE1GMVPFHx1mw==} - engines: {node: '>= 0.4'} - dev: true + is-negative-zero@2.0.3: {} - /is-number-object@1.0.7: - resolution: {integrity: sha512-k1U0IRzLMo7ZlYIfzRu23Oh6MiIFasgpb9X76eqfFZAqwH44UI4KTBvBYIZ1dSL9ZzChTB9ShHfLkR4pdW5krQ==} - engines: {node: '>= 0.4'} + is-number-object@1.0.7: dependencies: has-tostringtag: 1.0.0 - dev: true - /is-number@7.0.0: - resolution: {integrity: sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==} - engines: {node: '>=0.12.0'} - dev: true + is-number@7.0.0: {} - /is-obj-prop@1.0.0: - resolution: {integrity: sha512-5Idb61slRlJlsAzi0Wsfwbp+zZY+9LXKUAZpvT/1ySw+NxKLRWfa0Bzj+wXI3fX5O9hiddm5c3DAaRSNP/yl2w==} + is-obj-prop@1.0.0: dependencies: lowercase-keys: 1.0.1 obj-props: 1.4.0 - dev: true - /is-obj@2.0.0: - resolution: {integrity: sha512-drqDG3cbczxxEJRoOXcOjtdp1J/lyp1mNn0xaznRs8+muBhgQcrnbspox5X5fOw0HnMnbfDzvnEMEtqDEJEo8w==} - engines: {node: '>=8'} - dev: true + is-obj@2.0.0: {} - /is-path-inside@3.0.3: - resolution: {integrity: sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==} - engines: {node: '>=8'} - dev: true + is-path-inside@3.0.3: {} - /is-plain-obj@1.1.0: - resolution: {integrity: sha512-yvkRyxmFKEOQ4pNXCmJG5AEQNlXJS5LaONXo5/cLdTZdWvsZ1ioJEonLGAosKlMWE8lwUy/bJzMjcw8az73+Fg==} - engines: {node: '>=0.10.0'} - dev: true + is-plain-obj@1.1.0: {} - /is-plain-obj@2.1.0: - resolution: {integrity: sha512-YWnfyRwxL/+SsrWYfOpUtz5b3YD+nyfkHvjbcanzk8zgyO4ASD67uVMRt8k5bM4lLMDnXfriRhOpemw+NfT1eA==} - engines: {node: '>=8'} - dev: true + is-plain-obj@2.1.0: {} - /is-plain-obj@4.1.0: - resolution: {integrity: sha512-+Pgi+vMuUNkJyExiMBt5IlFoMyKnr5zhJ4Uspz58WOhBF5QoIZkFyNHIbBAtHwzVAgk5RtndVNsDRN61/mmDqg==} - engines: {node: '>=12'} - dev: true + is-plain-obj@4.1.0: {} - /is-plain-object@5.0.0: - resolution: {integrity: sha512-VRSzKkbMm5jMDoKLbltAkFQ5Qr7VDiTFGXxYFXXowVj387GeGNOCsOH6Msy00SGZ3Fp84b1Naa1psqgcCIEP5Q==} - engines: {node: '>=0.10.0'} - dev: true + is-plain-object@5.0.0: {} - /is-potential-custom-element-name@1.0.1: - resolution: {integrity: sha512-bCYeRA2rVibKZd+s2625gGnGF/t7DSqDs4dP7CrLA1m7jKWz6pps0LpYLJN8Q64HtmPKJ1hrN3nzPNKFEKOUiQ==} - dev: true + is-potential-custom-element-name@1.0.1: {} - /is-proto-prop@2.0.0: - resolution: {integrity: sha512-jl3NbQ/fGLv5Jhan4uX+Ge9ohnemqyblWVVCpAvtTQzNFvV2xhJq+esnkIbYQ9F1nITXoLfDDQLp7LBw/zzncg==} + is-proto-prop@2.0.0: dependencies: lowercase-keys: 1.0.1 proto-props: 2.0.0 - dev: true - /is-reference@1.2.1: - resolution: {integrity: sha512-U82MsXXiFIrjCK4otLT+o2NA2Cd2g5MLoOVXUZjIOhLurrRxpEXzI8O0KZHr3IjLvlAH1kTPYSuqer5T9ZVBKQ==} + is-reference@1.2.1: dependencies: '@types/estree': 1.0.5 - dev: true - /is-regex@1.1.4: - resolution: {integrity: sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg==} - engines: {node: '>= 0.4'} + is-regex@1.1.4: dependencies: call-bind: 1.0.7 has-tostringtag: 1.0.0 - dev: true - /is-set@2.0.3: - resolution: {integrity: sha512-iPAjerrse27/ygGLxw+EBR9agv9Y6uLeYVJMu+QNCoouJ1/1ri0mGrcWpfCqFZuzzx3WjtwxG098X+n4OuRkPg==} - engines: {node: '>= 0.4'} - dev: true + is-set@2.0.3: {} - /is-shared-array-buffer@1.0.2: - resolution: {integrity: sha512-sqN2UDu1/0y6uvXyStCOzyhAjCSlHceFoMKJW8W9EU9cvic/QdsZ0kEU93HEy3IUEFZIiH/3w+AH/UQbPHNdhA==} + is-shared-array-buffer@1.0.2: dependencies: call-bind: 1.0.7 - dev: true - /is-shared-array-buffer@1.0.3: - resolution: {integrity: sha512-nA2hv5XIhLR3uVzDDfCIknerhx8XUKnstuOERPNNIinXG7v9u+ohXF67vxm4TPTEPU6lm61ZkwP3c9PCB97rhg==} - engines: {node: '>= 0.4'} + is-shared-array-buffer@1.0.3: dependencies: call-bind: 1.0.7 - dev: true - /is-stream@2.0.1: - resolution: {integrity: sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==} - engines: {node: '>=8'} + is-stream@2.0.1: {} - /is-stream@3.0.0: - resolution: {integrity: sha512-LnQR4bZ9IADDRSkvpqMGvt/tEJWclzklNgSw48V5EAaAeDd6qGvN8ei6k5p0tvxSR171VmGyHuTiAOfxAbr8kA==} - engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} - dev: true + is-stream@3.0.0: {} - /is-string@1.0.7: - resolution: {integrity: sha512-tE2UXzivje6ofPW7l23cjDOMa09gb7xlAqG6jG5ej6uPV32TlWP3NKPigtaGeHNu9fohccRYvIiZMfOOnOYUtg==} - engines: {node: '>= 0.4'} + is-string@1.0.7: dependencies: has-tostringtag: 1.0.0 - dev: true - /is-subdir@1.2.0: - resolution: {integrity: sha512-2AT6j+gXe/1ueqbW6fLZJiIw3F8iXGJtt0yDrZaBhAZEG1raiTxKWU+IPqMCzQAXOUCKdA4UDMgacKH25XG2Cw==} - engines: {node: '>=4'} + is-subdir@1.2.0: dependencies: better-path-resolve: 1.0.0 - dev: true - /is-symbol@1.0.4: - resolution: {integrity: sha512-C/CPBqKWnvdcxqIARxyOh4v1UUEOCHpgDa0WYgpKDFMszcrPcffg5uhwSgPCLD2WWxmq6isisz87tzT01tuGhg==} - engines: {node: '>= 0.4'} + is-symbol@1.0.4: dependencies: has-symbols: 1.0.3 - dev: true - /is-text-path@2.0.0: - resolution: {integrity: sha512-+oDTluR6WEjdXEJMnC2z6A4FRwFoYuvShVVEGsS7ewc0UTi2QtAKMDJuL4BDEVt+5T7MjFo12RP8ghOM75oKJw==} - engines: {node: '>=8'} + is-text-path@2.0.0: dependencies: text-extensions: 2.4.0 - dev: true - /is-typed-array@1.1.13: - resolution: {integrity: sha512-uZ25/bUAlUY5fR4OKT4rZQEBrzQWYV9ZJYGGsUmEJ6thodVJ1HX64ePQ6Z0qPWP+m+Uq6e9UugrE38jeYsDSMw==} - engines: {node: '>= 0.4'} + is-typed-array@1.1.13: dependencies: which-typed-array: 1.1.15 - dev: true - /is-unicode-supported@1.3.0: - resolution: {integrity: sha512-43r2mRvz+8JRIKnWJ+3j8JtjRKZ6GmjzfaE/qiBJnikNnYv/6bagRJ1kUhNk8R5EX/GkobD+r+sfxCPJsiKBLQ==} - engines: {node: '>=12'} - dev: false + is-unicode-supported@1.3.0: {} - /is-unicode-supported@2.0.0: - resolution: {integrity: sha512-FRdAyx5lusK1iHG0TWpVtk9+1i+GjrzRffhDg4ovQ7mcidMQ6mj+MhKPmvh7Xwyv5gIS06ns49CA7Sqg7lC22Q==} - engines: {node: '>=18'} - dev: false + is-unicode-supported@2.0.0: {} - /is-weakmap@2.0.2: - resolution: {integrity: sha512-K5pXYOm9wqY1RgjpL3YTkF39tni1XajUIkawTLUo9EZEVUFga5gSQJF8nNS7ZwJQ02y+1YCNYcMh+HIf1ZqE+w==} - engines: {node: '>= 0.4'} - dev: true + is-weakmap@2.0.2: {} - /is-weakref@1.0.2: - resolution: {integrity: sha512-qctsuLZmIQ0+vSSMfoVvyFe2+GSEvnmZ2ezTup1SBse9+twCCeial6EEi3Nc2KFcf6+qz2FBPnjXsk8xhKSaPQ==} + is-weakref@1.0.2: dependencies: call-bind: 1.0.7 - dev: true - /is-weakset@2.0.3: - resolution: {integrity: sha512-LvIm3/KWzS9oRFHugab7d+M/GcBXuXX5xZkzPmN+NxihdQlZUQ4dWuSV1xR/sq6upL1TJEDrfBgRepHFdBtSNQ==} - engines: {node: '>= 0.4'} + is-weakset@2.0.3: dependencies: call-bind: 1.0.7 get-intrinsic: 1.2.4 - dev: true - /is-whitespace-character@1.0.4: - resolution: {integrity: sha512-SDweEzfIZM0SJV0EUga669UTKlmL0Pq8Lno0QDQsPnvECB3IM2aP0gdx5TrU0A01MAPfViaZiI2V1QMZLaKK5w==} - dev: true + is-whitespace-character@1.0.4: {} - /is-windows@0.2.0: - resolution: {integrity: sha512-n67eJYmXbniZB7RF4I/FTjK1s6RPOCTxhYrVYLRaCt3lF0mpWZPKr3T2LSZAqyjQsxR2qMmGYXXzK0YWwcPM1Q==} - engines: {node: '>=0.10.0'} - dev: true + is-windows@0.2.0: {} - /is-windows@1.0.2: - resolution: {integrity: sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA==} - engines: {node: '>=0.10.0'} - dev: true + is-windows@1.0.2: {} - /is-word-character@1.0.4: - resolution: {integrity: sha512-5SMO8RVennx3nZrqtKwCGyyetPE9VDba5ugvKLaD4KopPG5kR4mQ7tNt/r7feL5yt5h3lpuBbIUmCOG2eSzXHA==} - dev: true + is-word-character@1.0.4: {} - /isarray@0.0.1: - resolution: {integrity: sha512-D2S+3GLxWH+uhrNEcoh/fnmYeP8E8/zHl644d/jdA0g2uyXvy3sb0qxotE+ne0LtccHknQzWwZEzhak7oJ0COQ==} + isarray@0.0.1: {} - /isarray@2.0.5: - resolution: {integrity: sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==} - dev: true + isarray@2.0.5: {} - /isexe@2.0.0: - resolution: {integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==} + isexe@2.0.0: {} - /iso8601-duration@2.1.2: - resolution: {integrity: sha512-yXteYUiKv6x8seaDzyBwnZtPpmx766KfvQuaVNyPifYOjmPdOo3ajd4phDNa7Y5mTQGnXsNEcXFtVun1FjYXxQ==} + iso8601-duration@2.1.2: {} - /istanbul-lib-coverage@3.2.2: - resolution: {integrity: sha512-O8dpsF+r0WV/8MNRKfnmrtCWhuKjxrq2w+jpzBL5UZKTi2LeVWnWOmWRxFlesJONmc+wLAGvKQZEOanko0LFTg==} - engines: {node: '>=8'} - dev: true + istanbul-lib-coverage@3.2.2: {} - /istanbul-lib-instrument@5.2.1: - resolution: {integrity: sha512-pzqtp31nLv/XFOzXGuvhCb8qhjmTVo5vjVk19XE4CRlSWz0KoeJ3bw9XsA7nOp9YBf4qHjwBxkDzKcME/J29Yg==} - engines: {node: '>=8'} + istanbul-lib-instrument@5.2.1: dependencies: '@babel/core': 7.24.4 '@babel/parser': 7.24.4 @@ -14992,11 +19824,8 @@ packages: semver: 6.3.1 transitivePeerDependencies: - supports-color - dev: true - /istanbul-lib-instrument@6.0.1: - resolution: {integrity: sha512-EAMEJBsYuyyztxMxW3g7ugGPkrZsV57v0Hmv3mm1uQsmB+QnZuepg731CRaIgeUVSdmsTngOkSnauNF8p7FIhA==} - engines: {node: '>=10'} + istanbul-lib-instrument@6.0.1: dependencies: '@babel/core': 7.24.4 '@babel/parser': 7.24.4 @@ -15005,78 +19834,55 @@ packages: semver: 7.6.0 transitivePeerDependencies: - supports-color - dev: true - /istanbul-lib-report@3.0.1: - resolution: {integrity: sha512-GCfE1mtsHGOELCU8e/Z7YWzpmybrx/+dSTfLrvY8qRmaY6zXTKWn6WQIjaAFw069icm6GVMNkgu0NzI4iPZUNw==} - engines: {node: '>=10'} + istanbul-lib-report@3.0.1: 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: - resolution: {integrity: sha512-n3s8EwkdFIJCG3BPKBYvskgXGoy88ARzvegkitk60NxRdwltLOTaH7CUiMRXvwYorl0Q712iEjcWB+fK/MrWVw==} - engines: {node: '>=10'} + istanbul-lib-source-maps@4.0.1: dependencies: debug: 4.3.4 istanbul-lib-coverage: 3.2.2 source-map: 0.6.1 transitivePeerDependencies: - supports-color - dev: true - /istanbul-lib-source-maps@5.0.4: - resolution: {integrity: sha512-wHOoEsNJTVltaJp8eVkm8w+GVkVNHT2YDYo53YdzQEL2gWm1hBX5cGFR9hQJtuGLebidVX7et3+dmDZrmclduw==} - engines: {node: '>=10'} + istanbul-lib-source-maps@5.0.4: 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.7: - resolution: {integrity: sha512-BewmUXImeuRk2YY0PVbxgKAysvhRPUQE0h5QRM++nVWyubKGV0l8qQ5op8+B2DOmwSe63Jivj0BjkPQVf8fP5g==} - engines: {node: '>=8'} + istanbul-reports@3.1.7: dependencies: html-escaper: 2.0.2 istanbul-lib-report: 3.0.1 - dev: true - /iterator.prototype@1.1.2: - resolution: {integrity: sha512-DR33HMMr8EzwuRL8Y9D3u2BMj8+RqSE850jfGu59kS7tbmPLzGkZmVSfyCFSDxuZiEY6Rzt3T2NA/qU+NwVj1w==} + iterator.prototype@1.1.2: dependencies: define-properties: 1.2.1 get-intrinsic: 1.2.4 has-symbols: 1.0.3 reflect.getprototypeof: 1.0.6 set-function-name: 2.0.2 - dev: true - /jackspeak@2.3.6: - resolution: {integrity: sha512-N3yCS/NegsOBokc8GAdM8UcmfsKiSS8cipheD/nivzr700H+nsMOxJjQnvwOcRYVuFkdH0wGUvW2WbXGmrZGbQ==} - engines: {node: '>=14'} + jackspeak@2.3.6: dependencies: '@isaacs/cliui': 8.0.2 optionalDependencies: '@pkgjs/parseargs': 0.11.0 - dev: false - /jest-changed-files@29.7.0: - resolution: {integrity: sha512-fEArFiwf1BpQ+4bXSprcDc3/x4HSzL4al2tozwVpDFpsxALjLYdyiIK4e5Vz66GQJIbXJ82+35PtysofptNX2w==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + jest-changed-files@29.7.0: dependencies: execa: 5.1.1 jest-util: 29.7.0 p-limit: 3.1.0 - dev: true - /jest-circus@29.7.0: - resolution: {integrity: sha512-3E1nCMgipcTkCocFwM90XXQab9bS+GMsjdpmPrlelaxwD93Ad8iVEjX/vvHPdLPnFf+L40u+5+iutRdA1N9myw==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + jest-circus@29.7.0: dependencies: '@jest/environment': 29.7.0 '@jest/expect': 29.7.0 @@ -15101,17 +19907,8 @@ packages: transitivePeerDependencies: - babel-plugin-macros - supports-color - dev: true - /jest-cli@29.7.0(@types/node@20.10.4): - resolution: {integrity: sha512-OVVobw2IubN/GSYsxETi+gOe7Ka59EFMR/twOU3Jb2GnKKeMGJB5SGUUrEz3SFVmJASUdZUzy83sLNNQ2gZslg==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - hasBin: true - peerDependencies: - node-notifier: ^8.0.1 || ^9.0.0 || ^10.0.0 - peerDependenciesMeta: - node-notifier: - optional: true + jest-cli@29.7.0(@types/node@20.10.4): dependencies: '@jest/core': 29.7.0(ts-node@10.9.2) '@jest/test-result': 29.7.0 @@ -15129,17 +19926,8 @@ packages: - babel-plugin-macros - supports-color - ts-node - dev: true - /jest-cli@29.7.0(@types/node@20.12.7): - resolution: {integrity: sha512-OVVobw2IubN/GSYsxETi+gOe7Ka59EFMR/twOU3Jb2GnKKeMGJB5SGUUrEz3SFVmJASUdZUzy83sLNNQ2gZslg==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - hasBin: true - peerDependencies: - node-notifier: ^8.0.1 || ^9.0.0 || ^10.0.0 - peerDependenciesMeta: - node-notifier: - optional: true + jest-cli@29.7.0(@types/node@20.12.7): dependencies: '@jest/core': 29.7.0(ts-node@10.9.2) '@jest/test-result': 29.7.0 @@ -15157,17 +19945,8 @@ packages: - babel-plugin-macros - supports-color - ts-node - dev: true - /jest-cli@29.7.0(@types/node@20.12.7)(ts-node@10.9.2): - resolution: {integrity: sha512-OVVobw2IubN/GSYsxETi+gOe7Ka59EFMR/twOU3Jb2GnKKeMGJB5SGUUrEz3SFVmJASUdZUzy83sLNNQ2gZslg==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - hasBin: true - peerDependencies: - node-notifier: ^8.0.1 || ^9.0.0 || ^10.0.0 - peerDependenciesMeta: - node-notifier: - optional: true + jest-cli@29.7.0(@types/node@20.12.7)(ts-node@10.9.2): dependencies: '@jest/core': 29.7.0(ts-node@10.9.2) '@jest/test-result': 29.7.0 @@ -15185,19 +19964,8 @@ packages: - babel-plugin-macros - supports-color - ts-node - dev: true - /jest-config@29.7.0(@types/node@20.10.4): - resolution: {integrity: sha512-uXbpfeQ7R6TZBqI3/TxCU4q4ttk3u0PJeC+E0zbfSoSjq6bJ7buBPxzQPL0ifrkY4DNu4JUdk0ImlBUYi840eQ==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - peerDependencies: - '@types/node': '*' - ts-node: '>=9.0.0' - peerDependenciesMeta: - '@types/node': - optional: true - ts-node: - optional: true + jest-config@29.7.0(@types/node@20.10.4): dependencies: '@babel/core': 7.24.4 '@jest/test-sequencer': 29.7.0 @@ -15225,19 +19993,8 @@ packages: transitivePeerDependencies: - babel-plugin-macros - supports-color - dev: true - /jest-config@29.7.0(@types/node@20.12.7)(ts-node@10.9.2): - resolution: {integrity: sha512-uXbpfeQ7R6TZBqI3/TxCU4q4ttk3u0PJeC+E0zbfSoSjq6bJ7buBPxzQPL0ifrkY4DNu4JUdk0ImlBUYi840eQ==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - peerDependencies: - '@types/node': '*' - ts-node: '>=9.0.0' - peerDependenciesMeta: - '@types/node': - optional: true - ts-node: - optional: true + jest-config@29.7.0(@types/node@20.12.7)(ts-node@10.9.2): dependencies: '@babel/core': 7.24.4 '@jest/test-sequencer': 29.7.0 @@ -15266,11 +20023,8 @@ packages: transitivePeerDependencies: - babel-plugin-macros - supports-color - dev: true - /jest-dev-server@10.0.0: - resolution: {integrity: sha512-FtyBBDxrAIfTX3hyKSOwj5KU6Z7fFLew5pQYOFpwyf+qpPpULL8aYxtsFkbkAwcs+Mb7qhcNbVLeiWsLOd7CKw==} - engines: {node: '>=16'} + jest-dev-server@10.0.0: dependencies: chalk: 4.1.2 cwd: 0.10.0 @@ -15282,44 +20036,27 @@ packages: transitivePeerDependencies: - debug - supports-color - dev: true - /jest-diff@29.7.0: - resolution: {integrity: sha512-LMIgiIrhigmPrs03JHpxUh2yISK3vLFPkAodPeo0+BuF7wA2FoQbkEg1u8gBYBThncu7e1oEDUfIXVuTqLRUjw==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + jest-diff@29.7.0: dependencies: chalk: 4.1.2 diff-sequences: 29.6.3 jest-get-type: 29.6.3 pretty-format: 29.7.0 - dev: true - /jest-docblock@29.7.0: - resolution: {integrity: sha512-q617Auw3A612guyaFgsbFeYpNP5t2aoUNLwBUbc/0kD1R4t9ixDbyFTHd1nok4epoVFpr7PmeWHrhvuV3XaJ4g==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + jest-docblock@29.7.0: dependencies: detect-newline: 3.1.0 - dev: true - /jest-each@29.7.0: - resolution: {integrity: sha512-gns+Er14+ZrEoC5fhOfYCY1LOHHr0TI+rQUHZS8Ttw2l7gl+80eHc/gFf2Ktkw0+SIACDTeWvpFcv3B04VembQ==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + jest-each@29.7.0: dependencies: '@jest/types': 29.6.3 chalk: 4.1.2 jest-get-type: 29.6.3 jest-util: 29.7.0 pretty-format: 29.7.0 - dev: true - /jest-environment-jsdom@29.2.2: - resolution: {integrity: sha512-5mNtTcky1+RYv9kxkwMwt7fkzyX4EJUarV7iI+NQLigpV4Hz4sgfOdP4kOpCHXbkRWErV7tgXoXLm2CKtucr+A==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - peerDependencies: - canvas: ^2.5.0 - peerDependenciesMeta: - canvas: - optional: true + jest-environment-jsdom@29.2.2: dependencies: '@jest/environment': 29.5.0 '@jest/fake-timers': 29.5.0 @@ -15333,11 +20070,8 @@ packages: - bufferutil - supports-color - utf-8-validate - dev: true - /jest-environment-node@29.7.0: - resolution: {integrity: sha512-DOSwCRqXirTOyheM+4d5YZOrWcdu0LNZ87ewUoywbcb2XR4wKgqiG8vNeYwhjFMbEkfju7wx2GYH0P2gevGvFw==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + jest-environment-node@29.7.0: dependencies: '@jest/environment': 29.7.0 '@jest/fake-timers': 29.7.0 @@ -15345,11 +20079,8 @@ packages: '@types/node': 20.12.7 jest-mock: 29.7.0 jest-util: 29.7.0 - dev: true - /jest-environment-puppeteer@10.0.1(typescript@5.3.3): - resolution: {integrity: sha512-FxMzVRyqieQqSy5CPWiwdK5t9dkRHid5eoRTVa8RtYeXLlpW6lU0dAmxEfPkdnDVCiPUhC2APeKOXq0J72bgag==} - engines: {node: '>=16'} + jest-environment-puppeteer@10.0.1(typescript@5.3.3): dependencies: chalk: 4.1.2 cosmiconfig: 8.3.6(typescript@5.3.3) @@ -15360,16 +20091,10 @@ packages: - debug - supports-color - typescript - dev: true - /jest-get-type@29.6.3: - resolution: {integrity: sha512-zrteXnqYxfQh7l5FHyL38jL39di8H8rHoecLH3JNxH3BwOrBsNeabdap5e0I23lD4HHI8W5VFBZqG4Eaq5LNcw==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - dev: true + jest-get-type@29.6.3: {} - /jest-haste-map@29.5.0: - resolution: {integrity: sha512-IspOPnnBro8YfVYSw6yDRKh/TiCdRngjxeacCps1cQ9cgVN6+10JUcuJ1EabrgYLOATsIAigxA0rLR9x/YlrSA==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + jest-haste-map@29.5.0: dependencies: '@jest/types': 29.6.3 '@types/graceful-fs': 4.1.5 @@ -15384,11 +20109,8 @@ packages: walker: 1.0.8 optionalDependencies: fsevents: 2.3.3 - dev: true - /jest-haste-map@29.7.0: - resolution: {integrity: sha512-fP8u2pyfqx0K1rGn1R9pyE0/KTn+G7PxktWidOBTqFPLYX0b9ksaMFkhK5vrS3DVun09pckLdlx90QthlW7AmA==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + jest-haste-map@29.7.0: dependencies: '@jest/types': 29.6.3 '@types/graceful-fs': 4.1.5 @@ -15403,33 +20125,22 @@ packages: walker: 1.0.8 optionalDependencies: fsevents: 2.3.3 - dev: true - /jest-leak-detector@29.7.0: - resolution: {integrity: sha512-kYA8IJcSYtST2BY9I+SMC32nDpBT3J2NvWJx8+JCuCdl/CR1I4EKUJROiP8XtCcxqgTTBGJNdbB1A8XRKbTetw==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + jest-leak-detector@29.7.0: dependencies: jest-get-type: 29.6.3 pretty-format: 29.7.0 - dev: true - /jest-matcher-specific-error@1.0.0: - resolution: {integrity: sha512-thJdy9ibhDo8k+0arFalNCQBJ0u7eqTfpTzS2MzL3iCLmbRCkI+yhhKSiAxEi55e5ZUyf01ySa0fMqzF+sblAw==} - dev: true + jest-matcher-specific-error@1.0.0: {} - /jest-matcher-utils@29.7.0: - resolution: {integrity: sha512-sBkD+Xi9DtcChsI3L3u0+N0opgPYnCRPtGcQYrgXmR+hmt/fYfWAL0xRXYU8eWOdfuLgBe0YCW3AFtnRLagq/g==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + jest-matcher-utils@29.7.0: dependencies: chalk: 4.1.2 jest-diff: 29.7.0 jest-get-type: 29.6.3 pretty-format: 29.7.0 - dev: true - /jest-message-util@29.5.0: - resolution: {integrity: sha512-Kijeg9Dag6CKtIDA7O21zNTACqD5MD/8HfIV8pdD94vFyFuer52SigdC3IQMhab3vACxXMiFk+yMHNdbqtyTGA==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + jest-message-util@29.5.0: dependencies: '@babel/code-frame': 7.22.5 '@jest/types': 29.6.3 @@ -15440,11 +20151,8 @@ packages: pretty-format: 29.7.0 slash: 3.0.0 stack-utils: 2.0.5 - dev: true - /jest-message-util@29.7.0: - resolution: {integrity: sha512-GBEV4GRADeP+qtB2+6u61stea8mGcOT4mCtrYISZwfu9/ISHFJ/5zOMXYbpBE9RsS5+Gb63DW4FgmnKJ79Kf6w==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + jest-message-util@29.7.0: dependencies: '@babel/code-frame': 7.22.5 '@jest/types': 29.6.3 @@ -15455,43 +20163,24 @@ packages: pretty-format: 29.7.0 slash: 3.0.0 stack-utils: 2.0.5 - dev: true - /jest-mock@29.5.0: - resolution: {integrity: sha512-GqOzvdWDE4fAV2bWQLQCkujxYWL7RxjCnj71b5VhDAGOevB3qj3Ovg26A5NI84ZpODxyzaozXLOh2NCgkbvyaw==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + jest-mock@29.5.0: dependencies: '@jest/types': 29.6.3 '@types/node': 20.12.7 jest-util: 29.5.0 - dev: true - /jest-mock@29.7.0: - resolution: {integrity: sha512-ITOMZn+UkYS4ZFh83xYAOzWStloNzJFO2s8DWrE4lhtGD+AorgnbkiKERe4wQVBydIGPx059g6riW5Btp6Llnw==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + jest-mock@29.7.0: dependencies: '@jest/types': 29.6.3 '@types/node': 20.12.7 jest-util: 29.7.0 - dev: true - /jest-pnp-resolver@1.2.2(jest-resolve@29.7.0): - resolution: {integrity: sha512-olV41bKSMm8BdnuMsewT4jqlZ8+3TCARAXjZGT9jcoSnrfUnRCqnMoF9XEeoWjbzObpqF9dRhHQj0Xb9QdF6/w==} - engines: {node: '>=6'} - peerDependencies: - jest-resolve: '*' - peerDependenciesMeta: - jest-resolve: - optional: true + jest-pnp-resolver@1.2.2(jest-resolve@29.7.0): dependencies: jest-resolve: 29.7.0 - dev: true - /jest-puppeteer@10.0.1(puppeteer@22.6.5)(typescript@5.3.3): - resolution: {integrity: sha512-FzC35XbqeuQEt1smXh1EOqhJaRkWqJkyWDMfGkcZ8C59QHXeJ7F/iOmiNqYi6l/OsycUuOPCk+IkjfGfS9YbrQ==} - engines: {node: '>=16'} - peerDependencies: - puppeteer: '>=19' + jest-puppeteer@10.0.1(puppeteer@22.6.5)(typescript@5.3.3): dependencies: expect-puppeteer: 10.0.0 jest-environment-puppeteer: 10.0.1(typescript@5.3.3) @@ -15500,31 +20189,19 @@ packages: - debug - supports-color - typescript - dev: true - /jest-regex-util@29.4.3: - resolution: {integrity: sha512-O4FglZaMmWXbGHSQInfXewIsd1LMn9p3ZXB/6r4FOkyhX2/iP/soMG98jGvk/A3HAN78+5VWcBGO0BJAPRh4kg==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - dev: true + jest-regex-util@29.4.3: {} - /jest-regex-util@29.6.3: - resolution: {integrity: sha512-KJJBsRCyyLNWCNBOvZyRDnAIfUiRJ8v+hOBQYGn8gDyF3UegwiP4gwRR3/SDa42g1YbVycTidUF3rKjyLFDWbg==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - dev: true + jest-regex-util@29.6.3: {} - /jest-resolve-dependencies@29.7.0: - resolution: {integrity: sha512-un0zD/6qxJ+S0et7WxeI3H5XSe9lTBBR7bOHCHXkKR6luG5mwDDlIzVQ0V5cZCuoTgEdcdwzTghYkTWfubi+nA==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + jest-resolve-dependencies@29.7.0: dependencies: jest-regex-util: 29.6.3 jest-snapshot: 29.7.0 transitivePeerDependencies: - supports-color - dev: true - /jest-resolve@29.7.0: - resolution: {integrity: sha512-IOVhZSrg+UvVAshDSDtHyFCCBUl/Q3AAJv8iZ6ZjnZ74xzvwuzLXid9IIIPgTnY62SJjfuupMKZsZQRsCvxEgA==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + jest-resolve@29.7.0: dependencies: chalk: 4.1.2 graceful-fs: 4.2.11 @@ -15535,11 +20212,8 @@ packages: resolve: 1.22.8 resolve.exports: 2.0.1 slash: 3.0.0 - dev: true - /jest-runner@29.7.0: - resolution: {integrity: sha512-fsc4N6cPCAahybGBfTRcq5wFR6fpLznMg47sY5aDpsoejOcVYFb07AHuSnR0liMcPTgBsA3ZJL6kFOjPdoNipQ==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + jest-runner@29.7.0: dependencies: '@jest/console': 29.7.0 '@jest/environment': 29.7.0 @@ -15564,11 +20238,8 @@ packages: source-map-support: 0.5.13 transitivePeerDependencies: - supports-color - dev: true - /jest-runtime@29.7.0: - resolution: {integrity: sha512-gUnLjgwdGqW7B4LvOIkbKs9WGbn+QLqRQQ9juC6HndeDiezIwhDP+mhMwHWCEcfQ5RUXa6OPnFF8BJh5xegwwQ==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + jest-runtime@29.7.0: dependencies: '@jest/environment': 29.7.0 '@jest/fake-timers': 29.7.0 @@ -15594,11 +20265,8 @@ packages: strip-bom: 4.0.0 transitivePeerDependencies: - supports-color - dev: true - /jest-snapshot@29.7.0: - resolution: {integrity: sha512-Rm0BMWtxBcioHr1/OX5YCP8Uov4riHvKPknOGs804Zg9JGZgmIBkbtlxJC/7Z4msKYVbIJtfU+tKb8xlYNfdkw==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + jest-snapshot@29.7.0: dependencies: '@babel/core': 7.24.4 '@babel/generator': 7.20.4 @@ -15622,25 +20290,15 @@ packages: semver: 7.6.0 transitivePeerDependencies: - supports-color - dev: true - /jest-transform-stub@2.0.0: - resolution: {integrity: sha512-lspHaCRx/mBbnm3h4uMMS3R5aZzMwyNpNIJLXj4cEsV0mIUtS4IjYJLSoyjRCtnxb6RIGJ4NL2quZzfIeNhbkg==} - dev: true + jest-transform-stub@2.0.0: {} - /jest-transformer-svg@2.0.0(jest@29.7.0)(react@18.2.0): - resolution: {integrity: sha512-+f6er7UZTiHTeel9nma1i0NTAU8AjbEvhK2RYUoMxTNihwo98z2rrrDBIbppZI6ACDzeul3bhRmI9M6d25J/Nw==} - peerDependencies: - jest: ^28.1.0 || ^29.1.2 - react: ^17.0.0 || ^18.0.0 + jest-transformer-svg@2.0.0(jest@29.7.0)(react@18.2.0): dependencies: jest: 29.7.0(@types/node@20.12.7)(ts-node@10.9.2) react: 18.2.0 - dev: true - /jest-util@29.5.0: - resolution: {integrity: sha512-RYMgG/MTadOr5t8KdhejfvUU82MxsCu5MF6KuDUHl+NuwzUt+Sm6jJWxTJVrDR1j5M/gJVCPKQEpWXY+yIQ6lQ==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + jest-util@29.5.0: dependencies: '@jest/types': 29.6.3 '@types/node': 20.12.7 @@ -15648,11 +20306,8 @@ packages: ci-info: 3.8.0 graceful-fs: 4.2.11 picomatch: 2.3.1 - dev: true - /jest-util@29.7.0: - resolution: {integrity: sha512-z6EbKajIpqGKU56y5KBUgy1dt1ihhQJgWzUlZHArA/+X2ad7Cb5iF+AK1EWVL/Bo7Rz9uurpqw6SiBCefUbCGA==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + jest-util@29.7.0: dependencies: '@jest/types': 29.6.3 '@types/node': 20.12.7 @@ -15660,11 +20315,8 @@ packages: ci-info: 3.8.0 graceful-fs: 4.2.11 picomatch: 2.3.1 - dev: true - /jest-validate@29.7.0: - resolution: {integrity: sha512-ZB7wHqaRGVw/9hST/OuFUReG7M8vKeq0/J2egIGLdvjHCmYqGARhzXmtgi+gVeZ5uXFF219aOc3Ls2yLg27tkw==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + jest-validate@29.7.0: dependencies: '@jest/types': 29.6.3 camelcase: 6.3.0 @@ -15672,11 +20324,8 @@ packages: jest-get-type: 29.6.3 leven: 3.1.0 pretty-format: 29.7.0 - dev: true - /jest-watcher@29.7.0: - resolution: {integrity: sha512-49Fg7WXkU3Vl2h6LbLtMQ/HyB6rXSIX7SqvBLQmssRBGN9I0PNvPmAmCWSOY6SOvrjhI/F7/bGAv9RtnsPA03g==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + jest-watcher@29.7.0: dependencies: '@jest/test-result': 29.7.0 '@jest/types': 29.6.3 @@ -15686,37 +20335,22 @@ packages: emittery: 0.13.1 jest-util: 29.7.0 string-length: 4.0.2 - dev: true - /jest-worker@29.5.0: - resolution: {integrity: sha512-NcrQnevGoSp4b5kg+akIpthoAFHxPBcb5P6mYPY0fUNT+sSvmtu6jlkEle3anczUKIKEbMxFimk9oTP/tpIPgA==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + jest-worker@29.5.0: dependencies: '@types/node': 20.12.7 jest-util: 29.7.0 merge-stream: 2.0.0 supports-color: 8.1.1 - dev: true - /jest-worker@29.7.0: - resolution: {integrity: sha512-eIz2msL/EzL9UFTFFx7jBTkeZfku0yUAyZZZmJ93H2TYEiroIx2PQjEXcwYtYl8zXCxb+PAmA2hLIt/6ZEkPHw==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + jest-worker@29.7.0: dependencies: '@types/node': 20.12.7 jest-util: 29.7.0 merge-stream: 2.0.0 supports-color: 8.1.1 - dev: true - /jest@29.7.0(@types/node@20.10.4): - resolution: {integrity: sha512-NIy3oAFp9shda19hy4HK0HRTWKtPJmGdnvywu01nOqNC2vZg+Z+fvJDxpMQA88eb2I9EcafcdjYgsDthnYTvGw==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - hasBin: true - peerDependencies: - node-notifier: ^8.0.1 || ^9.0.0 || ^10.0.0 - peerDependenciesMeta: - node-notifier: - optional: true + jest@29.7.0(@types/node@20.10.4): dependencies: '@jest/core': 29.7.0(ts-node@10.9.2) '@jest/types': 29.6.3 @@ -15727,17 +20361,8 @@ packages: - babel-plugin-macros - supports-color - ts-node - dev: true - /jest@29.7.0(@types/node@20.12.7): - resolution: {integrity: sha512-NIy3oAFp9shda19hy4HK0HRTWKtPJmGdnvywu01nOqNC2vZg+Z+fvJDxpMQA88eb2I9EcafcdjYgsDthnYTvGw==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - hasBin: true - peerDependencies: - node-notifier: ^8.0.1 || ^9.0.0 || ^10.0.0 - peerDependenciesMeta: - node-notifier: - optional: true + jest@29.7.0(@types/node@20.12.7): dependencies: '@jest/core': 29.7.0(ts-node@10.9.2) '@jest/types': 29.6.3 @@ -15748,17 +20373,8 @@ packages: - babel-plugin-macros - supports-color - ts-node - dev: true - /jest@29.7.0(@types/node@20.12.7)(ts-node@10.9.2): - resolution: {integrity: sha512-NIy3oAFp9shda19hy4HK0HRTWKtPJmGdnvywu01nOqNC2vZg+Z+fvJDxpMQA88eb2I9EcafcdjYgsDthnYTvGw==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - hasBin: true - peerDependencies: - node-notifier: ^8.0.1 || ^9.0.0 || ^10.0.0 - peerDependenciesMeta: - node-notifier: - optional: true + jest@29.7.0(@types/node@20.12.7)(ts-node@10.9.2): dependencies: '@jest/core': 29.7.0(ts-node@10.9.2) '@jest/types': 29.6.3 @@ -15769,73 +20385,41 @@ packages: - babel-plugin-macros - supports-color - ts-node - dev: true - /jiti@1.21.0: - resolution: {integrity: sha512-gFqAIbuKyyso/3G2qhiO2OM6shY6EPP/R0+mkDbyspxKazh8BXDC5FiFsUjlczgdNz/vfra0da2y+aHrusLG/Q==} - hasBin: true - dev: true + jiti@1.21.0: {} - /joi@17.12.2: - resolution: {integrity: sha512-RonXAIzCiHLc8ss3Ibuz45u28GOsWE1UpfDXLbN/9NKbL4tCJf8TWYVKsoYuuh+sAUt7fsSNpA+r2+TBA6Wjmw==} + joi@17.12.2: dependencies: '@hapi/hoek': 9.3.0 '@hapi/topo': 5.1.0 '@sideway/address': 4.1.5 '@sideway/formula': 3.0.1 '@sideway/pinpoint': 2.0.0 - dev: true - /jose@5.0.1: - resolution: {integrity: sha512-gRVzy7s3RRdGbXmcTdlOswJOjhwPLx1ijIgAqLY6ktzFpOJxxYn4l0fC2vHaHHi4YBX/5FOL3aY+6W0cvQgpug==} + jose@5.0.1: {} - /jose@5.2.2: - resolution: {integrity: sha512-/WByRr4jDcsKlvMd1dRJnPfS1GVO3WuKyaurJ/vvXcOaUQO8rnNObCQMlv/5uCceVQIq5Q4WLF44ohsdiTohdg==} + jose@5.2.2: {} - /jose@5.2.4: - resolution: {integrity: sha512-6ScbIk2WWCeXkmzF6bRPmEuaqy1m8SbsRFMa/FLrSCkGIhj8OLVG/IH+XHVmNMx/KUo8cVWEE6oKR4dJ+S0Rkg==} - dev: false + jose@5.2.4: {} - /js-base64@3.7.5: - resolution: {integrity: sha512-3MEt5DTINKqfScXKfJFrRbxkrnk2AxPWGBL/ycjz4dK8iqiSJ06UxD8jh8xuh6p10TX4t2+7FsBYVxxQbMg+qA==} - dev: true + js-base64@3.7.5: {} - /js-tokens@4.0.0: - resolution: {integrity: sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==} - dev: true + js-tokens@4.0.0: {} - /js-tokens@8.0.3: - resolution: {integrity: sha512-UfJMcSJc+SEXEl9lH/VLHSZbThQyLpw1vLO1Lb+j4RWDvG3N2f7yj3PVQA3cmkTBNldJ9eFnM+xEXxHIXrYiJw==} - dev: true + js-tokens@8.0.3: {} - /js-types@1.0.0: - resolution: {integrity: sha512-bfwqBW9cC/Lp7xcRpug7YrXm0IVw+T9e3g4mCYnv0Pjr3zIzU9PCQElYU9oSGAWzXlbdl9X5SAMPejO9sxkeUw==} - engines: {node: '>=0.10.0'} - dev: true + js-types@1.0.0: {} - /js-yaml@3.14.1: - resolution: {integrity: sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==} - hasBin: true + js-yaml@3.14.1: dependencies: argparse: 1.0.10 esprima: 4.0.1 - dev: true - /js-yaml@4.1.0: - resolution: {integrity: sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==} - hasBin: true + js-yaml@4.1.0: dependencies: argparse: 2.0.1 - dev: true - /jsdom@20.0.2: - resolution: {integrity: sha512-AHWa+QO/cgRg4N+DsmHg1Y7xnz+8KU3EflM0LVDTdmrYOc1WWTSkOjtpUveQH+1Bqd5rtcVnb/DuxV/UjDO4rA==} - engines: {node: '>=14'} - peerDependencies: - canvas: ^2.5.0 - peerDependenciesMeta: - canvas: - optional: true + jsdom@20.0.2: dependencies: abab: 2.0.6 acorn: 8.10.0 @@ -15867,93 +20451,51 @@ packages: - bufferutil - supports-color - utf-8-validate - dev: true - /jsesc@0.5.0: - resolution: {integrity: sha512-uZz5UnB7u4T9LvwmFqXii7pZSouaRPorGs5who1Ip7VO0wxanFvBL7GkM6dTHlgX+jhBApRetaWpnDabOeTcnA==} - hasBin: true - dev: true + jsesc@0.5.0: {} - /jsesc@2.5.2: - resolution: {integrity: sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==} - engines: {node: '>=4'} - hasBin: true - dev: true + jsesc@2.5.2: {} - /jsesc@3.0.2: - resolution: {integrity: sha512-xKqzzWXDttJuOcawBt4KnKHHIf5oQ/Cxax+0PWFG+DFDgHNAdi+TXECADI+RYiFUMmx8792xsMbbgXj4CwnP4g==} - engines: {node: '>=6'} - hasBin: true + jsesc@3.0.2: {} - /json-bigint@1.0.0: - resolution: {integrity: sha512-SiPv/8VpZuWbvLSMtTDU8hEfrZWg/mH/nV/b4o0CYbSxu1UIQPLdwKOCIyLQX+VIPO5vrLX3i8qtqFyhdPSUSQ==} + json-bigint@1.0.0: dependencies: bignumber.js: 9.1.2 - dev: false - /json-buffer@3.0.1: - resolution: {integrity: sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==} + json-buffer@3.0.1: {} - /json-parse-even-better-errors@2.3.1: - resolution: {integrity: sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==} - dev: true + json-parse-even-better-errors@2.3.1: {} - /json-schema-traverse@0.4.1: - resolution: {integrity: sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==} + json-schema-traverse@0.4.1: {} - /json-schema-traverse@1.0.0: - resolution: {integrity: sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==} - dev: true + json-schema-traverse@1.0.0: {} - /json-stable-stringify-without-jsonify@1.0.1: - resolution: {integrity: sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==} - dev: true + json-stable-stringify-without-jsonify@1.0.1: {} - /json-stringify-safe@5.0.1: - resolution: {integrity: sha512-ZClg6AaYvamvYEE82d3Iyd3vSSIjQ+odgjaTzRuO3s7toCdFKczob2i0zCh7JE8kWn17yvAWhUVxvqGwUalsRA==} - dev: true + json-stringify-safe@5.0.1: {} - /json5@1.0.2: - resolution: {integrity: sha512-g1MWMLBiz8FKi1e4w0UyVL3w+iJceWAFBAaBnnGKOpNa5f8TLktkbre1+s6oICydWAm+HRUGTmI+//xv2hvXYA==} - hasBin: true + json5@1.0.2: dependencies: minimist: 1.2.8 - dev: true - /json5@2.2.3: - resolution: {integrity: sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==} - engines: {node: '>=6'} - hasBin: true - dev: true + json5@2.2.3: {} - /jsonc-eslint-parser@2.4.0: - resolution: {integrity: sha512-WYDyuc/uFcGp6YtM2H0uKmUwieOuzeE/5YocFJLnLfclZ4inf3mRn8ZVy1s7Hxji7Jxm6Ss8gqpexD/GlKoGgg==} - engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + jsonc-eslint-parser@2.4.0: dependencies: acorn: 8.10.0 eslint-visitor-keys: 3.4.1 espree: 9.6.0 semver: 7.5.2 - dev: true - /jsonc-parser@3.2.0: - resolution: {integrity: sha512-gfFQZrcTc8CnKXp6Y4/CBT3fTc0OVuDofpre4aEeEpSBPV5X5v4+Vmx+8snU7RLPrNHPKSgLxGo9YuQzz20o+w==} - dev: true + jsonc-parser@3.2.0: {} - /jsonfile@4.0.0: - resolution: {integrity: sha512-m6F1R3z8jjlf2imQHS2Qez5sjKWQzbuuhuJ/FKYFRZvPE3PuHcSMVZzfsLhGVOkfd20obL5SWEBew5ShlquNxg==} + jsonfile@4.0.0: optionalDependencies: graceful-fs: 4.2.11 - dev: true - /jsonparse@1.3.1: - resolution: {integrity: sha512-POQXvpdL69+CluYsillJ7SUhKvytYjW9vG/GKpnf+xP8UWgYEM/RaMzHHofbALDiKbbP1W8UEYmgGl39WkPZsg==} - engines: {'0': node >= 0.2.0} - dev: true + jsonparse@1.3.1: {} - /jsonwebtoken@9.0.2: - resolution: {integrity: sha512-PRp66vJ865SSqOlgqS8hujT5U4AOgMfhrwYIuIhfKaoSCZcirrmASQr8CX7cUg+RMih+hgznrjp99o+W4pJLHQ==} - engines: {node: '>=12', npm: '>=6'} + jsonwebtoken@9.0.2: dependencies: jws: 3.2.2 lodash.includes: 4.3.0 @@ -15965,88 +20507,57 @@ packages: lodash.once: 4.1.1 ms: 2.1.3 semver: 7.6.0 - dev: false - /jsx-ast-utils@3.3.5: - resolution: {integrity: sha512-ZZow9HBI5O6EPgSJLUb8n2NKgmVWTwCvHGwFuJlMjvLFqlGG6pjirPhtdsseaLZjSibD8eegzmYpUZwoIlj2cQ==} - engines: {node: '>=4.0'} + jsx-ast-utils@3.3.5: dependencies: array-includes: 3.1.8 array.prototype.flat: 1.3.2 object.assign: 4.1.5 object.values: 1.2.0 - dev: true - /just-extend@4.2.1: - resolution: {integrity: sha512-g3UB796vUFIY90VIv/WX3L2c8CS2MdWUww3CNrYmqza1Fg0DURc2K/O4YrnklBdQarSJ/y8JnJYDGc+1iumQjg==} - dev: true + just-extend@4.2.1: {} - /just-kebab-case@4.2.0: - resolution: {integrity: sha512-p2BdO7o4BI+pMun3J+dhaOfYan5JsZrw9wjshRjkWY9+p+u+kKSMhNWYnot2yHDR9CSahZ9iT3dcqJ+V72qHMw==} - dev: true + just-kebab-case@4.2.0: {} - /jwa@1.4.1: - resolution: {integrity: sha512-qiLX/xhEEFKUAJ6FiBMbes3w9ATzyk5W7Hvzpa/SLYdxNtng+gcurvrI7TbACjIXlsJyr05/S1oUhZrc63evQA==} + jwa@1.4.1: dependencies: buffer-equal-constant-time: 1.0.1 ecdsa-sig-formatter: 1.0.11 safe-buffer: 5.2.1 - dev: false - /jwa@2.0.0: - resolution: {integrity: sha512-jrZ2Qx916EA+fq9cEAeCROWPTfCwi1IVHqT2tapuqLEVVDKFDENFw1oL+MwrTvH6msKxsd1YTDVw6uKEcsrLEA==} + jwa@2.0.0: dependencies: buffer-equal-constant-time: 1.0.1 ecdsa-sig-formatter: 1.0.11 safe-buffer: 5.2.1 - dev: false - /jws@3.2.2: - resolution: {integrity: sha512-YHlZCB6lMTllWDtSPHz/ZXTsi8S00usEV6v1tjq8tOUZzw7DpSDWVXjXDre6ed1w/pd495ODpHZYSdkRTsa0HA==} + jws@3.2.2: dependencies: jwa: 1.4.1 safe-buffer: 5.2.1 - dev: false - /jws@4.0.0: - resolution: {integrity: sha512-KDncfTmOZoOMTFG4mBlG0qUIOlc03fmzH+ru6RgYVZhPkyiy/92Owlt/8UEN+a4TXR1FQetfIpJE8ApdvdVxTg==} + jws@4.0.0: dependencies: jwa: 2.0.0 safe-buffer: 5.2.1 - dev: false - /keygrip@1.1.0: - resolution: {integrity: sha512-iYSchDJ+liQ8iwbSI2QqsQOvqv58eJCEanyJPJi+Khyu8smkcKSFUCbPwzFcL7YVtZ6eONjqRX/38caJ7QjRAQ==} - engines: {node: '>= 0.6'} + keygrip@1.1.0: dependencies: tsscmp: 1.0.6 - /keyv@4.5.4: - resolution: {integrity: sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==} + keyv@4.5.4: dependencies: json-buffer: 3.0.1 - /kind-of@6.0.3: - resolution: {integrity: sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==} - engines: {node: '>=0.10.0'} - dev: true + kind-of@6.0.3: {} - /kleur@3.0.3: - resolution: {integrity: sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w==} - engines: {node: '>=6'} - dev: true + kleur@3.0.3: {} - /kleur@4.1.4: - resolution: {integrity: sha512-8QADVssbrFjivHWQU7KkMgptGTl6WAcSdlbBPY4uNF+mWr6DGcKrvY2w4FQJoXch7+fKMjj0dRrL75vk3k23OA==} - engines: {node: '>=6'} - dev: true + kleur@4.1.4: {} - /known-css-properties@0.29.0: - resolution: {integrity: sha512-Ne7wqW7/9Cz54PDt4I3tcV+hAyat8ypyOGzYRJQfdxnnjeWsTxt1cy8pjvvKeI5kfXuyvULyeeAvwvvtAX3ayQ==} - dev: true + known-css-properties@0.29.0: {} - /koa-body@6.0.1: - resolution: {integrity: sha512-M8ZvMD8r+kPHy28aWP9VxL7kY8oPWA+C7ZgCljrCMeaU7uX6wsIQgDHskyrAr9sw+jqnIXyv4Mlxri5R4InIJg==} + koa-body@6.0.1: dependencies: '@types/co-body': 6.1.3 '@types/formidable': 2.0.6 @@ -16054,57 +20565,39 @@ packages: co-body: 6.1.0 formidable: 3.5.1 zod: 3.22.4 - dev: false - /koa-compose@4.1.0: - resolution: {integrity: sha512-8ODW8TrDuMYvXRwra/Kh7/rJo9BtOfPc6qO8eAfC80CnCvSjSl0bkRM24X6/XBBEyj0v1nRUQ1LyOy3dbqOWXw==} + koa-compose@4.1.0: {} - /koa-compress@5.1.0: - resolution: {integrity: sha512-G3Ppo9jrUwlchp6qdoRgQNMiGZtM0TAHkxRZQ7EoVvIG8E47J4nAsMJxXHAUQ+0oc7t0MDxSdONWTFcbzX7/Bg==} - engines: {node: '>= 8.0.0'} + koa-compress@5.1.0: dependencies: bytes: 3.1.2 compressible: 2.0.18 http-errors: 1.8.1 koa-is-json: 1.0.0 statuses: 2.0.1 - dev: false - /koa-convert@2.0.0: - resolution: {integrity: sha512-asOvN6bFlSnxewce2e/DK3p4tltyfC4VM7ZwuTuepI7dEQVcvpyFuBcEARu1+Hxg8DIwytce2n7jrZtRlPrARA==} - engines: {node: '>= 10'} + koa-convert@2.0.0: dependencies: co: 4.6.0 koa-compose: 4.1.0 - /koa-is-json@1.0.0: - resolution: {integrity: sha512-+97CtHAlWDx0ndt0J8y3P12EWLwTLMXIfMnYDev3wOTwH/RpBGMlfn4bDXlMEg1u73K6XRE9BbUp+5ZAYoRYWw==} - dev: false + koa-is-json@1.0.0: {} - /koa-logger@3.2.1: - resolution: {integrity: sha512-MjlznhLLKy9+kG8nAXKJLM0/ClsQp/Or2vI3a5rbSQmgl8IJBQO0KI5FA70BvW+hqjtxjp49SpH2E7okS6NmHg==} - engines: {node: '>= 7.6.0'} + koa-logger@3.2.1: dependencies: bytes: 3.1.1 chalk: 2.4.2 humanize-number: 0.0.2 passthrough-counter: 1.0.0 - dev: false - /koa-mount@4.0.0: - resolution: {integrity: sha512-rm71jaA/P+6HeCpoRhmCv8KVBIi0tfGuO/dMKicbQnQW/YJntJ6MnnspkodoA4QstMVEZArsCphmd0bJEtoMjQ==} - engines: {node: '>= 7.6.0'} + koa-mount@4.0.0: dependencies: debug: 4.3.4 koa-compose: 4.1.0 transitivePeerDependencies: - supports-color - dev: false - /koa-proxies@0.12.4(koa@2.13.4): - resolution: {integrity: sha512-xxrEtN0e7s7/gNRoOMUltCbuIaCWqTQUTZNWQqet/8MoxSW0hG422lx2Al9FfYO3nCeA+b5c5/YmILRzavivDA==} - peerDependencies: - koa: '>=2' + koa-proxies@0.12.4(koa@2.13.4): dependencies: http-proxy: 1.18.1 koa: 2.13.4 @@ -16112,32 +20605,23 @@ packages: uuid: 8.3.2 transitivePeerDependencies: - debug - dev: false - /koa-router@12.0.0: - resolution: {integrity: sha512-zGrdiXygGYW8WvrzeGsHZvKnHs4DzyGoqJ9a8iHlRkiwuEAOAPyI27//OlhoWdgFAEIM3qbUgr0KCuRaP/TCag==} - engines: {node: '>= 12'} + koa-router@12.0.0: dependencies: http-errors: 2.0.0 koa-compose: 4.1.0 methods: 1.1.2 path-to-regexp: 6.2.1 - dev: false - /koa-send@5.0.1: - resolution: {integrity: sha512-tmcyQ/wXXuxpDxyNXv5yNNkdAMdFRqwtegBXUaowiQzUKqJehttS0x2j0eOZDQAyloAth5w6wwBImnFzkUz3pQ==} - engines: {node: '>= 8'} + koa-send@5.0.1: dependencies: debug: 4.3.4 http-errors: 1.8.1 resolve-path: 1.4.0 transitivePeerDependencies: - supports-color - dev: false - /koa@2.13.4: - resolution: {integrity: sha512-43zkIKubNbnrULWlHdN5h1g3SEKXOEzoAlRsHOTFpnlDu8JlAOZSMJBLULusuXRequboiwJcj5vtYXKB3k7+2g==} - engines: {node: ^4.8.4 || ^6.10.1 || ^7.10.1 || >= 8.1.4} + koa@2.13.4: dependencies: accepts: 1.3.7 cache-content-type: 1.0.1 @@ -16165,9 +20649,7 @@ packages: transitivePeerDependencies: - supports-color - /koa@2.15.3: - resolution: {integrity: sha512-j/8tY9j5t+GVMLeioLaxweJiKUayFhlGqNTzf2ZGwL0ZCQijd2RLHK0SLW5Tsko8YyyqCZC2cojIb0/s62qTAg==} - engines: {node: ^4.8.4 || ^6.10.1 || ^7.10.1 || >= 8.1.4} + koa@2.15.3: dependencies: accepts: 1.3.8 cache-content-type: 1.0.1 @@ -16194,122 +20676,54 @@ packages: vary: 1.1.2 transitivePeerDependencies: - supports-color - dev: false - /ky@1.2.3: - resolution: {integrity: sha512-2IM3VssHfG2zYz2FsHRUqIp8chhLc9uxDMcK2THxgFfv8pQhnMfN8L0ul+iW4RdBl5AglF8ooPIflRm3yNH0IA==} - engines: {node: '>=18'} + ky@1.2.3: {} - /language-subtag-registry@0.3.22: - resolution: {integrity: sha512-tN0MCzyWnoz/4nHS6uxdlFWoUZT7ABptwKPQ52Ea7URk6vll88bWBVhodtnlfEuCcKWNGoc+uGbw1cwa9IKh/w==} - dev: true + language-subtag-registry@0.3.22: {} - /language-tags@1.0.9: - resolution: {integrity: sha512-MbjN408fEndfiQXbFQ1vnd+1NoLDsnQW41410oQBXiyXDMYH5z505juWa4KUE1LqxRC7DgOgZDbKLxHIwm27hA==} - engines: {node: '>=0.10'} + language-tags@1.0.9: dependencies: language-subtag-registry: 0.3.22 - dev: true - /leven@3.1.0: - resolution: {integrity: sha512-qsda+H8jTaUaN/x5vzW2rzc+8Rw4TAQ/4KjB46IwK5VH+IlVeeeje/EoZRpiXvIqjFgK84QffqPztGI3VBLG1A==} - engines: {node: '>=6'} - dev: true + leven@3.1.0: {} - /levn@0.3.0: - resolution: {integrity: sha512-0OO4y2iOHix2W6ujICbKIaEQXvFQHue65vUG3pb5EUomzPI90z9hsA1VsO/dbIIpC53J8gxM9Q4Oho0jrCM/yA==} - engines: {node: '>= 0.8.0'} + levn@0.3.0: dependencies: prelude-ls: 1.1.2 type-check: 0.3.2 - dev: true - /levn@0.4.1: - resolution: {integrity: sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==} - engines: {node: '>= 0.8.0'} + levn@0.4.1: dependencies: prelude-ls: 1.2.1 type-check: 0.4.0 - dev: true - /libphonenumber-js@1.10.51: - resolution: {integrity: sha512-vY2I+rQwrDQzoPds0JeTEpeWzbUJgqoV0O4v31PauHBb/e+1KCXKylHcDnBMgJZ9fH9mErsEbROJY3Z3JtqEmg==} + libphonenumber-js@1.10.51: {} - /lightningcss-darwin-arm64@1.16.1: - resolution: {integrity: sha512-/J898YSAiGVqdybHdIF3Ao0Hbh2vyVVj5YNm3NznVzTSvkOi3qQCAtO97sfmNz+bSRHXga7ZPLm+89PpOM5gAg==} - engines: {node: '>= 12.0.0'} - cpu: [arm64] - os: [darwin] - requiresBuild: true - dev: true + lightningcss-darwin-arm64@1.16.1: optional: true - /lightningcss-darwin-x64@1.16.1: - resolution: {integrity: sha512-vyKCNPRNRqke+5i078V+N0GLfMVLEaNcqIcv28hA/vUNRGk/90EDkDB9EndGay0MoPIrC2y0qE3Y74b/OyedqQ==} - engines: {node: '>= 12.0.0'} - cpu: [x64] - os: [darwin] - requiresBuild: true - dev: true + lightningcss-darwin-x64@1.16.1: optional: true - /lightningcss-linux-arm-gnueabihf@1.16.1: - resolution: {integrity: sha512-0AJC52l40VbrzkMJz6qRvlqVVGykkR2MgRS4bLjVC2ab0H0I/n4p6uPZXGvNIt5gw1PedeND/hq+BghNdgfuPQ==} - engines: {node: '>= 12.0.0'} - cpu: [arm] - os: [linux] - requiresBuild: true - dev: true + lightningcss-linux-arm-gnueabihf@1.16.1: optional: true - /lightningcss-linux-arm64-gnu@1.16.1: - resolution: {integrity: sha512-NqxYXsRvI3/Fb9AQLXKrYsU0Q61LqKz5It+Es9gidsfcw1lamny4lmlUgO3quisivkaLCxEkogaizcU6QeZeWQ==} - engines: {node: '>= 12.0.0'} - cpu: [arm64] - os: [linux] - requiresBuild: true - dev: true + lightningcss-linux-arm64-gnu@1.16.1: optional: true - /lightningcss-linux-arm64-musl@1.16.1: - resolution: {integrity: sha512-VUPQ4dmB9yDQxpJF8/imtwNcbIPzlL6ArLHSUInOGxipDk1lOAklhUjbKUvlL3HVlDwD3WHCxggAY01WpFcjiA==} - engines: {node: '>= 12.0.0'} - cpu: [arm64] - os: [linux] - requiresBuild: true - dev: true + lightningcss-linux-arm64-musl@1.16.1: optional: true - /lightningcss-linux-x64-gnu@1.16.1: - resolution: {integrity: sha512-A40Jjnbellnvh4YF+kt047GLnUU59iLN2LFRCyWQG+QqQZeXOCzXfTQ6EJB4yvHB1mQvWOVdAzVrtEmRw3Vh8g==} - engines: {node: '>= 12.0.0'} - cpu: [x64] - os: [linux] - requiresBuild: true - dev: true + lightningcss-linux-x64-gnu@1.16.1: optional: true - /lightningcss-linux-x64-musl@1.16.1: - resolution: {integrity: sha512-VZf76GxW+8mk238tpw0u9R66gBi/m0YB0TvD54oeGiOqvTZ/mabkBkbsuXTSWcKYj8DSrLW+A42qu+6PLRsIgA==} - engines: {node: '>= 12.0.0'} - cpu: [x64] - os: [linux] - requiresBuild: true - dev: true + lightningcss-linux-x64-musl@1.16.1: optional: true - /lightningcss-win32-x64-msvc@1.16.1: - resolution: {integrity: sha512-Djy+UzlTtJMayVJU3eFuUW5Gdo+zVTNPJhlYw25tNC9HAoMCkIdSDDrGsWEdEyibEV7xwB8ySTmLuxilfhBtgg==} - engines: {node: '>= 12.0.0'} - cpu: [x64] - os: [win32] - requiresBuild: true - dev: true + lightningcss-win32-x64-msvc@1.16.1: optional: true - /lightningcss@1.16.1: - resolution: {integrity: sha512-zU8OTaps3VAodmI2MopfqqOQQ4A9L/2Eo7xoTH/4fNkecy6ftfiGwbbRMTQqtIqJjRg3f927e+lnyBBPhucY1Q==} - engines: {node: '>= 12.0.0'} + lightningcss@1.16.1: dependencies: detect-libc: 1.0.3 optionalDependencies: @@ -16321,21 +20735,12 @@ packages: lightningcss-linux-x64-gnu: 1.16.1 lightningcss-linux-x64-musl: 1.16.1 lightningcss-win32-x64-msvc: 1.16.1 - dev: true - /lilconfig@2.1.0: - resolution: {integrity: sha512-utWOt/GHzuUxnLKxB6dk81RoOeoNeHgbrXiuGk4yyF5qlRz+iIVWu56E2fqGHFrXz0QNUhLB/8nKqvRH66JKGQ==} - engines: {node: '>=10'} - dev: true + lilconfig@2.1.0: {} - /lines-and-columns@1.2.4: - resolution: {integrity: sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==} - dev: true + lines-and-columns@1.2.4: {} - /lint-staged@15.0.2: - resolution: {integrity: sha512-vnEy7pFTHyVuDmCAIFKR5QDO8XLVlPFQQyujQ/STOxe40ICWqJ6knS2wSJ/ffX/Lw0rz83luRDh+ET7toN+rOw==} - engines: {node: '>=18.12.0'} - hasBin: true + lint-staged@15.0.2: dependencies: chalk: 5.3.0 commander: 11.1.0 @@ -16349,11 +20754,8 @@ packages: yaml: 2.3.3 transitivePeerDependencies: - supports-color - dev: true - /listr2@7.0.2: - resolution: {integrity: sha512-rJysbR9GKIalhTbVL2tYbF2hVyDnrf7pFUZBwjPaMIdadYHmeT+EVi/Bu3qd7ETQPahTotg2WRCatXwRBW554g==} - engines: {node: '>=16.0.0'} + listr2@7.0.2: dependencies: cli-truncate: 3.1.0 colorette: 2.0.20 @@ -16361,12 +20763,8 @@ packages: log-update: 5.0.1 rfdc: 1.3.0 wrap-ansi: 8.1.0 - dev: true - /lmdb@2.7.11: - resolution: {integrity: sha512-x9bD4hVp7PFLUoELL8RglbNXhAMt5CYhkmss+CEau9KlNoilsTzNi9QDsPZb3KMpOGZXG6jmXhW3bBxE2XVztw==} - hasBin: true - requiresBuild: true + lmdb@2.7.11: dependencies: msgpackr: 1.8.5 node-addon-api: 4.3.0 @@ -16380,327 +20778,191 @@ packages: '@lmdb/lmdb-linux-arm64': 2.7.11 '@lmdb/lmdb-linux-x64': 2.7.11 '@lmdb/lmdb-win32-x64': 2.7.11 - dev: true - /load-yaml-file@0.2.0: - resolution: {integrity: sha512-OfCBkGEw4nN6JLtgRidPX6QxjBQGQf72q3si2uvqyFEMbycSFFHwAZeXx6cJgFM9wmLrf9zBwCP3Ivqa+LLZPw==} - engines: {node: '>=6'} + load-yaml-file@0.2.0: dependencies: graceful-fs: 4.2.11 js-yaml: 3.14.1 pify: 4.0.1 strip-bom: 3.0.0 - dev: true - /loader-utils@3.2.0: - resolution: {integrity: sha512-HVl9ZqccQihZ7JM85dco1MvO9G+ONvxoGa9rkhzFsneGLKSUg1gJf9bWzhRhcvm2qChhWpebQhP44qxjKIUCaQ==} - engines: {node: '>= 12.13.0'} - dev: true + loader-utils@3.2.0: {} - /local-pkg@0.5.0: - resolution: {integrity: sha512-ok6z3qlYyCDS4ZEU27HaU6x/xZa9Whf8jD4ptH5UZTQYZVYeb9bnZ3ojVhiJNLiXK1Hfc0GNbLXcmZ5plLDDBg==} - engines: {node: '>=14'} + local-pkg@0.5.0: dependencies: mlly: 1.6.1 pkg-types: 1.0.3 - dev: true - /locate-path@5.0.0: - resolution: {integrity: sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==} - engines: {node: '>=8'} + locate-path@5.0.0: dependencies: p-locate: 4.1.0 - /locate-path@6.0.0: - resolution: {integrity: sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==} - engines: {node: '>=10'} + locate-path@6.0.0: dependencies: p-locate: 5.0.0 - dev: true - /locate-path@7.2.0: - resolution: {integrity: sha512-gvVijfZvn7R+2qyPX8mAuKcFGDf6Nc61GdvGafQsHL0sBIxfKzA+usWn4GFC/bk+QdwPUD4kWFJLhElipq+0VA==} - engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + locate-path@7.2.0: dependencies: p-locate: 6.0.0 - /lodash-es@4.17.21: - resolution: {integrity: sha512-mKnC+QJ9pWVzv+C4/U3rRsHapFfHvQFoFB92e52xeyGMcX6/OlIl78je1u8vePzYZSkkogMPJ2yjxxsb89cxyw==} - dev: true + lodash-es@4.17.21: {} - /lodash.camelcase@4.3.0: - resolution: {integrity: sha512-TwuEnCnxbc3rAvhf/LbG7tJUDzhqXyFnv3dtzLOPgCG/hODL7WFnsbwktkD7yUV0RrreP/l1PALq/YSg6VvjlA==} - dev: true + lodash.camelcase@4.3.0: {} - /lodash.get@4.4.2: - resolution: {integrity: sha512-z+Uw/vLuy6gQe8cfaFWD7p0wVv8fJl3mbzXh33RS+0oW2wvUqiRXiQ69gLWSLpgB5/6sU+r6BlQR0MBILadqTQ==} - dev: true + lodash.get@4.4.2: {} - /lodash.includes@4.3.0: - resolution: {integrity: sha512-W3Bx6mdkRTGtlJISOvVD/lbqjTlPPUDTMnlXZFnVwi9NKJ6tiAk6LVdlhZMm17VZisqhKcgzpO5Wz91PCt5b0w==} - dev: false + lodash.includes@4.3.0: {} - /lodash.isboolean@3.0.3: - resolution: {integrity: sha512-Bz5mupy2SVbPHURB98VAcw+aHh4vRV5IPNhILUCsOzRmsTmSQ17jIuqopAentWoehktxGd9e/hbIXq980/1QJg==} - dev: false + lodash.isboolean@3.0.3: {} - /lodash.isempty@4.4.0: - resolution: {integrity: sha512-oKMuF3xEeqDltrGMfDxAPGIVMSSRv8tbRSODbrs4KGsRRLEhrW8N8Rd4DRgB2+621hY8A8XwwrTVhXWpxFvMzg==} + lodash.isempty@4.4.0: {} - /lodash.isinteger@4.0.4: - resolution: {integrity: sha512-DBwtEWN2caHQ9/imiNeEA5ys1JoRtRfY3d7V9wkqtbycnAmTvRRmbHKDV4a0EYc678/dia0jrte4tjYwVBaZUA==} - dev: false + lodash.isinteger@4.0.4: {} - /lodash.isnumber@3.0.3: - resolution: {integrity: sha512-QYqzpfwO3/CWf3XP+Z+tkQsfaLL/EnUlXWVkIk5FUPc4sBdTehEqZONuyRt2P67PXAk+NXmTBcc97zw9t1FQrw==} - dev: false + lodash.isnumber@3.0.3: {} - /lodash.isplainobject@4.0.6: - resolution: {integrity: sha512-oSXzaWypCMHkPC3NvBEaPHf0KsA5mvPrOPgQWDsbg8n7orZ290M0BmC/jgRZ4vcJ6DTAhjrsSYgdsW/F+MFOBA==} + lodash.isplainobject@4.0.6: {} - /lodash.isstring@4.0.1: - resolution: {integrity: sha512-0wJxfxH1wgO3GrbuP+dTTk7op+6L41QCXbGINEmD+ny/G/eCqGzxyCsh7159S+mgDDcoarnBw6PC1PS5+wUGgw==} - dev: false + lodash.isstring@4.0.1: {} - /lodash.kebabcase@4.1.1: - resolution: {integrity: sha512-N8XRTIMMqqDgSy4VLKPnJ/+hpGZN+PHQiJnSenYqPaVV/NCqEogTnAdZLQiGKhxX+JCs8waWq2t1XHWKOmlY8g==} - dev: true + lodash.kebabcase@4.1.1: {} - /lodash.merge@4.6.2: - resolution: {integrity: sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==} - dev: true + lodash.merge@4.6.2: {} - /lodash.mergewith@4.6.2: - resolution: {integrity: sha512-GK3g5RPZWTRSeLSpgP8Xhra+pnjBC56q9FZYe1d5RN3TJ35dbkGy3YqBSMbyCrlbi+CM9Z3Jk5yTL7RCsqboyQ==} - dev: true + lodash.mergewith@4.6.2: {} - /lodash.once@4.1.1: - resolution: {integrity: sha512-Sb487aTOCr9drQVL8pIxOzVhafOjZN9UU54hiN8PU3uAiSV7lx1yYNpbNmex2PK6dSJoNTSJUUswT651yww3Mg==} - dev: false + lodash.once@4.1.1: {} - /lodash.snakecase@4.1.1: - resolution: {integrity: sha512-QZ1d4xoBHYUeuouhEq3lk3Uq7ldgyFXGBhg04+oRLnIz8o9T65Eh+8YdroUwn846zchkA9yDsDl5CVVaV2nqYw==} - dev: true + lodash.snakecase@4.1.1: {} - /lodash.sortby@4.7.0: - resolution: {integrity: sha512-HDWXG8isMntAyRF5vZ7xKuEvOhT4AhlRt/3czTSjvGUxjYCBVRQY48ViDHyfYz9VIoBkW4TMGQNapx+l3RUwdA==} + lodash.sortby@4.7.0: {} - /lodash.startcase@4.4.0: - resolution: {integrity: sha512-+WKqsK294HMSc2jEbNgpHpd0JfIBhp7rEV4aqXWqFr6AlXov+SlcgB1Fv01y2kGe3Gc8nMW7VA0SrGuSkRfIEg==} - dev: true + lodash.startcase@4.4.0: {} - /lodash.transform@4.6.0: - resolution: {integrity: sha512-LO37ZnhmBVx0GvOU/caQuipEh4GN82TcWv3yHlebGDgOxbxiwwzW5Pcx2AcvpIv2WmvmSMoC492yQFNhy/l/UQ==} + lodash.transform@4.6.0: {} - /lodash.truncate@4.4.2: - resolution: {integrity: sha512-jttmRe7bRse52OsWIMDLaXxWqRAmtIUccAQ3garviCqJjafXOfNMO0yMfNpdD6zbGaTU0P5Nz7e7gAT6cKmJRw==} - dev: true + lodash.truncate@4.4.2: {} - /lodash.uniq@4.5.0: - resolution: {integrity: sha512-xfBaXQd9ryd9dlSDvnvI0lvxfLJlYAZzXomUYzLKtUeOQvOP5piqAWuGtrhWeqaXK9hhoM/iyJc5AV+XfsX3HQ==} - dev: true + lodash.uniq@4.5.0: {} - /lodash.upperfirst@4.3.1: - resolution: {integrity: sha512-sReKOYJIJf74dhJONhU4e0/shzi1trVbSWDOhKYE5XV2O+H7Sb2Dihwuc7xWxVl+DgFPyTqIN3zMfT9cq5iWDg==} - dev: true + lodash.upperfirst@4.3.1: {} - /lodash.zip@4.2.0: - resolution: {integrity: sha512-C7IOaBBK/0gMORRBd8OETNx3kmOkgIWIPvyDpZSCTwUrpYmgZwJkjZeOD8ww4xbOUOs4/attY+pciKvadNfFbg==} - dev: true + lodash.zip@4.2.0: {} - /lodash@4.17.21: - resolution: {integrity: sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==} + lodash@4.17.21: {} - /log-symbols@5.1.0: - resolution: {integrity: sha512-l0x2DvrW294C9uDCoQe1VSU4gf529FkSZ6leBl4TiqZH/e+0R7hSfHQBNut2mNygDgHwvYHfFLn6Oxb3VWj2rA==} - engines: {node: '>=12'} + log-symbols@5.1.0: dependencies: chalk: 5.3.0 is-unicode-supported: 1.3.0 - dev: false - /log-symbols@6.0.0: - resolution: {integrity: sha512-i24m8rpwhmPIS4zscNzK6MSEhk0DUWa/8iYQWxhffV8jkI4Phvs3F+quL5xvS0gdQR0FyTCMMH33Y78dDTzzIw==} - engines: {node: '>=18'} + log-symbols@6.0.0: dependencies: chalk: 5.3.0 is-unicode-supported: 1.3.0 - dev: false - /log-update@5.0.1: - resolution: {integrity: sha512-5UtUDQ/6edw4ofyljDNcOVJQ4c7OjDro4h3y8e1GQL5iYElYclVHJ3zeWchylvMaKnDbDilC8irOVyexnA/Slw==} - engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + log-update@5.0.1: dependencies: ansi-escapes: 5.0.0 cli-cursor: 4.0.0 slice-ansi: 5.0.0 strip-ansi: 7.1.0 wrap-ansi: 8.1.0 - dev: true - /longest-streak@3.0.1: - resolution: {integrity: sha512-cHlYSUpL2s7Fb3394mYxwTYj8niTaNHUCLr0qdiCXQfSjfuA7CKofpX2uSwEfFDQ0EB7JcnMnm+GjbqqoinYYg==} - dev: true + longest-streak@3.0.1: {} - /loose-envify@1.4.0: - resolution: {integrity: sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==} - hasBin: true + loose-envify@1.4.0: dependencies: js-tokens: 4.0.0 - dev: true - /loupe@2.3.7: - resolution: {integrity: sha512-zSMINGVYkdpYSOBmLi0D1Uo7JU9nVdQKrHxC8eYlV+9YKK9WePqAlL7lSlorG/U2Fw1w0hTBmaa/jrQ3UbPHtA==} + loupe@2.3.7: dependencies: get-func-name: 2.0.2 - dev: true - /lower-case@2.0.2: - resolution: {integrity: sha512-7fm3l3NAF9WfN6W3JOmf5drwpVqX78JtoGJ3A6W0a6ZnldM41w2fV5D490psKFTpMds8TJse/eHLFFsNHHjHgg==} + lower-case@2.0.2: dependencies: tslib: 2.6.2 - dev: false - /lowercase-keys@1.0.1: - resolution: {integrity: sha512-G2Lj61tXDnVFFOi8VZds+SoQjtQC3dgokKdDG2mTm1tx4m50NUHBOZSBwQQHyy0V12A0JTG4icfZQH+xPyh8VA==} - engines: {node: '>=0.10.0'} - dev: true + lowercase-keys@1.0.1: {} - /lowercase-keys@3.0.0: - resolution: {integrity: sha512-ozCC6gdQ+glXOQsveKD0YsDy8DSQFjDTz4zyzEHNV5+JP5D62LmfDZ6o1cycFx9ouG940M5dE8C8CTewdj2YWQ==} - engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} - dev: false + lowercase-keys@3.0.0: {} - /lowlight@1.20.0: - resolution: {integrity: sha512-8Ktj+prEb1RoCPkEOrPMYUN/nCggB7qAWe3a7OpMjWQkh3l2RD5wKRQ+o8Q8YuI9RG/xs95waaI/E6ym/7NsTw==} + lowlight@1.20.0: dependencies: fault: 1.0.4 highlight.js: 10.7.3 - dev: true - /lru-cache@10.0.0: - resolution: {integrity: sha512-svTf/fzsKHffP42sujkO/Rjs37BCIsQVRCeNYIm9WN8rgT7ffoUnRtZCqU+6BqcSBdv8gwJeTz8knJpgACeQMw==} - engines: {node: 14 || >=16.14} - dev: false + lru-cache@10.0.0: {} - /lru-cache@10.2.0: - resolution: {integrity: sha512-2bIM8x+VAf6JT4bKAljS1qUWgMsqZRPGJS6FSahIMPVvctcNhyVp7AJu7quxOW9jwkryBReKZY5tY5JYv2n/7Q==} - engines: {node: 14 || >=16.14} - dev: false + lru-cache@10.2.0: {} - /lru-cache@4.1.5: - resolution: {integrity: sha512-sWZlbEP2OsHNkXrMl5GYk/jKk70MBng6UU4YI/qGDYbgf6YbP4EvmqISbXCoJiRKs+1bSpFHVgQxvJ17F2li5g==} + lru-cache@4.1.5: dependencies: pseudomap: 1.0.2 yallist: 2.1.2 - dev: true - /lru-cache@5.1.1: - resolution: {integrity: sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==} + lru-cache@5.1.1: dependencies: yallist: 3.1.1 - dev: true - /lru-cache@6.0.0: - resolution: {integrity: sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==} - engines: {node: '>=10'} + lru-cache@6.0.0: dependencies: yallist: 4.0.0 - /lru-cache@7.18.3: - resolution: {integrity: sha512-jumlc0BIUrS3qJGgIkWZsyfAM7NCWiBcCDhnd+3NNM5KbBmLTgHVfWBcg6W+rLUsIpzpERPsvwUP7CckAQSOoA==} - engines: {node: '>=12'} - dev: true + lru-cache@7.18.3: {} - /lz-string@1.5.0: - resolution: {integrity: sha512-h5bgJWpxJNswbU7qCrV0tIKQCaS3blPDrqKWx+QxzuzL1zGUzij9XCWLrSLsJPu5t+eWA/ycetzYAO5IOMcWAQ==} - hasBin: true - dev: true + lz-string@1.5.0: {} - /magic-string@0.30.7: - resolution: {integrity: sha512-8vBuFF/I/+OSLRmdf2wwFCJCz+nSn0m6DPvGH1fS/KiQoSaR+sETbov0eIk9KhEKy8CYqIkIAnbohxT/4H0kuA==} - engines: {node: '>=12'} + magic-string@0.30.7: dependencies: '@jridgewell/sourcemap-codec': 1.4.15 - dev: true - /magicast@0.3.3: - resolution: {integrity: sha512-ZbrP1Qxnpoes8sz47AM0z08U+jW6TyRgZzcWy3Ma3vDhJttwMwAFDMMQFobwdBxByBD46JYmxRzeF7w2+wJEuw==} + magicast@0.3.3: dependencies: '@babel/parser': 7.24.0 '@babel/types': 7.24.0 source-map-js: 1.0.2 - dev: true - /make-dir@4.0.0: - resolution: {integrity: sha512-hXdUTZYIVOt1Ex//jAQi+wTZZpUpwBj/0QsOzqegb3rGMMeJiSEu5xLHnYfBrRV4RH2+OCSOO95Is/7x1WJ4bw==} - engines: {node: '>=10'} + make-dir@4.0.0: dependencies: semver: 7.6.0 - dev: true - /make-error@1.3.6: - resolution: {integrity: sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==} - dev: true + make-error@1.3.6: {} - /makeerror@1.0.12: - resolution: {integrity: sha512-JmqCvUhmt43madlpFzG4BQzG2Z3m6tvQDNKdClZnO3VbIudJYmxsT0FNJMeiB2+JTSlTQTSbU8QdesVmwJcmLg==} + makeerror@1.0.12: dependencies: tmpl: 1.0.5 - dev: true - /map-obj@1.0.1: - resolution: {integrity: sha512-7N/q3lyZ+LVCp7PzuxrJr4KMbBE2hW7BT7YNia330OFxIf4d3r5zVpicP2650l7CPN6RM9zOJRl3NGpqSiw3Eg==} - engines: {node: '>=0.10.0'} - dev: true + map-obj@1.0.1: {} - /map-obj@4.3.0: - resolution: {integrity: sha512-hdN1wVrZbb29eBGiGjJbeP8JbKjq1urkHJ/LIP/NY48MZ1QVXUsQBV1G1zvYFHn1XE06cwjBsOI2K3Ulnj1YXQ==} - engines: {node: '>=8'} + map-obj@4.3.0: {} - /map-obj@5.0.0: - resolution: {integrity: sha512-2L3MIgJynYrZ3TYMriLDLWocz15okFakV6J12HXvMXDHui2x/zgChzg1u9mFFGbbGWE+GsLpQByt4POb9Or+uA==} - engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + map-obj@5.0.0: {} - /markdown-escapes@1.0.4: - resolution: {integrity: sha512-8z4efJYk43E0upd0NbVXwgSTQs6cT3T06etieCMEg7dRbzCbxUCK/GHlX8mhHRDcp+OLlHkPKsvqQTCvsRl2cg==} - dev: true + markdown-escapes@1.0.4: {} - /markdown-table@3.0.2: - resolution: {integrity: sha512-y8j3a5/DkJCmS5x4dMCQL+OR0+2EAq3DOtio1COSHsmW2BGXnNCK3v12hJt1LrUz5iZH5g0LmuYOjDdI+czghA==} - dev: true + markdown-table@3.0.2: {} - /material-colors@1.2.6: - resolution: {integrity: sha512-6qE4B9deFBIa9YSpOc9O0Sgc43zTeVYbgDT5veRKSlB2+ZuHNoVVxA1L/ckMUayV9Ay9y7Z/SZCLcGteW9i7bg==} - dev: true + material-colors@1.2.6: {} - /mathml-tag-names@2.1.3: - resolution: {integrity: sha512-APMBEanjybaPzUrfqU0IMU5I0AswKMH7k8OTLs0vvV4KZpExkTkY87nR/zpbuTPj+gARop7aGUbl11pnDfW6xg==} - dev: true + mathml-tag-names@2.1.3: {} - /mdast-squeeze-paragraphs@4.0.0: - resolution: {integrity: sha512-zxdPn69hkQ1rm4J+2Cs2j6wDEv7O17TfXTJ33tl/+JPIoEmtV9t2ZzBM5LPHE8QlHsmVD8t3vPKCyY3oH+H8MQ==} + mdast-squeeze-paragraphs@4.0.0: dependencies: unist-util-remove: 2.1.0 - dev: true - /mdast-util-definitions@4.0.0: - resolution: {integrity: sha512-k8AJ6aNnUkB7IE+5azR9h81O5EQ/cTDXtWdMq9Kk5KcEW/8ritU5CeLg/9HhOC++nALHBlaogJ5jz0Ybk3kPMQ==} + mdast-util-definitions@4.0.0: dependencies: unist-util-visit: 2.0.3 - dev: true - /mdast-util-find-and-replace@3.0.1: - resolution: {integrity: sha512-SG21kZHGC3XRTSUhtofZkBzZTJNM5ecCi0SK2IMKmSXR8vO3peL+kb1O0z7Zl83jKtutG4k5Wv/W7V3/YHvzPA==} + mdast-util-find-and-replace@3.0.1: dependencies: '@types/mdast': 4.0.1 escape-string-regexp: 5.0.0 unist-util-is: 6.0.0 unist-util-visit-parents: 6.0.1 - dev: true - /mdast-util-from-markdown@2.0.0: - resolution: {integrity: sha512-n7MTOr/z+8NAX/wmhhDji8O3bRvPTV/U0oTCaZJkjhPSKTPhS3xufVhKGF8s1pJ7Ox4QgoIU7KHseh09S+9rTA==} + mdast-util-from-markdown@2.0.0: dependencies: '@types/mdast': 4.0.1 '@types/unist': 3.0.0 @@ -16716,20 +20978,16 @@ packages: unist-util-stringify-position: 4.0.0 transitivePeerDependencies: - supports-color - dev: true - /mdast-util-gfm-autolink-literal@2.0.0: - resolution: {integrity: sha512-FyzMsduZZHSc3i0Px3PQcBT4WJY/X/RCtEJKuybiC6sjPqLv7h1yqAkmILZtuxMSsUyaLUWNp71+vQH2zqp5cg==} + mdast-util-gfm-autolink-literal@2.0.0: dependencies: '@types/mdast': 4.0.1 ccount: 2.0.1 devlop: 1.1.0 mdast-util-find-and-replace: 3.0.1 micromark-util-character: 2.0.1 - dev: true - /mdast-util-gfm-footnote@2.0.0: - resolution: {integrity: sha512-5jOT2boTSVkMnQ7LTrd6n/18kqwjmuYqo7JUPe+tRCY6O7dAuTFMtTPauYYrMPpox9hlN0uOx/FL8XvEfG9/mQ==} + mdast-util-gfm-footnote@2.0.0: dependencies: '@types/mdast': 4.0.1 devlop: 1.1.0 @@ -16738,20 +20996,16 @@ packages: micromark-util-normalize-identifier: 2.0.0 transitivePeerDependencies: - supports-color - dev: true - /mdast-util-gfm-strikethrough@2.0.0: - resolution: {integrity: sha512-mKKb915TF+OC5ptj5bJ7WFRPdYtuHv0yTRxK2tJvi+BDqbkiG7h7u/9SI89nRAYcmap2xHQL9D+QG/6wSrTtXg==} + mdast-util-gfm-strikethrough@2.0.0: dependencies: '@types/mdast': 4.0.1 mdast-util-from-markdown: 2.0.0 mdast-util-to-markdown: 2.1.0 transitivePeerDependencies: - supports-color - dev: true - /mdast-util-gfm-table@2.0.0: - resolution: {integrity: sha512-78UEvebzz/rJIxLvE7ZtDd/vIQ0RHv+3Mh5DR96p7cS7HsBhYIICDBCu8csTNWNO6tBWfqXPWekRuj2FNOGOZg==} + mdast-util-gfm-table@2.0.0: dependencies: '@types/mdast': 4.0.1 devlop: 1.1.0 @@ -16760,10 +21014,8 @@ packages: mdast-util-to-markdown: 2.1.0 transitivePeerDependencies: - supports-color - dev: true - /mdast-util-gfm-task-list-item@2.0.0: - resolution: {integrity: sha512-IrtvNvjxC1o06taBAVJznEnkiHxLFTzgonUdy8hzFVeDun0uTjxxrRGVaNFqkU1wJR3RBPEfsxmU6jDWPofrTQ==} + mdast-util-gfm-task-list-item@2.0.0: dependencies: '@types/mdast': 4.0.1 devlop: 1.1.0 @@ -16771,10 +21023,8 @@ packages: mdast-util-to-markdown: 2.1.0 transitivePeerDependencies: - supports-color - dev: true - /mdast-util-gfm@3.0.0: - resolution: {integrity: sha512-dgQEX5Amaq+DuUqf26jJqSK9qgixgd6rYDHAv4aTBuA92cTknZlKpPfa86Z/s8Dj8xsAQpFfBmPUHWJBWqS4Bw==} + mdast-util-gfm@3.0.0: dependencies: mdast-util-from-markdown: 2.0.0 mdast-util-gfm-autolink-literal: 2.0.0 @@ -16785,17 +21035,13 @@ packages: mdast-util-to-markdown: 2.1.0 transitivePeerDependencies: - supports-color - dev: true - /mdast-util-phrasing@4.0.0: - resolution: {integrity: sha512-xadSsJayQIucJ9n053dfQwVu1kuXg7jCTdYsMK8rqzKZh52nLfSH/k0sAxE0u+pj/zKZX+o5wB+ML5mRayOxFA==} + mdast-util-phrasing@4.0.0: dependencies: '@types/mdast': 4.0.1 unist-util-is: 6.0.0 - dev: true - /mdast-util-to-hast@10.0.1: - resolution: {integrity: sha512-BW3LM9SEMnjf4HXXVApZMt8gLQWVNXc3jryK0nJu/rOXPOnlkUjmdkDlmxMirpbU9ILncGFIwLH/ubnWBbcdgA==} + mdast-util-to-hast@10.0.1: dependencies: '@types/mdast': 3.0.10 '@types/unist': 2.0.6 @@ -16805,10 +21051,8 @@ packages: unist-util-generated: 1.1.6 unist-util-position: 3.1.0 unist-util-visit: 2.0.3 - dev: true - /mdast-util-to-hast@13.0.2: - resolution: {integrity: sha512-U5I+500EOOw9e3ZrclN3Is3fRpw8c19SMyNZlZ2IS+7vLsNzb2Om11VpIVOR+/0137GhZsFEF6YiKD5+0Hr2Og==} + mdast-util-to-hast@13.0.2: dependencies: '@types/hast': 3.0.1 '@types/mdast': 4.0.1 @@ -16818,10 +21062,8 @@ packages: trim-lines: 3.0.1 unist-util-position: 5.0.0 unist-util-visit: 5.0.0 - dev: true - /mdast-util-to-markdown@2.1.0: - resolution: {integrity: sha512-SR2VnIEdVNCJbP6y7kVTJgPLifdr8WEU440fQec7qHoHOUz/oJ2jmNRqdDQ3rbiStOXb2mCDGTuwsK5OPUgYlQ==} + mdast-util-to-markdown@2.1.0: dependencies: '@types/mdast': 4.0.1 '@types/unist': 3.0.0 @@ -16831,33 +21073,20 @@ packages: micromark-util-decode-string: 2.0.0 unist-util-visit: 5.0.0 zwitch: 2.0.2 - dev: true - /mdast-util-to-string@4.0.0: - resolution: {integrity: sha512-0H44vDimn51F0YwvxSJSm0eCDOJTRlmN0R1yBh4HLj9wiV1Dn0QoXGbvFAWj2hSItVTlCmBF1hqKlIyUBVFLPg==} + mdast-util-to-string@4.0.0: dependencies: '@types/mdast': 4.0.1 - dev: true - /mdn-data@2.0.14: - resolution: {integrity: sha512-dn6wd0uw5GsdswPFfsgMp5NSB0/aDe6fK94YJV/AJDYXL6HVLWBsxeq7js7Ad+mU2K9LAlwpk6kN2D5mwCPVow==} - dev: true + mdn-data@2.0.14: {} - /mdn-data@2.0.30: - resolution: {integrity: sha512-GaqWWShW4kv/G9IEucWScBx9G1/vsFZZJUO+tD26M8J8z3Kw5RDQjaoZe03YAClgeS/SWPOcb4nkFBTEi5DUEA==} - dev: true + mdn-data@2.0.30: {} - /mdurl@1.0.1: - resolution: {integrity: sha512-/sKlQJCBYVY9Ers9hqzKou4H6V5UWc/M59TH2dvkt+84itfnq7uFOMLpOiOS4ujvHP4etln18fmIxA5R5fll0g==} - dev: true + mdurl@1.0.1: {} - /media-typer@0.3.0: - resolution: {integrity: sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g=} - engines: {node: '>= 0.6'} + media-typer@0.3.0: {} - /meow@10.1.5: - resolution: {integrity: sha512-/d+PQ4GKmGvM9Bee/DPa8z3mXs/pkvJE2KEThngVNOqtmljC6K7NMPxtc2JeZYTmpWb9k/TmxjeL18ez3h7vCw==} - engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + meow@10.1.5: dependencies: '@types/minimist': 1.2.2 camelcase-keys: 7.0.2 @@ -16871,16 +21100,10 @@ packages: trim-newlines: 4.1.1 type-fest: 1.4.0 yargs-parser: 20.2.9 - dev: true - /meow@12.1.1: - resolution: {integrity: sha512-BhXM0Au22RwUneMPwSCnyhTOizdWoIEPU9sp0Aqa1PnDMR5Wv2FGXYDjuzJEIX+Eo2Rb8xuYe5jrnm5QowQFkw==} - engines: {node: '>=16.10'} - dev: true + meow@12.1.1: {} - /meow@6.1.1: - resolution: {integrity: sha512-3YffViIt2QWgTy6Pale5QpopX/IvU3LPL03jOTqp6pGj3VjesdO/U8CuHMKpnQr4shCNCM5fd5XFFvIIl6JBHg==} - engines: {node: '>=8'} + meow@6.1.1: dependencies: '@types/minimist': 1.2.2 camelcase-keys: 6.2.2 @@ -16893,27 +21116,16 @@ packages: trim-newlines: 3.0.1 type-fest: 0.13.1 yargs-parser: 18.1.3 - dev: true - /merge-descriptors@1.0.1: - resolution: {integrity: sha512-cCi6g3/Zr1iqQi6ySbseM1Xvooa98N0w31jzUYrXPX2xqObmFGHJ0tQ5u74H3mVh7wLouTseZyYIq39g8cNp1w==} - dev: true + merge-descriptors@1.0.1: {} - /merge-stream@2.0.0: - resolution: {integrity: sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==} - dev: true + merge-stream@2.0.0: {} - /merge2@1.4.1: - resolution: {integrity: sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==} - engines: {node: '>= 8'} - dev: true + merge2@1.4.1: {} - /methods@1.1.2: - resolution: {integrity: sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w==} - engines: {node: '>= 0.6'} + methods@1.1.2: {} - /micromark-core-commonmark@2.0.0: - resolution: {integrity: sha512-jThOz/pVmAYUtkroV3D5c1osFXAMv9e0ypGDOIZuCeAe91/sD6BoE2Sjzt30yuXtwOYUmySOhMas/PVyh02itA==} + micromark-core-commonmark@2.0.0: dependencies: decode-named-character-reference: 1.0.1 devlop: 1.1.0 @@ -16931,19 +21143,15 @@ packages: micromark-util-subtokenize: 2.0.0 micromark-util-symbol: 2.0.0 micromark-util-types: 2.0.0 - dev: true - /micromark-extension-gfm-autolink-literal@2.0.0: - resolution: {integrity: sha512-rTHfnpt/Q7dEAK1Y5ii0W8bhfJlVJFnJMHIPisfPK3gpVNuOP0VnRl96+YJ3RYWV/P4gFeQoGKNlT3RhuvpqAg==} + micromark-extension-gfm-autolink-literal@2.0.0: dependencies: micromark-util-character: 2.0.1 micromark-util-sanitize-uri: 2.0.0 micromark-util-symbol: 2.0.0 micromark-util-types: 2.0.0 - dev: true - /micromark-extension-gfm-footnote@2.0.0: - resolution: {integrity: sha512-6Rzu0CYRKDv3BfLAUnZsSlzx3ak6HAoI85KTiijuKIz5UxZxbUI+pD6oHgw+6UtQuiRwnGRhzMmPRv4smcz0fg==} + micromark-extension-gfm-footnote@2.0.0: dependencies: devlop: 1.1.0 micromark-core-commonmark: 2.0.0 @@ -16953,10 +21161,8 @@ packages: micromark-util-sanitize-uri: 2.0.0 micromark-util-symbol: 2.0.0 micromark-util-types: 2.0.0 - dev: true - /micromark-extension-gfm-strikethrough@2.0.0: - resolution: {integrity: sha512-c3BR1ClMp5fxxmwP6AoOY2fXO9U8uFMKs4ADD66ahLTNcwzSCyRVU4k7LPV5Nxo/VJiR4TdzxRQY2v3qIUceCw==} + micromark-extension-gfm-strikethrough@2.0.0: dependencies: devlop: 1.1.0 micromark-util-chunked: 2.0.0 @@ -16964,36 +21170,28 @@ packages: micromark-util-resolve-all: 2.0.0 micromark-util-symbol: 2.0.0 micromark-util-types: 2.0.0 - dev: true - /micromark-extension-gfm-table@2.0.0: - resolution: {integrity: sha512-PoHlhypg1ItIucOaHmKE8fbin3vTLpDOUg8KAr8gRCF1MOZI9Nquq2i/44wFvviM4WuxJzc3demT8Y3dkfvYrw==} + micromark-extension-gfm-table@2.0.0: dependencies: devlop: 1.1.0 micromark-factory-space: 2.0.0 micromark-util-character: 2.0.1 micromark-util-symbol: 2.0.0 micromark-util-types: 2.0.0 - dev: true - /micromark-extension-gfm-tagfilter@2.0.0: - resolution: {integrity: sha512-xHlTOmuCSotIA8TW1mDIM6X2O1SiX5P9IuDtqGonFhEK0qgRI4yeC6vMxEV2dgyr2TiD+2PQ10o+cOhdVAcwfg==} + micromark-extension-gfm-tagfilter@2.0.0: dependencies: micromark-util-types: 2.0.0 - dev: true - /micromark-extension-gfm-task-list-item@2.0.1: - resolution: {integrity: sha512-cY5PzGcnULaN5O7T+cOzfMoHjBW7j+T9D2sucA5d/KbsBTPcYdebm9zUd9zzdgJGCwahV+/W78Z3nbulBYVbTw==} + micromark-extension-gfm-task-list-item@2.0.1: dependencies: devlop: 1.1.0 micromark-factory-space: 2.0.0 micromark-util-character: 2.0.1 micromark-util-symbol: 2.0.0 micromark-util-types: 2.0.0 - dev: true - /micromark-extension-gfm@3.0.0: - resolution: {integrity: sha512-vsKArQsicm7t0z2GugkCKtZehqUm31oeGBV/KVSorWSy8ZlNAv7ytjFhvaryUiCUJYqs+NoE6AFhpQvBTM6Q4w==} + micromark-extension-gfm@3.0.0: dependencies: micromark-extension-gfm-autolink-literal: 2.0.0 micromark-extension-gfm-footnote: 2.0.0 @@ -17003,140 +21201,100 @@ packages: micromark-extension-gfm-task-list-item: 2.0.1 micromark-util-combine-extensions: 2.0.0 micromark-util-types: 2.0.0 - dev: true - /micromark-factory-destination@2.0.0: - resolution: {integrity: sha512-j9DGrQLm/Uhl2tCzcbLhy5kXsgkHUrjJHg4fFAeoMRwJmJerT9aw4FEhIbZStWN8A3qMwOp1uzHr4UL8AInxtA==} + micromark-factory-destination@2.0.0: dependencies: micromark-util-character: 2.0.1 micromark-util-symbol: 2.0.0 micromark-util-types: 2.0.0 - dev: true - /micromark-factory-label@2.0.0: - resolution: {integrity: sha512-RR3i96ohZGde//4WSe/dJsxOX6vxIg9TimLAS3i4EhBAFx8Sm5SmqVfR8E87DPSR31nEAjZfbt91OMZWcNgdZw==} + micromark-factory-label@2.0.0: dependencies: devlop: 1.1.0 micromark-util-character: 2.0.1 micromark-util-symbol: 2.0.0 micromark-util-types: 2.0.0 - dev: true - /micromark-factory-space@2.0.0: - resolution: {integrity: sha512-TKr+LIDX2pkBJXFLzpyPyljzYK3MtmllMUMODTQJIUfDGncESaqB90db9IAUcz4AZAJFdd8U9zOp9ty1458rxg==} + micromark-factory-space@2.0.0: dependencies: micromark-util-character: 2.0.1 micromark-util-types: 2.0.0 - dev: true - /micromark-factory-title@2.0.0: - resolution: {integrity: sha512-jY8CSxmpWLOxS+t8W+FG3Xigc0RDQA9bKMY/EwILvsesiRniiVMejYTE4wumNc2f4UbAa4WsHqe3J1QS1sli+A==} + micromark-factory-title@2.0.0: dependencies: micromark-factory-space: 2.0.0 micromark-util-character: 2.0.1 micromark-util-symbol: 2.0.0 micromark-util-types: 2.0.0 - dev: true - /micromark-factory-whitespace@2.0.0: - resolution: {integrity: sha512-28kbwaBjc5yAI1XadbdPYHX/eDnqaUFVikLwrO7FDnKG7lpgxnvk/XGRhX/PN0mOZ+dBSZ+LgunHS+6tYQAzhA==} + micromark-factory-whitespace@2.0.0: dependencies: micromark-factory-space: 2.0.0 micromark-util-character: 2.0.1 micromark-util-symbol: 2.0.0 micromark-util-types: 2.0.0 - dev: true - /micromark-util-character@2.0.1: - resolution: {integrity: sha512-3wgnrmEAJ4T+mGXAUfMvMAbxU9RDG43XmGce4j6CwPtVxB3vfwXSZ6KhFwDzZ3mZHhmPimMAXg71veiBGzeAZw==} + micromark-util-character@2.0.1: dependencies: micromark-util-symbol: 2.0.0 micromark-util-types: 2.0.0 - dev: true - /micromark-util-chunked@2.0.0: - resolution: {integrity: sha512-anK8SWmNphkXdaKgz5hJvGa7l00qmcaUQoMYsBwDlSKFKjc6gjGXPDw3FNL3Nbwq5L8gE+RCbGqTw49FK5Qyvg==} + micromark-util-chunked@2.0.0: dependencies: micromark-util-symbol: 2.0.0 - dev: true - /micromark-util-classify-character@2.0.0: - resolution: {integrity: sha512-S0ze2R9GH+fu41FA7pbSqNWObo/kzwf8rN/+IGlW/4tC6oACOs8B++bh+i9bVyNnwCcuksbFwsBme5OCKXCwIw==} + micromark-util-classify-character@2.0.0: dependencies: micromark-util-character: 2.0.1 micromark-util-symbol: 2.0.0 micromark-util-types: 2.0.0 - dev: true - /micromark-util-combine-extensions@2.0.0: - resolution: {integrity: sha512-vZZio48k7ON0fVS3CUgFatWHoKbbLTK/rT7pzpJ4Bjp5JjkZeasRfrS9wsBdDJK2cJLHMckXZdzPSSr1B8a4oQ==} + micromark-util-combine-extensions@2.0.0: dependencies: micromark-util-chunked: 2.0.0 micromark-util-types: 2.0.0 - dev: true - /micromark-util-decode-numeric-character-reference@2.0.0: - resolution: {integrity: sha512-pIgcsGxpHEtTG/rPJRz/HOLSqp5VTuIIjXlPI+6JSDlK2oljApusG6KzpS8AF0ENUMCHlC/IBb5B9xdFiVlm5Q==} + micromark-util-decode-numeric-character-reference@2.0.0: dependencies: micromark-util-symbol: 2.0.0 - dev: true - /micromark-util-decode-string@2.0.0: - resolution: {integrity: sha512-r4Sc6leeUTn3P6gk20aFMj2ntPwn6qpDZqWvYmAG6NgvFTIlj4WtrAudLi65qYoaGdXYViXYw2pkmn7QnIFasA==} + micromark-util-decode-string@2.0.0: dependencies: decode-named-character-reference: 1.0.1 micromark-util-character: 2.0.1 micromark-util-decode-numeric-character-reference: 2.0.0 micromark-util-symbol: 2.0.0 - dev: true - /micromark-util-encode@2.0.0: - resolution: {integrity: sha512-pS+ROfCXAGLWCOc8egcBvT0kf27GoWMqtdarNfDcjb6YLuV5cM3ioG45Ys2qOVqeqSbjaKg72vU+Wby3eddPsA==} - dev: true + micromark-util-encode@2.0.0: {} - /micromark-util-html-tag-name@2.0.0: - resolution: {integrity: sha512-xNn4Pqkj2puRhKdKTm8t1YHC/BAjx6CEwRFXntTaRf/x16aqka6ouVoutm+QdkISTlT7e2zU7U4ZdlDLJd2Mcw==} - dev: true + micromark-util-html-tag-name@2.0.0: {} - /micromark-util-normalize-identifier@2.0.0: - resolution: {integrity: sha512-2xhYT0sfo85FMrUPtHcPo2rrp1lwbDEEzpx7jiH2xXJLqBuy4H0GgXk5ToU8IEwoROtXuL8ND0ttVa4rNqYK3w==} + micromark-util-normalize-identifier@2.0.0: dependencies: micromark-util-symbol: 2.0.0 - dev: true - /micromark-util-resolve-all@2.0.0: - resolution: {integrity: sha512-6KU6qO7DZ7GJkaCgwBNtplXCvGkJToU86ybBAUdavvgsCiG8lSSvYxr9MhwmQ+udpzywHsl4RpGJsYWG1pDOcA==} + micromark-util-resolve-all@2.0.0: dependencies: micromark-util-types: 2.0.0 - dev: true - /micromark-util-sanitize-uri@2.0.0: - resolution: {integrity: sha512-WhYv5UEcZrbAtlsnPuChHUAsu/iBPOVaEVsntLBIdpibO0ddy8OzavZz3iL2xVvBZOpolujSliP65Kq0/7KIYw==} + micromark-util-sanitize-uri@2.0.0: dependencies: micromark-util-character: 2.0.1 micromark-util-encode: 2.0.0 micromark-util-symbol: 2.0.0 - dev: true - /micromark-util-subtokenize@2.0.0: - resolution: {integrity: sha512-vc93L1t+gpR3p8jxeVdaYlbV2jTYteDje19rNSS/H5dlhxUYll5Fy6vJ2cDwP8RnsXi818yGty1ayP55y3W6fg==} + micromark-util-subtokenize@2.0.0: dependencies: devlop: 1.1.0 micromark-util-chunked: 2.0.0 micromark-util-symbol: 2.0.0 micromark-util-types: 2.0.0 - dev: true - /micromark-util-symbol@2.0.0: - resolution: {integrity: sha512-8JZt9ElZ5kyTnO94muPxIGS8oyElRJaiJO8EzV6ZSyGQ1Is8xwl4Q45qU5UOg+bGH4AikWziz0iN4sFLWs8PGw==} - dev: true + micromark-util-symbol@2.0.0: {} - /micromark-util-types@2.0.0: - resolution: {integrity: sha512-oNh6S2WMHWRZrmutsRmDDfkzKtxF+bc2VxLC9dvtrDIRFln627VsFP6fLMgTryGDljgLPjkrzQSDcPrjPyDJ5w==} - dev: true + micromark-util-types@2.0.0: {} - /micromark@4.0.0: - resolution: {integrity: sha512-o/sd0nMof8kYff+TqcDx3VSrgBTcZpSvYcAHIfHhv5VAuNmisCxjhx6YmxS8PFEpb9z5WKWKPdzf0jM23ro3RQ==} + micromark@4.0.0: dependencies: '@types/debug': 4.1.7 debug: 4.3.4 @@ -17157,165 +21315,87 @@ packages: micromark-util-types: 2.0.0 transitivePeerDependencies: - supports-color - dev: true - /micromatch@4.0.5: - resolution: {integrity: sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==} - engines: {node: '>=8.6'} + micromatch@4.0.5: dependencies: braces: 3.0.2 picomatch: 2.3.1 - dev: true - /mime-db@1.52.0: - resolution: {integrity: sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==} - engines: {node: '>= 0.6'} + mime-db@1.52.0: {} - /mime-types@2.1.35: - resolution: {integrity: sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==} - engines: {node: '>= 0.6'} + mime-types@2.1.35: dependencies: mime-db: 1.52.0 - /mime@1.6.0: - resolution: {integrity: sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==} - engines: {node: '>=4'} - hasBin: true - dev: true + mime@1.6.0: {} - /mime@2.6.0: - resolution: {integrity: sha512-USPkMeET31rOMiarsBNIHZKLGgvKc/LrjofAnBlOttf5ajRvqiRA8QsenbcooctK6d6Ts6aqZXBA+XbkKthiQg==} - engines: {node: '>=4.0.0'} - hasBin: true - dev: true + mime@2.6.0: {} - /mime@3.0.0: - resolution: {integrity: sha512-jSCU7/VB1loIWBZe14aEYHU/+1UMEHoaO7qxCOVJOw9GgH72VAWppxNcjU+x9a2k3GSIBXNKxXQFqRvvZ7vr3A==} - engines: {node: '>=10.0.0'} - hasBin: true - dev: false + mime@3.0.0: {} - /mimic-fn@2.1.0: - resolution: {integrity: sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==} - engines: {node: '>=6'} + mimic-fn@2.1.0: {} - /mimic-fn@4.0.0: - resolution: {integrity: sha512-vqiC06CuhBTUdZH+RYl8sFrL096vA45Ok5ISO6sE/Mr1jRbGH4Csnhi8f3wKVl7x8mO4Au7Ir9D3Oyv1VYMFJw==} - engines: {node: '>=12'} - dev: true + mimic-fn@4.0.0: {} - /mimic-response@3.1.0: - resolution: {integrity: sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ==} - engines: {node: '>=10'} - dev: false + mimic-response@3.1.0: {} - /mimic-response@4.0.0: - resolution: {integrity: sha512-e5ISH9xMYU0DzrT+jl8q2ze9D6eWBto+I8CNpe+VI+K2J/F/k3PdkdTdz4wvGVH4NTpo+NRYTVIuMQEMMcsLqg==} - engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} - dev: false + mimic-response@4.0.0: {} - /min-indent@1.0.1: - resolution: {integrity: sha512-I9jwMn07Sy/IwOj3zVkVik2JTvgpaykDZEigL6Rx6N9LbMywwUSMtxET+7lVoDLLd3O3IXwJwvuuns8UB/HeAg==} - engines: {node: '>=4'} - dev: true + min-indent@1.0.1: {} - /minimatch@3.1.2: - resolution: {integrity: sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==} + minimatch@3.1.2: dependencies: brace-expansion: 1.1.11 - dev: true - /minimatch@5.1.6: - resolution: {integrity: sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==} - engines: {node: '>=10'} + minimatch@5.1.6: dependencies: brace-expansion: 2.0.1 - dev: true - /minimatch@9.0.4: - resolution: {integrity: sha512-KqWh+VchfxcMNRAJjj2tnsSJdNbHsVgnkBhTNrW7AjVo6OvLtxw8zfT9oLw1JSohlFzJ8jCoTgaoXvJ+kHt6fw==} - engines: {node: '>=16 || 14 >=14.17'} + minimatch@9.0.4: dependencies: brace-expansion: 2.0.1 - /minimist-options@4.1.0: - resolution: {integrity: sha512-Q4r8ghd80yhO/0j1O3B2BjweX3fiHg9cdOwjJd2J76Q135c+NDxGCqdYKQ1SKBuFfgWbAUzBfvYjPUEeNgqN1A==} - engines: {node: '>= 6'} + minimist-options@4.1.0: dependencies: arrify: 1.0.1 is-plain-obj: 1.1.0 kind-of: 6.0.3 - dev: true - /minimist@1.2.8: - resolution: {integrity: sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==} - dev: true + minimist@1.2.8: {} - /minipass@4.2.8: - resolution: {integrity: sha512-fNzuVyifolSLFL4NzpF+wEF4qrgqaaKX0haXPQEdQ7NKAN+WecoKMHV09YcuL/DHxrUsYQOK3MiuDf7Ip2OXfQ==} - engines: {node: '>=8'} - dev: true + minipass@4.2.8: {} - /minipass@5.0.0: - resolution: {integrity: sha512-3FnjYuehv9k6ovOEbyOswadCDPX1piCfhV8ncmYtHOjuPwylVWsghTLo7rabjC3Rx5xD4HDx8Wm1xnMF7S5qFQ==} - engines: {node: '>=8'} - dev: false + minipass@5.0.0: {} - /minipass@7.0.4: - resolution: {integrity: sha512-jYofLM5Dam9279rdkWzqHozUo4ybjdZmCsDHePy5V/PbBcVMiSZR97gmAy45aqi8CK1lG2ECd356FU86avfwUQ==} - engines: {node: '>=16 || 14 >=14.17'} - dev: false + minipass@7.0.4: {} - /minizlib@3.0.1: - resolution: {integrity: sha512-umcy022ILvb5/3Djuu8LWeqUa8D68JaBzlttKeMWen48SjabqS3iY5w/vzeMzMUNhLDifyhbOwKDSznB1vvrwg==} - engines: {node: '>= 18'} + minizlib@3.0.1: dependencies: minipass: 7.0.4 rimraf: 5.0.5 - dev: false - /mitt@3.0.1: - resolution: {integrity: sha512-vKivATfr97l2/QBCYAkXYDbrIWPM2IIKEl7YPhjCvKlG3kE2gm+uBo6nEXK3M5/Ffh/FLpKExzOQ3JJoJGFKBw==} - dev: true + mitt@3.0.1: {} - /mixme@0.5.4: - resolution: {integrity: sha512-3KYa4m4Vlqx98GPdOHghxSdNtTvcP8E0kkaJ5Dlh+h2DRzF7zpuVVcA8B0QpKd11YJeP9QQ7ASkKzOeu195Wzw==} - engines: {node: '>= 8.0.0'} - dev: true + mixme@0.5.4: {} - /mkdirp@3.0.1: - resolution: {integrity: sha512-+NsyUUAZDmo6YVHzL/stxSu3t9YS1iljliy3BSDrXJ/dkn1KYdmtZODGGjLcc9XLgVVpH4KshHB8XmZgMhaBXg==} - engines: {node: '>=10'} - hasBin: true - dev: false + mkdirp@3.0.1: {} - /mlly@1.6.1: - resolution: {integrity: sha512-vLgaHvaeunuOXHSmEbZ9izxPx3USsk8KCQ8iC+aTlp5sKRSoZvwhHh5L9VbKSaVC6sJDqbyohIS76E2VmHIPAA==} + mlly@1.6.1: 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: - resolution: {integrity: sha512-ySViT69/76t8VhE1xXHK6Ch4NcDd26gx0MzKXLO+F7NOtnqH68d9zF94nT8ZWSxXh8ELOERsnJO/sWt1xZYw5A==} - dev: false + module-details-from-path@1.0.3: {} - /monaco-editor@0.47.0: - resolution: {integrity: sha512-VabVvHvQ9QmMwXu4du008ZDuyLnHs9j7ThVFsiJoXSOQk18+LF89N4ADzPbFenm0W4V2bGHnFBztIRQTgBfxzw==} - dev: true + monaco-editor@0.47.0: {} - /ms@2.1.2: - resolution: {integrity: sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==} + ms@2.1.2: {} - /ms@2.1.3: - resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==} + ms@2.1.3: {} - /msgpackr-extract@3.0.2: - resolution: {integrity: sha512-SdzXp4kD/Qf8agZ9+iTu6eql0m3kWm1A2y1hkpTeVNENutaB0BwHlSvAIaMxwntmRUAUjon2V4L8Z/njd0Ct8A==} - hasBin: true - requiresBuild: true + msgpackr-extract@3.0.2: dependencies: node-gyp-build-optional-packages: 5.0.7 optionalDependencies: @@ -17325,89 +21405,48 @@ packages: '@msgpackr-extract/msgpackr-extract-linux-arm64': 3.0.2 '@msgpackr-extract/msgpackr-extract-linux-x64': 3.0.2 '@msgpackr-extract/msgpackr-extract-win32-x64': 3.0.2 - dev: true optional: true - /msgpackr@1.8.5: - resolution: {integrity: sha512-mpPs3qqTug6ahbblkThoUY2DQdNXcm4IapwOS3Vm/87vmpzLVelvp9h3It1y9l1VPpiFLV11vfOXnmeEwiIXwg==} + msgpackr@1.8.5: optionalDependencies: msgpackr-extract: 3.0.2 - dev: true - /mute-stream@0.0.8: - resolution: {integrity: sha512-nnbWWOkoWyUsTjKrhgD0dcz22mdkSnpYqbEjIm2nhwhuxlSkpywJmBo8h0ZqJdkp73mb90SssHkN4rsRaBAfAA==} - dev: false + mute-stream@0.0.8: {} - /nanoid@3.3.6: - resolution: {integrity: sha512-BGcqMMJuToF7i1rt+2PWSNVnWIkGCU78jBG3RxO/bZlnZPK2Cmi2QaffxGO/2RvWi9sL+FAiRiXMgsyxQ1DIDA==} - engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1} - hasBin: true - dev: true + nanoid@3.3.6: {} - /nanoid@3.3.7: - resolution: {integrity: sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g==} - engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1} - hasBin: true - dev: true + nanoid@3.3.7: {} - /nanoid@4.0.2: - resolution: {integrity: sha512-7ZtY5KTCNheRGfEFxnedV5zFiORN1+Y1N6zvPTnHQd8ENUvfaDBeuJDZb2bN/oXwXxu3qkTXDzy57W5vAmDTBw==} - engines: {node: ^14 || ^16 || >=18} - hasBin: true + nanoid@4.0.2: {} - /nanoid@5.0.1: - resolution: {integrity: sha512-vWeVtV5Cw68aML/QaZvqN/3QQXc6fBfIieAlu05m7FZW2Dgb+3f0xc0TTxuJW+7u30t7iSDTV/j3kVI0oJqIfQ==} - engines: {node: ^18 || >=20} - hasBin: true + nanoid@5.0.1: {} - /nanoid@5.0.7: - resolution: {integrity: sha512-oLxFY2gd2IqnjcYyOXD8XGCftpGtZP2AbHbOkthDkvRywH5ayNtPVy9YlOPcHckXzbLTCHpkb7FB+yuxKV13pQ==} - engines: {node: ^18 || >=20} - hasBin: true - dev: false + nanoid@5.0.7: {} - /natural-compare@1.4.0: - resolution: {integrity: sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==} - dev: true + natural-compare@1.4.0: {} - /negotiator@0.6.2: - resolution: {integrity: sha512-hZXc7K2e+PgeI1eDBe/10Ard4ekbfrrqG8Ep+8Jmf4JID2bNg7NvCPOZN+kfF574pFQI7mum2AUqDidoKqcTOw==} - engines: {node: '>= 0.6'} + negotiator@0.6.2: {} - /negotiator@0.6.3: - resolution: {integrity: sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==} - engines: {node: '>= 0.6'} + negotiator@0.6.3: {} - /netmask@2.0.2: - resolution: {integrity: sha512-dBpDMdxv9Irdq66304OLfEmQ9tbNRFnFTuZiLo+bD+r332bBmMJ8GBLXklIXXgxd3+v9+KUnZaUR5PJMa75Gsg==} - engines: {node: '>= 0.4.0'} - dev: true + netmask@2.0.2: {} - /nise@5.1.5: - resolution: {integrity: sha512-VJuPIfUFaXNRzETTQEEItTOP8Y171ijr+JLq42wHes3DiryR8vT+1TXQW/Rx8JNUhyYYWyIvjXTU6dOhJcs9Nw==} + nise@5.1.5: dependencies: '@sinonjs/commons': 2.0.0 '@sinonjs/fake-timers': 10.3.0 '@sinonjs/text-encoding': 0.7.2 just-extend: 4.2.1 path-to-regexp: 1.8.0 - dev: true - /no-case@3.0.4: - resolution: {integrity: sha512-fgAN3jGAh+RoxUGZHTSOLJIqUc2wmoBwGR4tbpNAKmmovFoWq0OdRkb0VkldReO2a2iBT/OEulG9XSUc10r3zg==} + no-case@3.0.4: dependencies: lower-case: 2.0.2 tslib: 2.6.2 - dev: false - /no-case@4.0.0: - resolution: {integrity: sha512-WmS3EUGw+vXHlTgiUPi3NzbZNwH6+uGX0QLGgqG+aFSJ5rkX/Ee0nuwHBJfZTfQwwR8lGO819NEIwQ7CGhkdEQ==} - deprecated: Use `change-case` - dev: false + no-case@4.0.0: {} - /nock@13.3.1: - resolution: {integrity: sha512-vHnopocZuI93p2ccivFyGuUfzjq2fxNyNurp7816mlT5V5HF4SzXu8lvLrVzBbNqzs+ODooZ6OksuSUNM7Njkw==} - engines: {node: '>= 10.13'} + nock@13.3.1: dependencies: debug: 4.3.4 json-stringify-safe: 5.0.1 @@ -17415,82 +21454,42 @@ packages: propagate: 2.0.1 transitivePeerDependencies: - supports-color - dev: true - /nock@14.0.0-beta.5: - resolution: {integrity: sha512-u255tf4DYvyErTlPZA9uTfXghiZZy+NflUOFONPVKZ5tP0yaHwKig28zyFOLhu8y5YcCRC+V5vDk4HHileh2iw==} - engines: {node: '>= 18'} + nock@14.0.0-beta.5: dependencies: json-stringify-safe: 5.0.1 propagate: 2.0.1 - dev: true - /nock@14.0.0-beta.6: - resolution: {integrity: sha512-b7lc7qvj1dQzxtbU7TqyTMnKbNKwGQd585xsRtcCZOv3I/yOK9Vwv4nOgnLFxFtX9m1yjhQDRbgqFCqNh9HuEw==} - engines: {node: '>= 18'} + nock@14.0.0-beta.6: dependencies: json-stringify-safe: 5.0.1 propagate: 2.0.1 - dev: true - /node-addon-api@3.2.1: - resolution: {integrity: sha512-mmcei9JghVNDYydghQmeDX8KoAm0FAiYyIcUt/N4nhyAipB17pllZQDOJD2fotxABnt4Mdz+dKTO7eftLg4d0A==} - dev: true + node-addon-api@3.2.1: {} - /node-addon-api@4.3.0: - resolution: {integrity: sha512-73sE9+3UaLYYFmDsFZnqCInzPyh3MqIwZO9cw58yIqAZhONrrabrYyYe3TuIqtIiOuTXVhsGau8hcrhhwSsDIQ==} - dev: true + node-addon-api@4.3.0: {} - /node-fetch@2.7.0: - resolution: {integrity: sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==} - engines: {node: 4.x || >=6.0.0} - peerDependencies: - encoding: ^0.1.0 - peerDependenciesMeta: - encoding: - optional: true + node-fetch@2.7.0: dependencies: whatwg-url: 5.0.0 - dev: false - /node-forge@1.3.1: - resolution: {integrity: sha512-dPEtOeMvF9VMcYV/1Wb8CPoVAXtp6MKMlcbAt4ddqmGqUJ6fQZFXkNZNkNlfevtNkGtaSoXf/vNNNSvgrdXwtA==} - engines: {node: '>= 6.13.0'} - dev: false + node-forge@1.3.1: {} - /node-gyp-build-optional-packages@5.0.6: - resolution: {integrity: sha512-2ZJErHG4du9G3/8IWl/l9Bp5BBFy63rno5GVmjQijvTuUZKsl6g8RB4KH/x3NLcV5ZBb4GsXmAuTYr6dRml3Gw==} - hasBin: true - dev: true + node-gyp-build-optional-packages@5.0.6: {} - /node-gyp-build-optional-packages@5.0.7: - resolution: {integrity: sha512-YlCCc6Wffkx0kHkmam79GKvDQ6x+QZkMjFGrIMxgFNILFvGSbCp2fCBC55pGTT9gVaz8Na5CLmxt/urtzRv36w==} - hasBin: true - requiresBuild: true - dev: true + node-gyp-build-optional-packages@5.0.7: optional: true - /node-gyp-build-optional-packages@5.1.1: - resolution: {integrity: sha512-+P72GAjVAbTxjjwUmwjVrqrdZROD4nf8KgpBoDxqXXTiYZZt/ud60dE5yvCSr9lRO8e8yv6kgJIC0K0PfZFVQw==} - hasBin: true - requiresBuild: true + node-gyp-build-optional-packages@5.1.1: dependencies: detect-libc: 2.0.2 - dev: false optional: true - /node-gyp-build@4.5.0: - resolution: {integrity: sha512-2iGbaQBV+ITgCz76ZEjmhUKAKVf7xfY1sRl4UiKQspfZMH2h06SyhNsnSVy50cwkFQDGLyif6m/6uFXHkOZ6rg==} - hasBin: true - dev: true + node-gyp-build@4.5.0: {} - /node-int64@0.4.0: - resolution: {integrity: sha512-O5lz91xSOeoXP6DulyHfllpq+Eg00MWitZIbtPfoSEvqIHdl5gfcY6hYzDWnj0qD5tz52PI08u9qUvSVeUBeHw==} - dev: true + node-int64@0.4.0: {} - /node-mocks-http@1.12.1: - resolution: {integrity: sha512-jrA7Sn3qI6GsHgWtUW3gMj0vO6Yz0nJjzg3jRZYjcfj4tzi8oWPauDK1qHVJoAxTbwuDHF1JiM9GISZ/ocI/ig==} - engines: {node: '>=0.6'} + node-mocks-http@1.12.1: dependencies: accepts: 1.3.8 content-disposition: 0.5.4 @@ -17502,35 +21501,20 @@ packages: parseurl: 1.3.3 range-parser: 1.2.1 type-is: 1.6.18 - dev: true - /node-releases@2.0.14: - resolution: {integrity: sha512-y10wOWt8yZpqXmOgRo77WaHEmhYQYGNA6y421PKsKYWEK8aW+cqAphborZDhqfyKrbZEN92CN1X2KbafY2s7Yw==} - dev: true + node-releases@2.0.14: {} - /node-releases@2.0.6: - resolution: {integrity: sha512-PiVXnNuFm5+iYkLBNeq5211hvO38y63T0i2KKh2KnUs3RpzJ+JtODFjkD8yjLwnDkTYF1eKXheUwdssR+NRZdg==} - dev: true + node-releases@2.0.6: {} - /node-rsa@1.1.1: - resolution: {integrity: sha512-Jd4cvbJMryN21r5HgxQOpMEqv+ooke/korixNNK3mGqfGJmy0M77WDDzo/05969+OkMy3XW1UuZsSmW9KQm7Fw==} + node-rsa@1.1.1: dependencies: asn1: 0.2.6 - dev: false - /node-xmllint@1.0.0: - resolution: {integrity: sha512-71UV2HRUP+djvHpdyatiuv+Y1o8hI4ZI7bMfuuoACMLR1JJCErM4WXAclNeHd6BgHXkqeqnnAk3wpDkSQWmFXw==} - dev: false + node-xmllint@1.0.0: {} - /nodemailer@6.9.9: - resolution: {integrity: sha512-dexTll8zqQoVJEZPwQAKzxxtFn0qTnjdQTchoU6Re9BUUGBJiOy3YMn/0ShTW6J5M0dfQ1NeDeRTTl4oIWgQMA==} - engines: {node: '>=6.0.0'} - dev: false + nodemailer@6.9.9: {} - /nodemon@3.0.0: - resolution: {integrity: sha512-yU9NSp3n+DUSt3S2LmtXss+4kOsmC8ZLpXeGe5mKuLdqkoSRwmaplk2lo5cmve7TPw5MgMcd2cazL0KpUscoSQ==} - engines: {node: '>=10'} - hasBin: true + nodemon@3.0.0: dependencies: chokidar: 3.5.3 debug: 3.2.7(supports-color@5.5.0) @@ -17542,165 +21526,103 @@ packages: supports-color: 5.5.0 touch: 3.1.0 undefsafe: 2.0.5 - dev: true - /nopt@1.0.10: - resolution: {integrity: sha512-NWmpvLSqUrgrAC9HCuxEvb+PSloHpqVu+FqcO4eeF2h5qYRhA7ev6KvelyQAKtegUbC6RypJnlEOhd8vloNKYg==} - hasBin: true + nopt@1.0.10: dependencies: abbrev: 1.1.1 - dev: true - /normalize-package-data@2.5.0: - resolution: {integrity: sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==} + normalize-package-data@2.5.0: dependencies: hosted-git-info: 2.8.9 resolve: 1.22.8 semver: 5.7.2 validate-npm-package-license: 3.0.4 - dev: true - /normalize-package-data@3.0.3: - resolution: {integrity: sha512-p2W1sgqij3zMMyRC067Dg16bfzVH+w7hyegmpIvZ4JNjqtGOVAIvLmjBx3yP7YTe9vKJgkoNOPjwQGogDoMXFA==} - engines: {node: '>=10'} + normalize-package-data@3.0.3: dependencies: hosted-git-info: 4.1.0 is-core-module: 2.13.1 semver: 7.6.0 validate-npm-package-license: 3.0.4 - dev: true - /normalize-path@3.0.0: - resolution: {integrity: sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==} - engines: {node: '>=0.10.0'} - dev: true + normalize-path@3.0.0: {} - /normalize-url@8.0.0: - resolution: {integrity: sha512-uVFpKhj5MheNBJRTiMZ9pE/7hD1QTeEvugSJW/OmLzAp78PB5O6adfMNTvmfKhXBkvCzC+rqifWcVYpGFwTjnw==} - engines: {node: '>=14.16'} - dev: false + normalize-url@8.0.0: {} - /npm-run-path@4.0.1: - resolution: {integrity: sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==} - engines: {node: '>=8'} + npm-run-path@4.0.1: dependencies: path-key: 3.1.1 - dev: true - /npm-run-path@5.1.0: - resolution: {integrity: sha512-sJOdmRGrY2sjNTRMbSvluQqg+8X7ZK61yvzBEIDhz4f8z1TZFYABsqjjCBd/0PUNE9M6QDgHJXQkGUEm7Q+l9Q==} - engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + npm-run-path@5.1.0: dependencies: path-key: 4.0.0 - dev: true - /nth-check@2.1.1: - resolution: {integrity: sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w==} + nth-check@2.1.1: dependencies: boolbase: 1.0.0 - dev: true - /nullthrows@1.1.1: - resolution: {integrity: sha512-2vPPEi+Z7WqML2jZYddDIfy5Dqb0r2fze2zTxNNknZaFpVHU3mFB3R+DWeJWGVx0ecvttSGlJTI+WG+8Z4cDWw==} - dev: true + nullthrows@1.1.1: {} - /nwsapi@2.2.2: - resolution: {integrity: sha512-90yv+6538zuvUMnN+zCr8LuV6bPFdq50304114vJYJ8RDyK8D5O9Phpbd6SZWgI7PwzmmfN1upeOJlvybDSgCw==} - dev: true + nwsapi@2.2.2: {} - /obj-props@1.4.0: - resolution: {integrity: sha512-p7p/7ltzPDiBs6DqxOrIbtRdwxxVRBj5ROukeNb9RgA+fawhrz5n2hpNz8DDmYR//tviJSj7nUnlppGmONkjiQ==} - engines: {node: '>=0.10.0'} - dev: true + obj-props@1.4.0: {} - /object-assign@4.1.1: - resolution: {integrity: sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==} - engines: {node: '>=0.10.0'} - dev: true + object-assign@4.1.1: {} - /object-hash@3.0.0: - resolution: {integrity: sha512-RSn9F68PjH9HqtltsSnqYC1XXoWe9Bju5+213R98cNGttag9q9yAOTzdbsqvIa7aNm5WffBZFpWYr2aWrklWAw==} - engines: {node: '>= 6'} - dev: false + object-hash@3.0.0: {} - /object-inspect@1.13.1: - resolution: {integrity: sha512-5qoj1RUiKOMsCCNLV1CBiPYE10sziTsnmNxkAI/rZhiD63CF7IqdFGC/XzjWjpSgLf0LxXX3bDFIh0E18f6UhQ==} + object-inspect@1.13.1: {} - /object-keys@1.1.1: - resolution: {integrity: sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==} - engines: {node: '>= 0.4'} + object-keys@1.1.1: {} - /object.assign@4.1.4: - resolution: {integrity: sha512-1mxKf0e58bvyjSCtKYY4sRe9itRk3PJpquJOjeIkz885CczcI4IvJJDLPS72oowuSh+pBxUFROpX+TU++hxhZQ==} - engines: {node: '>= 0.4'} + object.assign@4.1.4: dependencies: call-bind: 1.0.7 define-properties: 1.1.4 has-symbols: 1.0.3 object-keys: 1.1.1 - dev: true - /object.assign@4.1.5: - resolution: {integrity: sha512-byy+U7gp+FVwmyzKPYhW2h5l3crpmGsxl7X2s8y43IgxvG4g3QZ6CffDtsNQy1WsmZpQbO+ybo0AlW7TY6DcBQ==} - engines: {node: '>= 0.4'} + object.assign@4.1.5: dependencies: call-bind: 1.0.7 define-properties: 1.2.1 has-symbols: 1.0.3 object-keys: 1.1.1 - dev: true - /object.entries@1.1.8: - resolution: {integrity: sha512-cmopxi8VwRIAw/fkijJohSfpef5PdN0pMQJN6VC/ZKvn0LIknWD8KtgY6KlQdEc4tIjcQ3HxSMmnvtzIscdaYQ==} - engines: {node: '>= 0.4'} + object.entries@1.1.8: dependencies: call-bind: 1.0.7 define-properties: 1.2.1 es-object-atoms: 1.0.0 - dev: true - /object.fromentries@2.0.8: - resolution: {integrity: sha512-k6E21FzySsSK5a21KRADBd/NGneRegFO5pLHfdQLpRDETUNJueLXs3WCzyQ3tFRDYgbq3KHGXfTbi2bs8WQ6rQ==} - engines: {node: '>= 0.4'} + object.fromentries@2.0.8: dependencies: call-bind: 1.0.7 define-properties: 1.2.1 es-abstract: 1.23.3 es-object-atoms: 1.0.0 - dev: true - /object.groupby@1.0.3: - resolution: {integrity: sha512-+Lhy3TQTuzXI5hevh8sBGqbmurHbbIjAi0Z4S63nthVLmLxfbj4T54a4CfZrXIrt9iP4mVAPYMo/v99taj3wjQ==} - engines: {node: '>= 0.4'} + object.groupby@1.0.3: dependencies: call-bind: 1.0.7 define-properties: 1.2.1 es-abstract: 1.23.3 - dev: true - /object.hasown@1.1.4: - resolution: {integrity: sha512-FZ9LZt9/RHzGySlBARE3VF+gE26TxR38SdmqOqliuTnl9wrKulaQs+4dee1V+Io8VfxqzAfHu6YuRgUy8OHoTg==} - engines: {node: '>= 0.4'} + object.hasown@1.1.4: dependencies: define-properties: 1.2.1 es-abstract: 1.23.3 es-object-atoms: 1.0.0 - dev: true - /object.values@1.2.0: - resolution: {integrity: sha512-yBYjY9QX2hnRmZHAjG/f13MzmBzxzYgQhFrke06TTyKY5zSTEqkOeukBzIdVA3j3ulu8Qa3MbVFShV7T2RmGtQ==} - engines: {node: '>= 0.4'} + object.values@1.2.0: dependencies: call-bind: 1.0.7 define-properties: 1.2.1 es-object-atoms: 1.0.0 - dev: true - /obuf@1.1.2: - resolution: {integrity: sha512-PX1wu0AmAdPqOL1mWhqmlOd8kOIZQwGZw6rh7uby9fTc5lhaOWFLX3I6R1hrF9k3zUY40e6igsLGkDXK92LJNg==} + obuf@1.1.2: {} - /oidc-provider@8.4.6: - resolution: {integrity: sha512-liuHBXRaIjer6nPGWagrl5UjPhIZqahqLVPoYlc2WXsRR7XddwNCBUl1ks5r3Q3uCUfMdQTv1VsjmlaObdff8w==} + oidc-provider@8.4.6: dependencies: '@koa/cors': 5.0.0 '@koa/router': 12.0.1 @@ -17717,62 +21639,41 @@ packages: raw-body: 2.5.2 transitivePeerDependencies: - supports-color - dev: false - /oidc-token-hash@5.0.3: - resolution: {integrity: sha512-IF4PcGgzAr6XXSff26Sk/+P4KZFJVuHAJZj3wgO3vX2bMdNVp/QXTP3P7CEm9V1IdG8lDLY3HhiqpsE/nOwpPw==} - engines: {node: ^10.13.0 || >=12.0.0} - dev: false + oidc-token-hash@5.0.3: {} - /on-finished@2.3.0: - resolution: {integrity: sha1-IPEzZIGwg811M3mSoWlxqi2QaUc=} - engines: {node: '>= 0.8'} + on-finished@2.3.0: dependencies: ee-first: 1.1.1 - /on-finished@2.4.1: - resolution: {integrity: sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==} - engines: {node: '>= 0.8'} + on-finished@2.4.1: dependencies: ee-first: 1.1.1 - dev: false - /once@1.4.0: - resolution: {integrity: sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==} + once@1.4.0: dependencies: wrappy: 1.0.2 - /onetime@5.1.2: - resolution: {integrity: sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==} - engines: {node: '>=6'} + onetime@5.1.2: dependencies: mimic-fn: 2.1.0 - /onetime@6.0.0: - resolution: {integrity: sha512-1FlR+gjXK7X+AsAHso35MnyN5KqGwJRi/31ft6x0M194ht7S+rWAvd7PHss9xSKMzE0asv1pyIHaJYq+BbacAQ==} - engines: {node: '>=12'} + onetime@6.0.0: dependencies: mimic-fn: 4.0.0 - dev: true - /only@0.0.2: - resolution: {integrity: sha1-Kv3oTQPlC5qO3EROMGEKcCle37Q=} + only@0.0.2: {} - /openapi-schema-validator@12.1.3: - resolution: {integrity: sha512-xTHOmxU/VQGUgo7Cm0jhwbklOKobXby+/237EG967+3TQEYJztMgX9Q5UE2taZKwyKPUq0j11dngpGjUuxz1hQ==} + openapi-schema-validator@12.1.3: dependencies: ajv: 8.12.0 ajv-formats: 2.1.1(ajv@8.12.0) lodash.merge: 4.6.2 openapi-types: 12.1.3 - dev: true - /openapi-types@12.1.3: - resolution: {integrity: sha512-N4YtSYJqghVu4iek2ZUvcN/0aqH1kRDuNqzcycDxhOUpg7GdvLa2F3DgS6yBNhInhv2r/6I0Flkn7CqL8+nIcw==} + openapi-types@12.1.3: {} - /optionator@0.8.3: - resolution: {integrity: sha512-+IW9pACdk3XWmmTXG8m3upGUJst5XRGzxMRjXzAuJ1XnIFNvfhjjIuYkDvysnPQ7qzqVzLt78BCruntqRhWQbA==} - engines: {node: '>= 0.8.0'} + optionator@0.8.3: dependencies: deep-is: 0.1.4 fast-levenshtein: 2.0.6 @@ -17780,11 +21681,8 @@ packages: prelude-ls: 1.1.2 type-check: 0.3.2 word-wrap: 1.2.3 - dev: true - /optionator@0.9.3: - resolution: {integrity: sha512-JjCoypp+jKn1ttEFExxhetCKeJt9zhAgAve5FXHixTvFDW/5aEktX9bufBKLRRMdU7bNtpLfcGu94B3cdEJgjg==} - engines: {node: '>= 0.8.0'} + optionator@0.9.3: dependencies: '@aashutoshrathi/word-wrap': 1.2.6 deep-is: 0.1.4 @@ -17792,11 +21690,8 @@ packages: levn: 0.4.1 prelude-ls: 1.2.1 type-check: 0.4.0 - dev: true - - /ora@6.1.2: - resolution: {integrity: sha512-EJQ3NiP5Xo94wJXIzAyOtSb0QEIAUu7m8t6UZ9krbz0vAJqr92JpcK/lEXg91q6B9pEGqrykkd2EQplnifDSBw==} - engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + + ora@6.1.2: dependencies: bl: 5.1.0 chalk: 5.3.0 @@ -17807,11 +21702,8 @@ packages: log-symbols: 5.1.0 strip-ansi: 7.0.1 wcwidth: 1.0.1 - dev: false - /ora@8.0.1: - resolution: {integrity: sha512-ANIvzobt1rls2BDny5fWZ3ZVKyD6nscLvfFRpQgfWsythlcsVUC9kL0zq6j2Z5z9wwp1kd7wpsD/T9qNPVLCaQ==} - engines: {node: '>=18'} + ora@8.0.1: dependencies: chalk: 5.3.0 cli-cursor: 4.0.0 @@ -17822,149 +21714,85 @@ packages: stdin-discarder: 0.2.2 string-width: 7.0.0 strip-ansi: 7.1.0 - dev: false - /ordered-binary@1.4.0: - resolution: {integrity: sha512-EHQ/jk4/a9hLupIKxTfUsQRej1Yd/0QLQs3vGvIqg5ZtCYSzNhkzHoZc7Zf4e4kUlDaC3Uw8Q/1opOLNN2OKRQ==} - dev: true + ordered-binary@1.4.0: {} - /os-homedir@1.0.2: - resolution: {integrity: sha512-B5JU3cabzk8c67mRRd3ECmROafjYMXbuzlwtqdM8IbS8ktlTix8aFGb2bAGKrSRIlnfKwovGUUr72JUPyOb6kQ==} - engines: {node: '>=0.10.0'} - dev: true + os-homedir@1.0.2: {} - /os-tmpdir@1.0.2: - resolution: {integrity: sha512-D2FR03Vir7FIu45XBY20mTb+/ZSWB00sjU9jdQXt83gDrI4Ztz5Fs7/yy74g2N5SVQY4xY1qDr4rNddwYRVX0g==} - engines: {node: '>=0.10.0'} + os-tmpdir@1.0.2: {} - /otplib@12.0.1: - resolution: {integrity: sha512-xDGvUOQjop7RDgxTQ+o4pOol0/3xSZzawTiPKRrHnQWAy0WjhNs/5HdIDJCrqC4MBynmjXgULc6YfioaxZeFgg==} + otplib@12.0.1: dependencies: '@otplib/core': 12.0.1 '@otplib/preset-default': 12.0.1 '@otplib/preset-v11': 12.0.1 - dev: false - /outdent@0.5.0: - resolution: {integrity: sha512-/jHxFIzoMXdqPzTaCpFzAAWhpkSjZPF4Vsn6jAfNpmbH/ymsmd7Qc6VE9BGn0L6YMj6uwpQLxCECpus4ukKS9Q==} - dev: true + outdent@0.5.0: {} - /overlayscrollbars-react@0.5.0(overlayscrollbars@2.0.3)(react@18.2.0): - resolution: {integrity: sha512-uCNTnkfWW74veoiEv3kSwoLelKt4e8gTNv65D771X3il0x5g5Yo0fUbro7SpQzR9yNgi23cvB2mQHTTdQH96pA==} - peerDependencies: - overlayscrollbars: ^2.0.0 - react: '>=16.8.0 || ^18.0.0' + overlayscrollbars-react@0.5.0(overlayscrollbars@2.0.3)(react@18.2.0): dependencies: overlayscrollbars: 2.0.3 react: 18.2.0 - dev: true - /overlayscrollbars@2.0.3: - resolution: {integrity: sha512-boOkJFER1Tc21sxF4a7ghGl+ETV3WtP7YgsUyDPo1VTHUIPdQLfnTzMyOOdMkKkVcpJOYMKwwr4m+saCtgawCg==} - dev: true + overlayscrollbars@2.0.3: {} - /p-cancelable@3.0.0: - resolution: {integrity: sha512-mlVgR3PGuzlo0MmTdk4cXqXWlwQDLnONTAg6sm62XkMJEiRxN3GL3SffkYvqwonbkJBcrI7Uvv5Zh9yjvn2iUw==} - engines: {node: '>=12.20'} - dev: false + p-cancelable@3.0.0: {} - /p-cancelable@4.0.1: - resolution: {integrity: sha512-wBowNApzd45EIKdO1LaU+LrMBwAcjfPaYtVzV3lmfM3gf8Z4CHZsiIqlM8TZZ8okYvh5A1cP6gTfCRQtwUpaUg==} - engines: {node: '>=14.16'} - dev: false + p-cancelable@4.0.1: {} - /p-defer@4.0.0: - resolution: {integrity: sha512-Vb3QRvQ0Y5XnF40ZUWW7JfLogicVh/EnA5gBIvKDJoYpeI82+1E3AlB9yOcKFS0AhHrWVnAQO39fbR0G99IVEQ==} - engines: {node: '>=12'} + p-defer@4.0.0: {} - /p-filter@2.1.0: - resolution: {integrity: sha512-ZBxxZ5sL2HghephhpGAQdoskxplTwr7ICaehZwLIlfL6acuVgZPm8yBNuRAFBGEqtD/hmUeq9eqLg2ys9Xr/yw==} - engines: {node: '>=8'} + p-filter@2.1.0: dependencies: p-map: 2.1.0 - dev: true - /p-limit@2.3.0: - resolution: {integrity: sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==} - engines: {node: '>=6'} + p-limit@2.3.0: dependencies: p-try: 2.2.0 - /p-limit@3.1.0: - resolution: {integrity: sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==} - engines: {node: '>=10'} + p-limit@3.1.0: dependencies: yocto-queue: 0.1.0 - /p-limit@4.0.0: - resolution: {integrity: sha512-5b0R4txpzjPWVw/cXXUResoD4hb6U/x9BH08L7nw+GN1sezDzPdxeRvpc9c433fZhBan/wusjbCsqwqm4EIBIQ==} - engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + p-limit@4.0.0: dependencies: yocto-queue: 1.0.0 - /p-limit@5.0.0: - resolution: {integrity: sha512-/Eaoq+QyLSiXQ4lyYV23f14mZRQcXnxfHrN0vCai+ak9G0pp9iEQukIIZq5NccEvwRB8PUnZT0KsOoDCINS1qQ==} - engines: {node: '>=18'} + p-limit@5.0.0: dependencies: yocto-queue: 1.0.0 - /p-locate@4.1.0: - resolution: {integrity: sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==} - engines: {node: '>=8'} + p-locate@4.1.0: dependencies: p-limit: 2.3.0 - /p-locate@5.0.0: - resolution: {integrity: sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==} - engines: {node: '>=10'} + p-locate@5.0.0: dependencies: p-limit: 3.1.0 - dev: true - /p-locate@6.0.0: - resolution: {integrity: sha512-wPrq66Llhl7/4AGC6I+cqxT07LhXvWL08LNXz1fENOw0Ap4sRZZ/gZpTTJ5jpurzzzfS2W/Ge9BY3LgLjCShcw==} - engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + p-locate@6.0.0: dependencies: p-limit: 4.0.0 - /p-map@2.1.0: - resolution: {integrity: sha512-y3b8Kpd8OAN444hxfBbFfj1FY/RjtTd8tzYwhUqNYXx0fXx2iX4maP4Qr6qhIKbQXI02wTLAda4fYUbDagTUFw==} - engines: {node: '>=6'} - dev: true + p-map@2.1.0: {} - /p-map@7.0.2: - resolution: {integrity: sha512-z4cYYMMdKHzw4O5UkWJImbZynVIo0lSGTXc7bzB1e/rrDqkgGUNysK/o4bTr+0+xKvvLoTyGqYC4Fgljy9qe1Q==} - engines: {node: '>=18'} - dev: false + p-map@7.0.2: {} - /p-queue@8.0.1: - resolution: {integrity: sha512-NXzu9aQJTAzbBqOt2hwsR63ea7yvxJc0PwN/zobNAudYfb1B7R08SzB4TsLeSbUCuG467NhnoT0oO6w1qRO+BA==} - engines: {node: '>=18'} + p-queue@8.0.1: dependencies: eventemitter3: 5.0.1 p-timeout: 6.1.2 - dev: false - /p-retry@6.0.0: - resolution: {integrity: sha512-6NuuXu8Upembd4sNdo4PRbs+M6aHgBTrFE6lkH0YKjVzne3cDW4gkncB98ty/bkMxLxLVNeD5bX9FyWjM7WZ+A==} - engines: {node: '>=16.17'} + p-retry@6.0.0: dependencies: '@types/retry': 0.12.2 retry: 0.13.1 - dev: false - /p-timeout@6.1.2: - resolution: {integrity: sha512-UbD77BuZ9Bc9aABo74gfXhNvzC9Tx7SxtHSh1fxvx3jTLLYvmVhiQZZrJzqqU0jKbN32kb5VOKiLEQI/3bIjgQ==} - engines: {node: '>=14.16'} - dev: false + p-timeout@6.1.2: {} - /p-try@2.2.0: - resolution: {integrity: sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==} - engines: {node: '>=6'} + p-try@2.2.0: {} - /pac-proxy-agent@7.0.1: - resolution: {integrity: sha512-ASV8yU4LLKBAjqIPMbrgtaKIvxQri/yh2OpI+S6hVa9JRkUI3Y3NPFbfngDtY7oFtSMD3w31Xns89mDa3Feo5A==} - engines: {node: '>= 14'} + pac-proxy-agent@7.0.1: dependencies: '@tootallnate/quickjs-emscripten': 0.23.0 agent-base: 7.1.0 @@ -17976,40 +21804,22 @@ packages: socks-proxy-agent: 8.0.2 transitivePeerDependencies: - supports-color - dev: true - /pac-resolver@7.0.0: - resolution: {integrity: sha512-Fd9lT9vJbHYRACT8OhCbZBbxr6KRSawSovFpy8nDGshaK99S/EBhVIHp9+crhxrsZOuvLpgL1n23iyPg6Rl2hg==} - engines: {node: '>= 14'} + pac-resolver@7.0.0: dependencies: degenerator: 5.0.1 ip: 1.1.9 netmask: 2.0.2 - dev: true - /packet-reader@1.0.0: - resolution: {integrity: sha512-HAKu/fG3HpHFO0AA8WE8q2g+gBJaZ9MG7fcKk+IJPLTGAD6Psw4443l+9DGRbOIh3/aXr7Phy0TjilYivJo5XQ==} + packet-reader@1.0.0: {} - /pako@1.0.11: - resolution: {integrity: sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw==} - dev: false + pako@1.0.11: {} - /parcel-resolver-ignore@2.1.3(parcel@2.9.3): - resolution: {integrity: sha512-C8uLvR4o7SPRSsQ/Nylm1/PdsLwn/Z9bzCs66qT3XIebJC7ojaFFF3MDl/mie5audngjcFF8wzU0AoEQkZq2pA==} - engines: {parcel: '>=2.0.0'} - peerDependencies: - parcel: '>=2.0.0' + parcel-resolver-ignore@2.1.3(parcel@2.9.3): dependencies: parcel: 2.9.3(postcss@8.4.31) - dev: true - /parcel@2.9.3(postcss@8.4.31): - resolution: {integrity: sha512-2GTVocFkwblV/TIg9AmT7TI2fO4xdWkyN8aFUEVtiVNWt96GTR3FgQyHFValfCbcj1k9Xf962Ws2hYXYUr9k1Q==} - engines: {node: '>= 12.0.0'} - hasBin: true - peerDependenciesMeta: - '@parcel/core': - optional: true + parcel@2.9.3(postcss@8.4.31): dependencies: '@parcel/config-default': 2.9.3(@parcel/core@2.9.3)(postcss@8.4.31) '@parcel/core': 2.9.3 @@ -18034,17 +21844,12 @@ packages: - srcset - terser - uncss - dev: true - /parent-module@1.0.1: - resolution: {integrity: sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==} - engines: {node: '>=6'} + parent-module@1.0.1: dependencies: callsites: 3.1.0 - dev: true - /parse-entities@2.0.0: - resolution: {integrity: sha512-kkywGpCcRYhqQIchaWqZ875wzpS/bMKhz5HnN3p7wveJTkTtyAB/AlnS0f8DFSqYW1T82t6yEAkEcB+A1I3MbQ==} + parse-entities@2.0.0: dependencies: character-entities: 1.2.4 character-entities-legacy: 1.1.4 @@ -18052,163 +21857,93 @@ packages: is-alphanumerical: 1.0.4 is-decimal: 1.0.4 is-hexadecimal: 1.0.4 - dev: true - /parse-json@5.2.0: - resolution: {integrity: sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==} - engines: {node: '>=8'} + parse-json@5.2.0: dependencies: '@babel/code-frame': 7.22.5 error-ex: 1.3.2 json-parse-even-better-errors: 2.3.1 lines-and-columns: 1.2.4 - dev: true - /parse-passwd@1.0.0: - resolution: {integrity: sha512-1Y1A//QUXEZK7YKz+rD9WydcE1+EuPr6ZBgKecAB8tmoW6UFv0NREVJe1p+jRxtThkcbbKkfwIbWJe/IeE6m2Q==} - engines: {node: '>=0.10.0'} - dev: true + parse-passwd@1.0.0: {} - /parse5@6.0.1: - resolution: {integrity: sha512-Ofn/CTFzRGTTxwpNEs9PP93gXShHcTq255nzRYSKe8AkVpZY7e1fpmTfOyoIvjP5HG7Z2ZM7VS9PPhQGW2pOpw==} - dev: true + parse5@6.0.1: {} - /parse5@7.1.1: - resolution: {integrity: sha512-kwpuwzB+px5WUg9pyK0IcK/shltJN5/OVhQagxhCQNtT9Y9QRZqNY2e1cmbu/paRh5LMnz/oVTVLBpjFmMZhSg==} + parse5@7.1.1: dependencies: entities: 4.4.0 - dev: true - /parseurl@1.3.3: - resolution: {integrity: sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==} - engines: {node: '>= 0.8'} + parseurl@1.3.3: {} - /passthrough-counter@1.0.0: - resolution: {integrity: sha1-GWfZ5m2lcrXAI8eH2xEqOHqxZvo=} - dev: false + passthrough-counter@1.0.0: {} - /path-exists@4.0.0: - resolution: {integrity: sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==} - engines: {node: '>=8'} + path-exists@4.0.0: {} - /path-exists@5.0.0: - resolution: {integrity: sha512-RjhtfwJOxzcFmNOi6ltcbcu4Iu+FL3zEj83dk4kAS+fVpTxXLO1b38RvJgT/0QwvV/L3aY9TAnyv0EOqW4GoMQ==} - engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + path-exists@5.0.0: {} - /path-is-absolute@1.0.1: - resolution: {integrity: sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==} - engines: {node: '>=0.10.0'} + path-is-absolute@1.0.1: {} - /path-key@3.1.1: - resolution: {integrity: sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==} - engines: {node: '>=8'} + path-key@3.1.1: {} - /path-key@4.0.0: - resolution: {integrity: sha512-haREypq7xkM7ErfgIyA0z+Bj4AGKlMSdlQE2jvJo6huWD1EdkKYV+G/T4nq0YEF2vgTT8kqMFKo1uHn950r4SQ==} - engines: {node: '>=12'} - dev: true + path-key@4.0.0: {} - /path-match@1.2.4: - resolution: {integrity: sha512-UWlehEdqu36jmh4h5CWJ7tARp1OEVKGHKm6+dg9qMq5RKUTV5WJrGgaZ3dN2m7WFAXDbjlHzvJvL/IUpy84Ktw==} + path-match@1.2.4: dependencies: http-errors: 1.4.0 path-to-regexp: 1.8.0 - dev: false - /path-parse@1.0.7: - resolution: {integrity: sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==} + path-parse@1.0.7: {} - /path-scurry@1.10.2: - resolution: {integrity: sha512-7xTavNy5RQXnsjANvVvMkEjvloOinkAjv/Z6Ildz9v2RinZ4SBKTWFOVRbaF8p0vpHnyjV/UwNDdKuUv6M5qcA==} - engines: {node: '>=16 || 14 >=14.17'} + path-scurry@1.10.2: dependencies: lru-cache: 10.2.0 minipass: 7.0.4 - dev: false - /path-to-regexp@1.8.0: - resolution: {integrity: sha512-n43JRhlUKUAlibEJhPeir1ncUID16QnEjNpwzNdO3Lm4ywrBpBZ5oLD0I6br9evr1Y9JTqwRtAh7JLoOzAQdVA==} + path-to-regexp@1.8.0: dependencies: isarray: 0.0.1 - /path-to-regexp@6.2.1: - resolution: {integrity: sha512-JLyh7xT1kizaEvcaXOQwOc2/Yhw6KZOvPf1S8401UyLk86CU79LN3vl7ztXGm/pZ+YjoyAJ4rxmHwbkBXJX+yw==} - dev: false + path-to-regexp@6.2.1: {} - /path-type@4.0.0: - resolution: {integrity: sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==} - engines: {node: '>=8'} - dev: true + path-type@4.0.0: {} - /pathe@1.1.2: - resolution: {integrity: sha512-whLdWMYL2TwI08hn8/ZqAbrVemu0LNaNNJZX73O6qaIdCTfXutsLhMkjdENX0qhsQ9uIimo4/aQOmXkoon2nDQ==} - dev: true + pathe@1.1.2: {} - /pathval@1.1.1: - resolution: {integrity: sha512-Dp6zGqpTdETdR63lehJYPeIOqpiNBNtc7BpWSLrOje7UaIsE5aY92r/AunQA7rsXvet3lrJ3JnZX29UPTKXyKQ==} - dev: true + pathval@1.1.1: {} - /pend@1.2.0: - resolution: {integrity: sha512-F3asv42UuXchdzt+xXqfW1OGlVBe+mxa2mqI0pg5yAHZPvFmY3Y6drSf/GQ1A86WgWEN9Kzh/WrgKa6iGcHXLg==} - dev: true + pend@1.2.0: {} - /pg-cloudflare@1.1.1: - resolution: {integrity: sha512-xWPagP/4B6BgFO+EKz3JONXv3YDgvkbVrGw2mTo3D6tVDQRh1e7cqVGvyR3BE+eQgAvx1XhW/iEASj4/jCWl3Q==} - requiresBuild: true + pg-cloudflare@1.1.1: optional: true - /pg-connection-string@2.5.0: - resolution: {integrity: sha512-r5o/V/ORTA6TmUnyWZR9nCj1klXCO2CEKNRlVuJptZe85QuhFayC7WeMic7ndayT5IRIR0S0xFxFi2ousartlQ==} - dev: true + pg-connection-string@2.5.0: {} - /pg-connection-string@2.6.2: - resolution: {integrity: sha512-ch6OwaeaPYcova4kKZ15sbJ2hKb/VP48ZD2gE7i1J+L4MspCtBMAx8nMgz7bksc7IojCIIWuEhHibSMFH8m8oA==} + pg-connection-string@2.6.2: {} - /pg-cursor@2.10.3(pg@8.11.3): - resolution: {integrity: sha512-rDyBVoqPVnx/PTmnwQAYgusSeAKlTL++gmpf5klVK+mYMFEqsOc6VHHZnPKc/4lOvr4r6fiMuoxSFuBF1dx4FQ==} - peerDependencies: - pg: ^8 + pg-cursor@2.10.3(pg@8.11.3): dependencies: pg: 8.11.3 - /pg-formatter@1.3.0: - resolution: {integrity: sha512-y1kNdgD+QWzhmYCm91z/k7VGyx6BekQg6ww/krFEEhw1IIB4zEk2xaB0pmueTcc59YFetpiHIKECgHEuw6gyvg==} - engines: {node: '>=10.0'} - hasBin: true + pg-formatter@1.3.0: dependencies: shell-quote: 1.7.3 yargs: 17.7.2 - dev: true - /pg-int8@1.0.1: - resolution: {integrity: sha512-WCtabS6t3c8SkpDBUlb1kjOs7l66xsGdKpIPZsg4wR+B3+u9UAum2odSsF9tnvxg80h4ZxLWMy4pRjOsFIqQpw==} - engines: {node: '>=4.0.0'} + pg-int8@1.0.1: {} - /pg-numeric@1.0.2: - resolution: {integrity: sha512-BM/Thnrw5jm2kKLE5uJkXqqExRUY/toLHda65XgFTBTFYZyopbKjBe29Ii3RbkvlsMoFwD+tHeGaCjjv0gHlyw==} - engines: {node: '>=4'} + pg-numeric@1.0.2: {} - /pg-pool@3.5.2(pg@8.8.0): - resolution: {integrity: sha512-His3Fh17Z4eg7oANLob6ZvH8xIVen3phEZh2QuyrIl4dQSDVEabNducv6ysROKpDNPSD+12tONZVWfSgMvDD9w==} - peerDependencies: - pg: '>=8.0' + pg-pool@3.5.2(pg@8.8.0): dependencies: pg: 8.8.0 - dev: true - /pg-pool@3.6.1(pg@8.11.3): - resolution: {integrity: sha512-jizsIzhkIitxCGfPRzJn1ZdcosIt3pz9Sh3V01fm1vZnbnCMgmGl5wvGGdNN2EL9Rmb0EcFoCkixH4Pu+sP9Og==} - peerDependencies: - pg: '>=8.0' + pg-pool@3.6.1(pg@8.11.3): dependencies: pg: 8.11.3 - /pg-protocol@1.6.0: - resolution: {integrity: sha512-M+PDm637OY5WM307051+bsDia5Xej6d9IR4GwJse1qA1DIhiKlksvrneZOYQq42OM+spubpcNYEo2FcKQrDk+Q==} + pg-protocol@1.6.0: {} - /pg-types@2.2.0: - resolution: {integrity: sha512-qTAAlrEsl8s4OiEQY69wDvcMIdQN6wdz5ojQiOy6YRMuynxenON0O5oCpJI6lshc6scgAY8qvJ2On/p+CXY0GA==} - engines: {node: '>=4'} + pg-types@2.2.0: dependencies: pg-int8: 1.0.1 postgres-array: 2.0.0 @@ -18216,9 +21951,7 @@ packages: postgres-date: 1.0.7 postgres-interval: 1.2.0 - /pg-types@4.0.2: - resolution: {integrity: sha512-cRL3JpS3lKMGsKaWndugWQoLOCoP+Cic8oseVcbr0qhPzYD5DWXK+RZ9LY9wxRf7RQia4SCwQlXk0q6FCPrVng==} - engines: {node: '>=10'} + pg-types@4.0.2: dependencies: pg-int8: 1.0.1 pg-numeric: 1.0.2 @@ -18228,14 +21961,7 @@ packages: postgres-interval: 3.0.0 postgres-range: 1.1.2 - /pg@8.11.3: - resolution: {integrity: sha512-+9iuvG8QfaaUrrph+kpF24cXkH1YOOUeArRNYIxq1viYHZagBxrTno7cecY1Fa44tJeZvaoG+Djpkc3JwehN5g==} - engines: {node: '>= 8.0.0'} - peerDependencies: - pg-native: '>=3.0.1' - peerDependenciesMeta: - pg-native: - optional: true + pg@8.11.3: dependencies: buffer-writer: 2.0.0 packet-reader: 1.0.0 @@ -18247,14 +21973,7 @@ packages: optionalDependencies: pg-cloudflare: 1.1.1 - /pg@8.8.0: - resolution: {integrity: sha512-UXYN0ziKj+AeNNP7VDMwrehpACThH7LUl/p8TDFpEUuSejCUIwGSfxpHsPvtM6/WXFy6SU4E5RG4IJV/TZAGjw==} - engines: {node: '>= 8.0.0'} - peerDependencies: - pg-native: '>=3.0.1' - peerDependenciesMeta: - pg-native: - optional: true + pg@8.8.0: dependencies: buffer-writer: 2.0.0 packet-reader: 1.0.0 @@ -18263,123 +21982,65 @@ packages: pg-protocol: 1.6.0 pg-types: 2.2.0 pgpass: 1.0.4 - dev: true - /pgpass@1.0.4: - resolution: {integrity: sha512-YmuA56alyBq7M59vxVBfPJrGSozru8QAdoNlWuW3cz8l+UX3cWge0vTvjKhsSHSJpo3Bom8/Mm6hf0TR5GY0+w==} + pgpass@1.0.4: dependencies: split2: 3.2.2 - /picocolors@1.0.0: - resolution: {integrity: sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==} - dev: true + picocolors@1.0.0: {} - /picomatch@2.3.1: - resolution: {integrity: sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==} - engines: {node: '>=8.6'} - dev: true + picomatch@2.3.1: {} - /pidtree@0.6.0: - resolution: {integrity: sha512-eG2dWTVw5bzqGRztnHExczNxt5VGsE6OwTeCG3fdUf9KBsZzO3R5OIIIzWR+iZA0NtZ+RDVdaoE2dK1cn6jH4g==} - engines: {node: '>=0.10'} - hasBin: true - dev: true + pidtree@0.6.0: {} - /pify@4.0.1: - resolution: {integrity: sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==} - engines: {node: '>=6'} - dev: true + pify@4.0.1: {} - /pirates@4.0.5: - resolution: {integrity: sha512-8V9+HQPupnaXMA23c5hvl69zXvTwTzyAYasnkb0Tts4XvO4CliqONMOnvlq26rkhLC3nWDFBJf73LU1e1VZLaQ==} - engines: {node: '>= 6'} - dev: true + pirates@4.0.5: {} - /pkg-dir@4.2.0: - resolution: {integrity: sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==} - engines: {node: '>=8'} + pkg-dir@4.2.0: dependencies: find-up: 4.1.0 - dev: true - /pkg-dir@5.0.0: - resolution: {integrity: sha512-NPE8TDbzl/3YQYY7CSS228s3g2ollTFnc+Qi3tqmqJp9Vg2ovUpixcJEo2HJScN2Ez+kEaal6y70c0ehqJBJeA==} - engines: {node: '>=10'} + pkg-dir@5.0.0: dependencies: find-up: 5.0.0 - dev: true - /pkg-types@1.0.3: - resolution: {integrity: sha512-nN7pYi0AQqJnoLPC9eHFQ8AcyaixBUOwvqc5TDnIKCMEE6I0y8P7OKA7fPexsXGCGxQDl/cmrLAp26LhcwxZ4A==} + pkg-types@1.0.3: dependencies: jsonc-parser: 3.2.0 mlly: 1.6.1 pathe: 1.1.2 - dev: true - /pluralize@8.0.0: - resolution: {integrity: sha512-Nc3IT5yHzflTfbjgqWcCPpo7DaKy4FnpB0l/zCAW0Tc7jxAiuqSxHasntB3D7887LSrA93kDJ9IXovxJYxyLCA==} - engines: {node: '>=4'} + pluralize@8.0.0: {} - /pngjs@5.0.0: - resolution: {integrity: sha512-40QW5YalBNfQo5yRYmiw7Yz6TKKVr3h6970B2YE+3fQpsWcrbj1PzJgxeJ19DRQjhMbKPIuMY8rFaXc8moolVw==} - engines: {node: '>=10.13.0'} - dev: false + pngjs@5.0.0: {} - /possible-typed-array-names@1.0.0: - resolution: {integrity: sha512-d7Uw+eZoloe0EHDIYoe+bQ5WXnGMOpmiZFTuMWCwpjzzkL2nTjcKiAk4hh8TjnGye2TwWOk3UXucZ+3rbmBa8Q==} - engines: {node: '>= 0.4'} - dev: true + possible-typed-array-names@1.0.0: {} - /postcss-media-query-parser@0.2.3: - resolution: {integrity: sha512-3sOlxmbKcSHMjlUXQZKQ06jOswE7oVkXPxmZdoB1r5l0q6gTFTQSHxNxOrCccElbW7dxNytifNEo8qidX2Vsig==} - dev: true + postcss-media-query-parser@0.2.3: {} - /postcss-modules-extract-imports@3.0.0(postcss@8.4.31): - resolution: {integrity: sha512-bdHleFnP3kZ4NYDhuGlVK+CMrQ/pqUm8bx/oGL93K6gVwiclvX5x0n76fYMKuIGKzlABOy13zsvqjb0f92TEXw==} - engines: {node: ^10 || ^12 || >= 14} - peerDependencies: - postcss: ^8.1.0 + postcss-modules-extract-imports@3.0.0(postcss@8.4.31): dependencies: postcss: 8.4.31 - dev: true - /postcss-modules-local-by-default@4.0.0(postcss@8.4.31): - resolution: {integrity: sha512-sT7ihtmGSF9yhm6ggikHdV0hlziDTX7oFoXtuVWeDd3hHObNkcHRo9V3yg7vCAY7cONyxJC/XXCmmiHHcvX7bQ==} - engines: {node: ^10 || ^12 || >= 14} - peerDependencies: - postcss: ^8.1.0 + postcss-modules-local-by-default@4.0.0(postcss@8.4.31): dependencies: icss-utils: 5.1.0(postcss@8.4.31) postcss: 8.4.31 postcss-selector-parser: 6.0.11 postcss-value-parser: 4.2.0 - dev: true - /postcss-modules-scope@3.0.0(postcss@8.4.31): - resolution: {integrity: sha512-hncihwFA2yPath8oZ15PZqvWGkWf+XUfQgUGamS4LqoP1anQLOsOJw0vr7J7IwLpoY9fatA2qiGUGmuZL0Iqlg==} - engines: {node: ^10 || ^12 || >= 14} - peerDependencies: - postcss: ^8.1.0 + postcss-modules-scope@3.0.0(postcss@8.4.31): dependencies: postcss: 8.4.31 postcss-selector-parser: 6.0.11 - dev: true - /postcss-modules-values@4.0.0(postcss@8.4.31): - resolution: {integrity: sha512-RDxHkAiEGI78gS2ofyvCsu7iycRv7oqw5xMWn9iMoR0N/7mf9D50ecQqUo5BZ9Zh2vH4bCUR/ktCqbB9m8vJjQ==} - engines: {node: ^10 || ^12 || >= 14} - peerDependencies: - postcss: ^8.1.0 + postcss-modules-values@4.0.0(postcss@8.4.31): dependencies: icss-utils: 5.1.0(postcss@8.4.31) postcss: 8.4.31 - dev: true - /postcss-modules@4.3.0(postcss@8.4.31): - resolution: {integrity: sha512-zoUttLDSsbWDinJM9jH37o7hulLRyEgH6fZm2PchxN7AZ8rkdWiALyNhnQ7+jg7cX9f10m6y5VhHsrjO0Mf/DA==} - peerDependencies: - postcss: ^8.0.0 + postcss-modules@4.3.0(postcss@8.4.31): dependencies: generic-names: 4.0.0 icss-replace-symbols: 1.1.0 @@ -18390,267 +22051,149 @@ packages: postcss-modules-scope: 3.0.0(postcss@8.4.31) postcss-modules-values: 4.0.0(postcss@8.4.31) string-hash: 1.1.3 - dev: true - /postcss-resolve-nested-selector@0.1.1: - resolution: {integrity: sha512-HvExULSwLqHLgUy1rl3ANIqCsvMS0WHss2UOsXhXnQaZ9VCc2oBvIpXrl00IUFT5ZDITME0o6oiXeiHr2SAIfw==} - dev: true + postcss-resolve-nested-selector@0.1.1: {} - /postcss-safe-parser@6.0.0(postcss@8.4.38): - resolution: {integrity: sha512-FARHN8pwH+WiS2OPCxJI8FuRJpTVnn6ZNFiqAM2aeW2LwTHWWmWgIyKC6cUo0L8aeKiF/14MNvnpls6R2PBeMQ==} - engines: {node: '>=12.0'} - peerDependencies: - postcss: ^8.3.3 + postcss-safe-parser@6.0.0(postcss@8.4.38): dependencies: postcss: 8.4.38 - dev: true - /postcss-scss@4.0.9(postcss@8.4.31): - resolution: {integrity: sha512-AjKOeiwAitL/MXxQW2DliT28EKukvvbEWx3LBmJIRN8KfBGZbRTxNYW0kSqi1COiTZ57nZ9NW06S6ux//N1c9A==} - engines: {node: '>=12.0'} - peerDependencies: - postcss: ^8.4.29 + postcss-scss@4.0.9(postcss@8.4.31): dependencies: postcss: 8.4.31 - dev: true - /postcss-selector-parser@6.0.11: - resolution: {integrity: sha512-zbARubNdogI9j7WY4nQJBiNqQf3sLS3wCP4WfOidu+p28LofJqDH1tcXypGrcmMHhDk2t9wGhCsYe/+szLTy1g==} - engines: {node: '>=4'} + postcss-selector-parser@6.0.11: dependencies: cssesc: 3.0.0 util-deprecate: 1.0.2 - dev: true - /postcss-selector-parser@6.0.16: - resolution: {integrity: sha512-A0RVJrX+IUkVZbW3ClroRWurercFhieevHB38sr2+l9eUClMqome3LmEmnhlNy+5Mr2EYN6B2Kaw9wYdd+VHiw==} - engines: {node: '>=4'} + postcss-selector-parser@6.0.16: dependencies: cssesc: 3.0.0 util-deprecate: 1.0.2 - dev: true - /postcss-sorting@8.0.2(postcss@8.4.38): - resolution: {integrity: sha512-M9dkSrmU00t/jK7rF6BZSZauA5MAaBW4i5EnJXspMwt4iqTh/L9j6fgMnbElEOfyRyfLfVbIHj/R52zHzAPe1Q==} - peerDependencies: - postcss: ^8.4.20 + postcss-sorting@8.0.2(postcss@8.4.38): dependencies: postcss: 8.4.38 - dev: true - /postcss-value-parser@3.3.1: - resolution: {integrity: sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==} - dev: true + postcss-value-parser@3.3.1: {} - /postcss-value-parser@4.2.0: - resolution: {integrity: sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==} - dev: true + postcss-value-parser@4.2.0: {} - /postcss@8.4.31: - resolution: {integrity: sha512-PS08Iboia9mts/2ygV3eLpY5ghnUcfLV/EXTOW1E2qYxJKGGBUtNjN76FYHnMs36RmARn41bC0AZmn+rR0OVpQ==} - engines: {node: ^10 || ^12 || >=14} + postcss@8.4.31: dependencies: nanoid: 3.3.6 picocolors: 1.0.0 source-map-js: 1.0.2 - dev: true - /postcss@8.4.38: - resolution: {integrity: sha512-Wglpdk03BSfXkHoQa3b/oulrotAkwrlLDRSOb9D0bN86FdRyE9lppSp33aHNPgBa0JKCoB+drFLZkQoRRYae5A==} - engines: {node: ^10 || ^12 || >=14} + postcss@8.4.38: dependencies: nanoid: 3.3.7 picocolors: 1.0.0 source-map-js: 1.2.0 - dev: true - /postgres-array@2.0.0: - resolution: {integrity: sha512-VpZrUqU5A69eQyW2c5CA1jtLecCsN2U/bD6VilrFDWq5+5UIEVO7nazS3TEcHf1zuPYO/sqGvUvW62g86RXZuA==} - engines: {node: '>=4'} + postgres-array@2.0.0: {} - /postgres-array@3.0.2: - resolution: {integrity: sha512-6faShkdFugNQCLwucjPcY5ARoW1SlbnrZjmGl0IrrqewpvxvhSLHimCVzqeuULCbG0fQv7Dtk1yDbG3xv7Veog==} - engines: {node: '>=12'} + postgres-array@3.0.2: {} - /postgres-bytea@1.0.0: - resolution: {integrity: sha512-xy3pmLuQqRBZBXDULy7KbaitYqLcmxigw14Q5sj8QBVLqEwXfeybIKVWiqAXTlcvdvb0+xkOtDbfQMOf4lST1w==} - engines: {node: '>=0.10.0'} + postgres-bytea@1.0.0: {} - /postgres-bytea@3.0.0: - resolution: {integrity: sha512-CNd4jim9RFPkObHSjVHlVrxoVQXz7quwNFpz7RY1okNNme49+sVyiTvTRobiLV548Hx/hb1BG+iE7h9493WzFw==} - engines: {node: '>= 6'} + postgres-bytea@3.0.0: dependencies: obuf: 1.1.2 - /postgres-date@1.0.7: - resolution: {integrity: sha512-suDmjLVQg78nMK2UZ454hAG+OAW+HQPZ6n++TNDUX+L0+uUlLywnoxJKDou51Zm+zTCjrCl0Nq6J9C5hP9vK/Q==} - engines: {node: '>=0.10.0'} + postgres-date@1.0.7: {} - /postgres-date@2.1.0: - resolution: {integrity: sha512-K7Juri8gtgXVcDfZttFKVmhglp7epKb1K4pgrkLxehjqkrgPhfG6OO8LHLkfaqkbpjNRnra018XwAr1yQFWGcA==} - engines: {node: '>=12'} + postgres-date@2.1.0: {} - /postgres-interval@1.2.0: - resolution: {integrity: sha512-9ZhXKM/rw350N1ovuWHbGxnGh/SNJ4cnxHiM0rxE4VN41wsg8P8zWn9hv/buK00RP4WvlOyr/RBDiptyxVbkZQ==} - engines: {node: '>=0.10.0'} + postgres-interval@1.2.0: dependencies: xtend: 4.0.2 - /postgres-interval@3.0.0: - resolution: {integrity: sha512-BSNDnbyZCXSxgA+1f5UU2GmwhoI0aU5yMxRGO8CdFEcY2BQF9xm/7MqKnYoM1nJDk8nONNWDk9WeSmePFhQdlw==} - engines: {node: '>=12'} + postgres-interval@3.0.0: {} - /postgres-interval@4.0.2: - resolution: {integrity: sha512-EMsphSQ1YkQqKZL2cuG0zHkmjCCzQqQ71l2GXITqRwjhRleCdv00bDk/ktaSi0LnlaPzAc3535KTrjXsTdtx7A==} - engines: {node: '>=12'} + postgres-interval@4.0.2: {} - /postgres-range@1.1.2: - resolution: {integrity: sha512-CmPJDSpd3/xYJrtw/tI0Cv029B0zMtnesUOHCZmgvypGBLn+eExXcjCS5OY7mpiw6imYEvd2IMD36sAOYA9U1w==} + postgres-range@1.1.2: {} - /posthtml-parser@0.10.2: - resolution: {integrity: sha512-PId6zZ/2lyJi9LiKfe+i2xv57oEjJgWbsHGGANwos5AvdQp98i6AtamAl8gzSVFGfQ43Glb5D614cvZf012VKg==} - engines: {node: '>=12'} + posthtml-parser@0.10.2: dependencies: htmlparser2: 7.2.0 - dev: true - /posthtml-parser@0.11.0: - resolution: {integrity: sha512-QecJtfLekJbWVo/dMAA+OSwY79wpRmbqS5TeXvXSX+f0c6pW4/SE6inzZ2qkU7oAMCPqIDkZDvd/bQsSFUnKyw==} - engines: {node: '>=12'} + posthtml-parser@0.11.0: dependencies: htmlparser2: 7.2.0 - dev: true - /posthtml-render@3.0.0: - resolution: {integrity: sha512-z+16RoxK3fUPgwaIgH9NGnK1HKY9XIDpydky5eQGgAFVXTCSezalv9U2jQuNV+Z9qV1fDWNzldcw4eK0SSbqKA==} - engines: {node: '>=12'} + posthtml-render@3.0.0: dependencies: is-json: 2.0.1 - dev: true - /posthtml@0.16.6: - resolution: {integrity: sha512-JcEmHlyLK/o0uGAlj65vgg+7LIms0xKXe60lcDOTU7oVX/3LuEuLwrQpW3VJ7de5TaFKiW4kWkaIpJL42FEgxQ==} - engines: {node: '>=12.0.0'} + posthtml@0.16.6: dependencies: posthtml-parser: 0.11.0 posthtml-render: 3.0.0 - dev: true - /preferred-pm@3.0.3: - resolution: {integrity: sha512-+wZgbxNES/KlJs9q40F/1sfOd/j7f1O9JaHcW5Dsn3aUUOZg3L2bjpVUcKV2jvtElYfoTuQiNeMfQJ4kwUAhCQ==} - engines: {node: '>=10'} + preferred-pm@3.0.3: dependencies: find-up: 5.0.0 find-yarn-workspace-root2: 1.2.16 path-exists: 4.0.0 which-pm: 2.0.0 - dev: true - /prelude-ls@1.1.2: - resolution: {integrity: sha512-ESF23V4SKG6lVSGZgYNpbsiaAkdab6ZgOxe52p7+Kid3W3u3bxR4Vfd/o21dmN7jSt0IwgZ4v5MUd26FEtXE9w==} - engines: {node: '>= 0.8.0'} - dev: true + prelude-ls@1.1.2: {} - /prelude-ls@1.2.1: - resolution: {integrity: sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==} - engines: {node: '>= 0.8.0'} - dev: true + prelude-ls@1.2.1: {} - /prettier-linter-helpers@1.0.0: - resolution: {integrity: sha512-GbK2cP9nraSSUF9N2XwUwqfzlAFlMNYYl+ShE/V+H8a9uNl/oUqB1w2EL54Jh0OlyRSd8RfWYJ3coVS4TROP2w==} - engines: {node: '>=6.0.0'} + prettier-linter-helpers@1.0.0: dependencies: fast-diff: 1.2.0 - dev: true - /prettier@2.8.4: - resolution: {integrity: sha512-vIS4Rlc2FNh0BySk3Wkd6xmwxB0FpOndW5fisM5H8hsZSxU2VWVB5CWIkIjWvrHjIhxk2g3bfMKM87zNTrZddw==} - engines: {node: '>=10.13.0'} - hasBin: true - dev: true + prettier@2.8.4: {} - /prettier@3.0.0: - resolution: {integrity: sha512-zBf5eHpwHOGPC47h0zrPyNn+eAEIdEzfywMoYn2XPi0P44Zp0tSq64rq0xAREh4auw2cJZHo9QUob+NqCQky4g==} - engines: {node: '>=14'} - hasBin: true - dev: true + prettier@3.0.0: {} - /pretty-bytes@6.1.1: - resolution: {integrity: sha512-mQUvGU6aUFQ+rNvTIAcZuWGRT9a6f6Yrg9bHs4ImKF+HZCEK+plBvnAZYSIQztknZF2qnzNtr6F8s0+IuptdlQ==} - engines: {node: ^14.13.1 || >=16.0.0} - dev: true + pretty-bytes@6.1.1: {} - /pretty-format@27.5.1: - resolution: {integrity: sha512-Qb1gy5OrP5+zDf2Bvnzdl3jsTf1qXVMazbvCoKhtKqVs4/YK4ozX4gKQJJVyNe+cajNPn0KoC0MC3FUmaHWEmQ==} - engines: {node: ^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0} + pretty-format@27.5.1: dependencies: ansi-regex: 5.0.1 ansi-styles: 5.2.0 react-is: 17.0.2 - dev: true - /pretty-format@29.7.0: - resolution: {integrity: sha512-Pdlw/oPxN+aXdmM9R00JVC9WVFoCLTKJvDVLgmJ+qAffBMxsV85l/Lu7sNx4zSzPyoL2euImuEwHhOXdEgNFZQ==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + pretty-format@29.7.0: dependencies: '@jest/schemas': 29.6.3 ansi-styles: 5.2.0 react-is: 18.2.0 - dev: true - - /prismjs@1.27.0: - resolution: {integrity: sha512-t13BGPUlFDR7wRB5kQDG4jjl7XeuH6jbJGt11JHPL96qwsEHNX2+68tFXqc1/k+/jALsbSWJKUOT/hcYAZ5LkA==} - engines: {node: '>=6'} - dev: true - /process@0.11.10: - resolution: {integrity: sha512-cdGef/drWFoydD1JsMzuFf8100nZl+GT+yacc2bEced5f9Rjk4z+WtFUTBu9PhOi9j/jfmBPu0mMEY4wIdAF8A==} - engines: {node: '>= 0.6.0'} + prismjs@1.27.0: {} - /progress@2.0.3: - resolution: {integrity: sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==} - engines: {node: '>=0.4.0'} - dev: true + process@0.11.10: {} - /prompts@2.4.2: - resolution: {integrity: sha512-NxNv/kLguCA7p3jE8oL2aEBsrJWgAakBpgmgK6lpPWV+WuOmY6r2/zbAVnP+T8bQlA0nzHXSJSJW0Hq7ylaD2Q==} - engines: {node: '>= 6'} + progress@2.0.3: {} + + prompts@2.4.2: dependencies: kleur: 3.0.3 sisteransi: 1.0.5 - dev: true - /prop-types@15.8.1: - resolution: {integrity: sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==} + prop-types@15.8.1: dependencies: loose-envify: 1.4.0 object-assign: 4.1.1 react-is: 16.13.1 - dev: true - /propagate@2.0.1: - resolution: {integrity: sha512-vGrhOavPSTz4QVNuBNdcNXePNdNMaO1xj9yBeH1ScQPjk/rhg9sSlCXPhMkFuaNNW/syTvYqsnbIJxMBfRbbag==} - engines: {node: '>= 8'} - dev: true + propagate@2.0.1: {} - /property-information@5.6.0: - resolution: {integrity: sha512-YUHSPk+A30YPv+0Qf8i9Mbfe/C0hdPXk1s1jPVToV8pk8BQtpw10ct89Eo7OWkutrwqvT0eicAxlOg3dOAu8JA==} + property-information@5.6.0: dependencies: xtend: 4.0.2 - dev: true - /property-information@6.2.0: - resolution: {integrity: sha512-kma4U7AFCTwpqq5twzC1YVIDXSqg6qQK6JN0smOw8fgRy1OkMi0CYSzFmsy6dnqSenamAtj0CyXMUJ1Mf6oROg==} - dev: true + property-information@6.2.0: {} - /proto-props@2.0.0: - resolution: {integrity: sha512-2yma2tog9VaRZY2mn3Wq51uiSW4NcPYT1cQdBagwyrznrilKSZwIZ0UG3ZPL/mx+axEns0hE35T5ufOYZXEnBQ==} - engines: {node: '>=4'} - dev: true + proto-props@2.0.0: {} - /proxy-agent@6.4.0: - resolution: {integrity: sha512-u0piLU+nCOHMgGjRbimiXmA9kM/L9EHh3zL81xCdp7m+Y2pHIsnmbdDoEDoAz5geaonNR6q6+yOPQs6n4T6sBQ==} - engines: {node: '>= 14'} + proxy-agent@6.4.0: dependencies: agent-base: 7.1.0 debug: 4.3.4 @@ -18662,38 +22205,23 @@ packages: socks-proxy-agent: 8.0.2 transitivePeerDependencies: - supports-color - dev: true - /proxy-from-env@1.1.0: - resolution: {integrity: sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==} - dev: true + proxy-from-env@1.1.0: {} - /pseudomap@1.0.2: - resolution: {integrity: sha512-b/YwNhb8lk1Zz2+bXXpS/LK9OisiZZ1SNsSLxN1x2OXVEhW2Ckr/7mWE5vrC1ZTiJlD9g19jWszTmJsB+oEpFQ==} - dev: true + pseudomap@1.0.2: {} - /psl@1.9.0: - resolution: {integrity: sha512-E/ZsdU4HLs/68gYzgGTkMicWTLPdAftJLfJFlLUAAKZGkStNU72sZjT66SnMDVOfOWY/YAoiD7Jxa9iHvngcag==} - dev: true + psl@1.9.0: {} - /pstree.remy@1.1.8: - resolution: {integrity: sha512-77DZwxQmxKnu3aR542U+X8FypNzbfJ+C5XQDk3uWjWxn6151aIMGthWYRXTqT1E5oJvg+ljaa2OJi+VfvCOQ8w==} - dev: true + pstree.remy@1.1.8: {} - /pump@3.0.0: - resolution: {integrity: sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==} + pump@3.0.0: dependencies: end-of-stream: 1.4.4 once: 1.4.0 - dev: true - /punycode@2.3.0: - resolution: {integrity: sha512-rRV+zQD8tVFys26lAGR9WUuS4iUAngJScM+ZRSKtvl5tKeZ2t5bvdNFdNHBW9FWR4guGHlgmsZ1G7BSm2wTbuA==} - engines: {node: '>=6'} + punycode@2.3.0: {} - /puppeteer-core@22.6.5: - resolution: {integrity: sha512-s0/5XkAWe0/dWISiljdrybjwDCHhgN31Nu/wznOZPKeikgcJtZtbvPKBz0t802XWqfSQnQDt3L6xiAE5JLlfuw==} - engines: {node: '>=18'} + puppeteer-core@22.6.5: dependencies: '@puppeteer/browsers': 2.2.2 chromium-bidi: 0.5.17(devtools-protocol@0.0.1262051) @@ -18704,13 +22232,8 @@ packages: - bufferutil - supports-color - utf-8-validate - dev: true - /puppeteer@22.6.5(typescript@5.3.3): - resolution: {integrity: sha512-YuoRKGj3MxHhUwrey7vmNvU4odGdUdNsj1ee8pfcqQlLWIXfMOXZCAXh8xdzpZESHH3tCGWp2xmPZE8E6iUEWg==} - engines: {node: '>=18'} - hasBin: true - requiresBuild: true + puppeteer@22.6.5(typescript@5.3.3): dependencies: '@puppeteer/browsers': 2.2.2 cosmiconfig: 9.0.0(typescript@5.3.3) @@ -18721,111 +22244,62 @@ packages: - supports-color - typescript - utf-8-validate - dev: true - /pure-rand@6.0.0: - resolution: {integrity: sha512-rLSBxJjP+4DQOgcJAx6RZHT2he2pkhQdSnofG5VWyVl6GRq/K02ISOuOLcsMOrtKDIJb8JN2zm3FFzWNbezdPw==} - dev: true + pure-rand@6.0.0: {} - /pvtsutils@1.3.5: - resolution: {integrity: sha512-ARvb14YB9Nm2Xi6nBq1ZX6dAM0FsJnuk+31aUp4TrcZEdKUlSqOqsxJHUPJDNE3qiIp+iUPEIeR6Je/tgV7zsA==} + pvtsutils@1.3.5: dependencies: tslib: 2.6.2 - dev: false - /pvutils@1.1.3: - resolution: {integrity: sha512-pMpnA0qRdFp32b1sJl1wOJNxZLQ2cbQx+k6tjNtZ8CpvVhNqEPRgivZ2WOUev2YMajecdH7ctUPDvEe87nariQ==} - engines: {node: '>=6.0.0'} - dev: false + pvutils@1.1.3: {} - /qrcode@1.5.3: - resolution: {integrity: sha512-puyri6ApkEHYiVl4CFzo1tDkAZ+ATcnbJrJ6RiBM1Fhctdn/ix9MTE3hRph33omisEbC/2fcfemsseiKgBPKZg==} - engines: {node: '>=10.13.0'} - hasBin: true + qrcode@1.5.3: dependencies: dijkstrajs: 1.0.3 encode-utf8: 1.0.3 pngjs: 5.0.0 yargs: 15.4.1 - dev: false - /qs@6.12.1: - resolution: {integrity: sha512-zWmv4RSuB9r2mYQw3zxQuHWeU+42aKi1wWig/j4ele4ygELZ7PEO6MM7rim9oAQH2A5MWfsAVf/jPvTPgCbvUQ==} - engines: {node: '>=0.6'} + qs@6.12.1: dependencies: side-channel: 1.0.6 - /query-string@9.0.0: - resolution: {integrity: sha512-4EWwcRGsO2H+yzq6ddHcVqkCQ2EFUSfDMEjF8ryp8ReymyZhIuaFRGLomeOQLkrzacMHoyky2HW0Qe30UbzkKw==} - engines: {node: '>=18'} + query-string@9.0.0: dependencies: decode-uri-component: 0.4.1 filter-obj: 5.1.0 split-on-first: 3.0.0 - dev: false - /querystringify@2.2.0: - resolution: {integrity: sha512-FIqgj2EUvTa7R50u0rGsyTftzjYmv/a3hO345bZNrqabNqjtgiDMgmo4mkUjd+nzU5oF3dClKqFIPUKybUyqoQ==} - dev: true + querystringify@2.2.0: {} - /queue-microtask@1.2.3: - resolution: {integrity: sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==} - dev: true + queue-microtask@1.2.3: {} - /queue-tick@1.0.1: - resolution: {integrity: sha512-kJt5qhMxoszgU/62PLP1CJytzd2NKetjSRnyuj31fDd3Rlcz3fzlFdFLD1SItunPwyqEOkca6GbV612BWfaBag==} - requiresBuild: true - dev: true + queue-tick@1.0.1: {} - /quick-lru@4.0.1: - resolution: {integrity: sha512-ARhCpm70fzdcvNQfPoy49IaanKkTlRWF2JMzqhcJbhSFRZv7nPTvZJdcY7301IPmvW+/p0RgIWnQDLJxifsQ7g==} - engines: {node: '>=8'} - dev: true + quick-lru@4.0.1: {} - /quick-lru@5.1.1: - resolution: {integrity: sha512-WuyALRjWPDGtt/wzJiadO5AXY+8hZ80hVpe6MyivgraREW751X3SbhRvG3eLKOYN+8VEvqLcf3wdnt44Z4S4SA==} - engines: {node: '>=10'} + quick-lru@5.1.1: {} - /quick-lru@6.1.1: - resolution: {integrity: sha512-S27GBT+F0NTRiehtbrgaSE1idUAJ5bX8dPAQTdylEyNlrdcH5X4Lz7Edz3DYzecbsCluD5zO8ZNEe04z3D3u6Q==} - engines: {node: '>=12'} + quick-lru@6.1.1: {} - /quick-lru@7.0.0: - resolution: {integrity: sha512-MX8gB7cVYTrYcFfAnfLlhRd0+Toyl8yX8uBx1MrX7K0jegiz9TumwOK27ldXrgDlHRdVi+MqU9Ssw6dr4BNreg==} - engines: {node: '>=18'} - dev: false + quick-lru@7.0.0: {} - /range-parser@1.2.1: - resolution: {integrity: sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==} - engines: {node: '>= 0.6'} - dev: true + range-parser@1.2.1: {} - /raw-body@2.5.2: - resolution: {integrity: sha512-8zGqypfENjCIqGhgXToC8aB2r7YrBX+AQAfIPs/Mlk+BtPTztOvTS01NRW/3Eh60J+a48lt8qsCzirQ6loCVfA==} - engines: {node: '>= 0.8'} + raw-body@2.5.2: dependencies: bytes: 3.1.2 http-errors: 2.0.0 iconv-lite: 0.4.24 unpipe: 1.0.0 - dev: false - /react-animate-height@3.0.4(react-dom@18.2.0)(react@18.2.0): - resolution: {integrity: sha512-k+mBS8yCzpFp+7BdrHsL5bXd6CO/2bYO2SvRGKfxK+Ss3nzplAJLlgnd6Zhcxe/avdpy/CgcziicFj7pIHgG5g==} - engines: {node: '>= 12.0.0'} - peerDependencies: - react: '>=16.8.0 || ^18.0.0' - react-dom: '>=16.8.0' + react-animate-height@3.0.4(react-dom@18.2.0)(react@18.2.0): dependencies: classnames: 2.3.1 react: 18.2.0 react-dom: 18.2.0(react@18.2.0) - dev: true - /react-color@2.19.3(react@18.2.0): - resolution: {integrity: sha512-LEeGE/ZzNLIsFWa1TMe8y5VYqr7bibneWmvJwm1pCn/eNmrabWDh659JSPn9BuaMpEfU83WTOJfnCcjDZwNQTA==} - peerDependencies: - react: '*' + react-color@2.19.3(react@18.2.0): dependencies: '@icons/material': 0.2.4(react@18.2.0) lodash: 4.17.21 @@ -18835,49 +22309,23 @@ packages: react: 18.2.0 reactcss: 1.2.3(react@18.2.0) tinycolor2: 1.6.0 - dev: true - /react-confetti@6.1.0(react@18.2.0): - resolution: {integrity: sha512-7Ypx4vz0+g8ECVxr88W9zhcQpbeujJAVqL14ZnXJ3I23mOI9/oBVTQ3dkJhUmB0D6XOtCZEM6N0Gm9PMngkORw==} - engines: {node: '>=10.18'} - peerDependencies: - react: ^16.3.0 || ^17.0.1 || ^18.0.0 + react-confetti@6.1.0(react@18.2.0): dependencies: react: 18.2.0 tween-functions: 1.2.0 - dev: true - /react-device-detect@2.2.3(react-dom@18.2.0)(react@18.2.0): - resolution: {integrity: sha512-buYY3qrCnQVlIFHrC5UcUoAj7iANs/+srdkwsnNjI7anr3Tt7UY6MqNxtMLlr0tMBied0O49UZVK8XKs3ZIiPw==} - peerDependencies: - react: '>= 0.14.0 || ^18.0.0' - react-dom: '>= 0.14.0' + react-device-detect@2.2.3(react-dom@18.2.0)(react@18.2.0): dependencies: react: 18.2.0 react-dom: 18.2.0(react@18.2.0) ua-parser-js: 1.0.37 - dev: true - /react-dnd-html5-backend@16.0.0: - resolution: {integrity: sha512-be3lKEbbT8FQcoTjFlQ4ZXG/NVrFNJu9W0INc5rm/5EFQpHCkz+xpbB2U8j9uh5Bvk7AsJyQrZznEut0hrNPIA==} + react-dnd-html5-backend@16.0.0: dependencies: dnd-core: 16.0.0 - dev: true - /react-dnd@16.0.0(@types/node@20.12.7)(@types/react@18.0.31)(react@18.2.0): - resolution: {integrity: sha512-RCoeWRWhuwSoqdLaJV8N/weARLyXqsf43OC3QiBWPORIIGGovF/EqI8ckf14ca3bl6oZNI/igtxX49+IDmNDeQ==} - peerDependencies: - '@types/hoist-non-react-statics': '>= 3.3.1' - '@types/node': '>= 12' - '@types/react': '>= 16' - react: '>= 16.14 || ^18.0.0' - peerDependenciesMeta: - '@types/hoist-non-react-statics': - optional: true - '@types/node': - optional: true - '@types/react': - optional: true + react-dnd@16.0.0(@types/node@20.12.7)(@types/react@18.0.31)(react@18.2.0): dependencies: '@react-dnd/invariant': 4.0.0 '@react-dnd/shallowequal': 4.0.0 @@ -18887,133 +22335,70 @@ packages: fast-deep-equal: 3.1.3 hoist-non-react-statics: 3.3.2 react: 18.2.0 - dev: true - /react-dom@18.2.0(react@18.2.0): - resolution: {integrity: sha512-6IMTriUmvsjHUjNtEDudZfuDQUoWXVxKHhlEGSk81n4YFS+r/Kl99wXiwlVXtPBtJenozv2P+hxDsw9eA7Xo6g==} - peerDependencies: - react: ^18.2.0 || ^18.0.0 + react-dom@18.2.0(react@18.2.0): dependencies: loose-envify: 1.4.0 react: 18.2.0 scheduler: 0.23.0 - dev: true - /react-dropzone@14.2.3(react@18.2.0): - resolution: {integrity: sha512-O3om8I+PkFKbxCukfIR3QAGftYXDZfOE2N1mr/7qebQJHs7U+/RSL/9xomJNpRg9kM5h9soQSdf0Gc7OHF5Fug==} - engines: {node: '>= 10.13'} - peerDependencies: - react: '>= 16.8 || 18.0.0 || ^18.0.0' + react-dropzone@14.2.3(react@18.2.0): dependencies: attr-accept: 2.2.2 file-selector: 0.6.0 prop-types: 15.8.1 react: 18.2.0 - dev: true - /react-error-boundary@3.1.4(react@18.2.0): - resolution: {integrity: sha512-uM9uPzZJTF6wRQORmSrvOIgt4lJ9MC1sNgEOj2XGsDTRE4kmpWxg7ENK9EWNKJRMAOY9z0MuF4yIfl6gp4sotA==} - engines: {node: '>=10', npm: '>=6'} - peerDependencies: - react: '>=16.13.1 || ^18.0.0' + react-error-boundary@3.1.4(react@18.2.0): dependencies: '@babel/runtime': 7.21.0 react: 18.2.0 - dev: true - /react-error-overlay@6.0.9: - resolution: {integrity: sha512-nQTTcUu+ATDbrSD1BZHr5kgSD4oF8OFjxun8uAaL8RwPBacGBNPf/yAuVVdx17N8XNzRDMrZ9XcKZHCjPW+9ew==} - dev: true + react-error-overlay@6.0.9: {} - /react-fast-compare@3.2.1: - resolution: {integrity: sha512-xTYf9zFim2pEif/Fw16dBiXpe0hoy5PxcD8+OwBnTtNLfIm3g6WxhKNurY+6OmdH1u6Ta/W/Vl6vjbYP1MFnDg==} - dev: true + react-fast-compare@3.2.1: {} - /react-helmet@6.1.0(react@18.2.0): - resolution: {integrity: sha512-4uMzEY9nlDlgxr61NL3XbKRy1hEkXmKNXhjbAIOVw5vcFrsdYbH2FEwcNyWvWinl103nXgzYNlns9ca+8kFiWw==} - peerDependencies: - react: '>=16.3.0 || ^18.0.0' + react-helmet@6.1.0(react@18.2.0): dependencies: object-assign: 4.1.1 prop-types: 15.8.1 react: 18.2.0 react-fast-compare: 3.2.1 react-side-effect: 2.1.2(react@18.2.0) - dev: true - /react-hook-form@7.34.0(react@18.2.0): - resolution: {integrity: sha512-s0/TJ09NVlEk2JPp3yit1WnMuPNBXFmUKEQPulgDi9pYBw/ZmmAFHe6AXWq73Y+kp8ye4OcMf0Jv+i/qLPektg==} - engines: {node: '>=12.22.0'} - peerDependencies: - react: ^16.8.0 || ^17 || ^18 || ^18.0.0 + react-hook-form@7.34.0(react@18.2.0): dependencies: react: 18.2.0 - dev: true - /react-hook-form@7.43.9(react@18.2.0): - resolution: {integrity: sha512-AUDN3Pz2NSeoxQ7Hs6OhQhDr6gtF9YRuutGDwPQqhSUAHJSgGl2VeY3qN19MG0SucpjgDiuMJ4iC5T5uB+eaNQ==} - engines: {node: '>=12.22.0'} - peerDependencies: - react: ^16.8.0 || ^17 || ^18 || ^18.0.0 + react-hook-form@7.43.9(react@18.2.0): dependencies: react: 18.2.0 - dev: true - /react-hot-toast@2.2.0(csstype@3.0.11)(react-dom@18.2.0)(react@18.2.0): - resolution: {integrity: sha512-248rXw13uhf/6TNDVzagX+y7R8J183rp7MwUMNkcrBRyHj/jWOggfXTGlM8zAOuh701WyVW+eUaWG2LeSufX9g==} - engines: {node: '>=10'} - peerDependencies: - react: '>=16 || ^18.0.0' - react-dom: '>=16' + react-hot-toast@2.2.0(csstype@3.0.11)(react-dom@18.2.0)(react@18.2.0): dependencies: goober: 2.1.8(csstype@3.0.11) react: 18.2.0 react-dom: 18.2.0(react@18.2.0) transitivePeerDependencies: - csstype - dev: true - /react-i18next@12.3.1(i18next@22.4.15)(react-dom@18.2.0)(react@18.2.0): - resolution: {integrity: sha512-5v8E2XjZDFzK7K87eSwC7AJcAkcLt5xYZ4+yTPDAW1i7C93oOY1dnr4BaQM7un4Hm+GmghuiPvevWwlca5PwDA==} - peerDependencies: - i18next: '>= 19.0.0' - react: '>= 16.8.0 || ^18.0.0' - react-dom: '*' - react-native: '*' - peerDependenciesMeta: - react-dom: - optional: true - react-native: - optional: true + react-i18next@12.3.1(i18next@22.4.15)(react-dom@18.2.0)(react@18.2.0): dependencies: '@babel/runtime': 7.21.0 html-parse-stringify: 3.0.1 i18next: 22.4.15 react: 18.2.0 react-dom: 18.2.0(react@18.2.0) - dev: true - /react-is@16.13.1: - resolution: {integrity: sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==} - dev: true + react-is@16.13.1: {} - /react-is@17.0.2: - resolution: {integrity: sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==} - dev: true + react-is@17.0.2: {} - /react-is@18.2.0: - resolution: {integrity: sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==} - dev: true + react-is@18.2.0: {} - /react-lifecycles-compat@3.0.4: - resolution: {integrity: sha512-fBASbA6LnOU9dOU2eW7aQ8xmYBSXUIWr+UmF9b1efZBazGNO+rcXT/icdKnYm2pTwcRylVUYwW7H1PHfLekVzA==} - dev: true + react-lifecycles-compat@3.0.4: {} - /react-markdown@9.0.0(@types/react@18.0.31)(react@18.2.0): - resolution: {integrity: sha512-v6yNf3AB8GfJ8lCpUvzxAXKxgsHpdmWPlcVRQ6Nocsezp255E/IDrF31kLQsPJeB/cKto/geUwjU36wH784FCA==} - peerDependencies: - '@types/react': '>=18' - react: '>=18 || ^18.0.0' + react-markdown@9.0.0(@types/react@18.0.31)(react@18.2.0): dependencies: '@types/hast': 3.0.1 '@types/react': 18.0.31 @@ -19030,14 +22415,8 @@ packages: vfile: 6.0.1 transitivePeerDependencies: - supports-color - dev: true - /react-modal@3.15.1(react-dom@18.2.0)(react@18.2.0): - resolution: {integrity: sha512-duB9bxOaYg7Zt6TMFldIFxQRtSP+Dg3F1ZX3FXxSUn+3tZZ/9JCgeAQKDg7rhZSAqopq8TFRw3yIbnx77gyFTw==} - engines: {node: '>=8'} - peerDependencies: - react: ^0.14.0 || ^15.0.0 || ^16 || ^17 || ^18 || ^18.0.0 - react-dom: ^0.14.0 || ^15.0.0 || ^16 || ^17 || ^18 + react-modal@3.15.1(react-dom@18.2.0)(react@18.2.0): dependencies: exenv: 1.2.2 prop-types: 15.8.1 @@ -19045,87 +22424,47 @@ packages: react-dom: 18.2.0(react@18.2.0) react-lifecycles-compat: 3.0.4 warning: 4.0.3 - dev: true - /react-paginate@8.1.3(react@18.2.0): - resolution: {integrity: sha512-zBp80DBRcaeBnAeHUfbGKD0XHfbGNUolQ+S60Ymfs8o7rusYaJYZMAt1j93ADDNLlzRmJ0tMF/NeTlcdKf7dlQ==} - peerDependencies: - react: ^16 || ^17 || ^18 || ^18.0.0 + react-paginate@8.1.3(react@18.2.0): dependencies: prop-types: 15.8.1 react: 18.2.0 - dev: true - /react-refresh@0.9.0: - resolution: {integrity: sha512-Gvzk7OZpiqKSkxsQvO/mbTN1poglhmAV7gR/DdIrRrSMXraRQQlfikRJOr3Nb9GTMPC5kof948Zy6jJZIFtDvQ==} - engines: {node: '>=0.10.0'} - dev: true + react-refresh@0.9.0: {} - /react-resize-detector@7.1.2(react-dom@18.2.0)(react@18.2.0): - resolution: {integrity: sha512-zXnPJ2m8+6oq9Nn8zsep/orts9vQv3elrpA+R8XTcW7DVVUJ9vwDwMXaBtykAYjMnkCIaOoK9vObyR7ZgFNlOw==} - peerDependencies: - react: ^16.0.0 || ^17.0.0 || ^18.0.0 - react-dom: ^16.0.0 || ^17.0.0 || ^18.0.0 + react-resize-detector@7.1.2(react-dom@18.2.0)(react@18.2.0): dependencies: lodash: 4.17.21 react: 18.2.0 react-dom: 18.2.0(react@18.2.0) - dev: true - /react-router-dom@6.10.0(react-dom@18.2.0)(react@18.2.0): - resolution: {integrity: sha512-E5dfxRPuXKJqzwSe/qGcqdwa18QiWC6f3H3cWXM24qj4N0/beCIf/CWTipop2xm7mR0RCS99NnaqPNjHtrAzCg==} - engines: {node: '>=14'} - peerDependencies: - react: '>=16.8 || ^18.0.0' - react-dom: '>=16.8' + react-router-dom@6.10.0(react-dom@18.2.0)(react@18.2.0): dependencies: '@remix-run/router': 1.5.0 react: 18.2.0 react-dom: 18.2.0(react@18.2.0) react-router: 6.10.0(react@18.2.0) - dev: true - /react-router@6.10.0(react@18.2.0): - resolution: {integrity: sha512-Nrg0BWpQqrC3ZFFkyewrflCud9dio9ME3ojHCF/WLsprJVzkq3q3UeEhMCAW1dobjeGbWgjNn/PVF6m46ANxXQ==} - engines: {node: '>=14'} - peerDependencies: - react: '>=16.8 || ^18.0.0' + react-router@6.10.0(react@18.2.0): dependencies: '@remix-run/router': 1.5.0 react: 18.2.0 - dev: true - /react-side-effect@2.1.2(react@18.2.0): - resolution: {integrity: sha512-PVjOcvVOyIILrYoyGEpDN3vmYNLdy1CajSFNt4TDsVQC5KpTijDvWVoR+/7Rz2xT978D8/ZtFceXxzsPwZEDvw==} - peerDependencies: - react: ^16.3.0 || ^17.0.0 || ^18.0.0 + react-side-effect@2.1.2(react@18.2.0): dependencies: react: 18.2.0 - dev: true - /react-smooth@2.0.1(prop-types@15.8.1)(react-dom@18.2.0)(react@18.2.0): - resolution: {integrity: sha512-Own9TA0GPPf3as4vSwFhDouVfXP15ie/wIHklhyKBH5AN6NFtdk0UpHBnonV11BtqDkAWlt40MOUc+5srmW7NA==} - peerDependencies: - prop-types: ^15.6.0 - react: ^15.0.0 || ^16.0.0 || ^17.0.0 || ^18.0.0 - react-dom: ^15.0.0 || ^16.0.0 || ^17.0.0 || ^18.0.0 + react-smooth@2.0.1(prop-types@15.8.1)(react-dom@18.2.0)(react@18.2.0): dependencies: fast-equals: 2.0.4 prop-types: 15.8.1 react: 18.2.0 react-dom: 18.2.0(react@18.2.0) react-transition-group: 2.9.0(react-dom@18.2.0)(react@18.2.0) - dev: true - /react-string-replace@1.0.0: - resolution: {integrity: sha512-+iLsyE4AeSmnfctgswXOf1PmKRgns6wJ4LVb+8ADMU6mDK3jvBE11QzfMQf7CYtPUUiBCDjZ9ZppzXOIYrzCRg==} - engines: {node: '>=0.12.0'} - dev: true + react-string-replace@1.0.0: {} - /react-syntax-highlighter@15.5.0(react@18.2.0): - resolution: {integrity: sha512-+zq2myprEnQmH5yw6Gqc8lD55QHnpKaU8TOcFeC/Lg/MQSs8UknEA0JC4nTZGFAXC2J2Hyj/ijJ7NlabyPi2gg==} - peerDependencies: - react: '>= 0.14.0 || ^18.0.0' + react-syntax-highlighter@15.5.0(react@18.2.0): dependencies: '@babel/runtime': 7.17.9 highlight.js: 10.7.3 @@ -19133,32 +22472,17 @@ packages: prismjs: 1.27.0 react: 18.2.0 refractor: 3.6.0 - dev: true - /react-timer-hook@3.0.5(react-dom@18.2.0)(react@18.2.0): - resolution: {integrity: sha512-n+98SdmYvui2ne3KyWb3Ldu4k0NYQa3g/VzW6VEIfZJ8GAk/jJsIY700M8Nd2vNSTj05c7wKyQfJBqZ0x7zfiA==} - peerDependencies: - react: '>=16.8.0 || ^18.0.0' - react-dom: '>=16.8.0' + react-timer-hook@3.0.5(react-dom@18.2.0)(react@18.2.0): dependencies: react: 18.2.0 react-dom: 18.2.0(react@18.2.0) - dev: true - /react-top-loading-bar@2.3.1(react@18.2.0): - resolution: {integrity: sha512-rQk2Nm+TOBrM1C4E3e6KwT65iXyRSgBHjCkr2FNja1S51WaPulRA5nKj/xazuQ3x89wDDdGsrqkqy0RBIfd0xg==} - engines: {node: '>=10'} - peerDependencies: - react: ^16 || ^17 || ^18 || ^18.0.0 + react-top-loading-bar@2.3.1(react@18.2.0): dependencies: react: 18.2.0 - dev: true - /react-transition-group@2.9.0(react-dom@18.2.0)(react@18.2.0): - resolution: {integrity: sha512-+HzNTCHpeQyl4MJ/bdE0u6XRMe9+XG/+aL4mCxVN4DnPBQ0/5bfHWPDuOZUzYdMj94daZaZdCCc1Dzt9R/xSSg==} - peerDependencies: - react: '>=15.0.0 || ^18.0.0' - react-dom: '>=15.0.0' + react-transition-group@2.9.0(react-dom@18.2.0)(react@18.2.0): dependencies: dom-helpers: 3.4.0 loose-envify: 1.4.0 @@ -19166,100 +22490,64 @@ packages: react: 18.2.0 react-dom: 18.2.0(react@18.2.0) react-lifecycles-compat: 3.0.4 - dev: true - /react@18.2.0: - resolution: {integrity: sha512-/3IjMdb2L9QbBdWiW5e3P2/npwMBaU9mHCSCUzNln0ZCYbcfTsGbTJrU/kGemdH2IWmB2ioZ+zkxtmq6g09fGQ==} - engines: {node: '>=0.10.0'} + react@18.2.0: dependencies: loose-envify: 1.4.0 - dev: true - /reactcss@1.2.3(react@18.2.0): - resolution: {integrity: sha512-KiwVUcFu1RErkI97ywr8nvx8dNOpT03rbnma0SSalTYjkrPYaEajR4a/MRt6DZ46K6arDRbWMNHF+xH7G7n/8A==} - peerDependencies: - react: '*' + reactcss@1.2.3(react@18.2.0): dependencies: lodash: 4.17.21 react: 18.2.0 - dev: true - /read-pkg-up@7.0.1: - resolution: {integrity: sha512-zK0TB7Xd6JpCLmlLmufqykGE+/TlOePD6qKClNW7hHDKFh/J7/7gCWGR7joEQEW1bKq3a3yUZSObOoWLFQ4ohg==} - engines: {node: '>=8'} + read-pkg-up@7.0.1: dependencies: find-up: 4.1.0 read-pkg: 5.2.0 type-fest: 0.8.1 - dev: true - /read-pkg-up@8.0.0: - resolution: {integrity: sha512-snVCqPczksT0HS2EC+SxUndvSzn6LRCwpfSvLrIfR5BKDQQZMaI6jPRC9dYvYFDRAuFEAnkwww8kBBNE/3VvzQ==} - engines: {node: '>=12'} + read-pkg-up@8.0.0: dependencies: find-up: 5.0.0 read-pkg: 6.0.0 type-fest: 1.4.0 - dev: true - /read-pkg@5.2.0: - resolution: {integrity: sha512-Ug69mNOpfvKDAc2Q8DRpMjjzdtrnv9HcSMX+4VsZxD1aZ6ZzrIE7rlzXBtWTyhULSMKg076AW6WR5iZpD0JiOg==} - engines: {node: '>=8'} + read-pkg@5.2.0: dependencies: '@types/normalize-package-data': 2.4.1 normalize-package-data: 2.5.0 parse-json: 5.2.0 type-fest: 0.6.0 - dev: true - /read-pkg@6.0.0: - resolution: {integrity: sha512-X1Fu3dPuk/8ZLsMhEj5f4wFAF0DWoK7qhGJvgaijocXxBmSToKfbFtqbxMO7bVjNA1dmE5huAzjXj/ey86iw9Q==} - engines: {node: '>=12'} + read-pkg@6.0.0: dependencies: '@types/normalize-package-data': 2.4.1 normalize-package-data: 3.0.3 parse-json: 5.2.0 type-fest: 1.4.0 - dev: true - /read-yaml-file@1.1.0: - resolution: {integrity: sha512-VIMnQi/Z4HT2Fxuwg5KrY174U1VdUIASQVWXXyqtNRtxSr9IYkn1rsI6Tb6HsrHCmB7gVpNwX6JxPTHcH6IoTA==} - engines: {node: '>=6'} + read-yaml-file@1.1.0: dependencies: graceful-fs: 4.2.11 js-yaml: 3.14.1 pify: 4.0.1 strip-bom: 3.0.0 - dev: true - /readable-stream@3.6.2: - resolution: {integrity: sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==} - engines: {node: '>= 6'} + readable-stream@3.6.2: dependencies: inherits: 2.0.4 string_decoder: 1.3.0 util-deprecate: 1.0.2 - /readdirp@3.6.0: - resolution: {integrity: sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==} - engines: {node: '>=8.10.0'} + readdirp@3.6.0: dependencies: picomatch: 2.3.1 - dev: true - /recharts-scale@0.4.5: - resolution: {integrity: sha512-kivNFO+0OcUNu7jQquLXAxz1FIwZj8nrj+YkOKc5694NbjCvcT6aSZiIzNzd2Kul4o4rTto8QVR9lMNtxD4G1w==} + recharts-scale@0.4.5: dependencies: decimal.js-light: 2.5.1 - dev: true - /recharts@2.1.13(prop-types@15.8.1)(react-dom@18.2.0)(react@18.2.0): - resolution: {integrity: sha512-9VWu2nzExmfiMFDHKqRFhYlJVmjzQGVKH5rBetXR4EuyEXuu3Y6cVxQuNEdusHhbm4SoPPrVDCwlBdREL3sQPA==} - engines: {node: '>=12'} - peerDependencies: - prop-types: ^15.6.0 - react: ^16.0.0 || ^17.0.0 || ^18.0.0 - react-dom: ^16.0.0 || ^17.0.0 || ^18.0.0 + recharts@2.1.13(prop-types@15.8.1)(react-dom@18.2.0)(react@18.2.0): dependencies: classnames: 2.3.1 d3-interpolate: 3.0.1 @@ -19275,26 +22563,18 @@ packages: react-smooth: 2.0.1(prop-types@15.8.1)(react-dom@18.2.0)(react@18.2.0) recharts-scale: 0.4.5 reduce-css-calc: 2.1.8 - dev: true - /redent@3.0.0: - resolution: {integrity: sha512-6tDA8g98We0zd0GvVeMT9arEOnTw9qM03L9cJXaCjrip1OO764RDBLBfrB4cwzNGDj5OA5ioymC9GkizgWJDUg==} - engines: {node: '>=8'} + redent@3.0.0: dependencies: indent-string: 4.0.0 strip-indent: 3.0.0 - dev: true - /redent@4.0.0: - resolution: {integrity: sha512-tYkDkVVtYkSVhuQ4zBgfvciymHaeuel+zFKXShfDnFP5SyVEP7qo70Rf1jTOTCx3vGNAbnEi/xFkcfQVMIBWag==} - engines: {node: '>=12'} + redent@4.0.0: dependencies: indent-string: 5.0.0 strip-indent: 4.0.0 - dev: true - /redis@4.6.5: - resolution: {integrity: sha512-O0OWA36gDQbswOdUuAhRL6mTZpHFN525HlgZgDaVNgCJIAZR3ya06NTESb0R+TUZ+BFaDpz6NnnVvoMx9meUFg==} + redis@4.6.5: dependencies: '@redis/bloom': 1.2.0(@redis/client@1.5.6) '@redis/client': 1.5.6 @@ -19302,24 +22582,17 @@ packages: '@redis/json': 1.0.4(@redis/client@1.5.6) '@redis/search': 1.1.2(@redis/client@1.5.6) '@redis/time-series': 1.0.4(@redis/client@1.5.6) - dev: false - /reduce-css-calc@2.1.8: - resolution: {integrity: sha512-8liAVezDmUcH+tdzoEGrhfbGcP7nOV4NkGE3a74+qqvE7nt9i4sKLGBuZNOnpI4WiGksiNPklZxva80061QiPg==} + reduce-css-calc@2.1.8: dependencies: css-unit-converter: 1.1.2 postcss-value-parser: 3.3.1 - dev: true - /redux@4.1.2: - resolution: {integrity: sha512-SH8PglcebESbd/shgf6mii6EIoRM0zrQyjcuQ+ojmfxjTtE0z9Y8pa62iA/OJ58qjP6j27uyW4kUF4jl/jd6sw==} + redux@4.1.2: dependencies: '@babel/runtime': 7.21.0 - dev: true - /reflect.getprototypeof@1.0.6: - resolution: {integrity: sha512-fmfw4XgoDke3kdI6h4xcUz1dG8uaiv5q9gcEwLS4Pnth2kxT+GZ7YehS1JTMGBQmtV7Y4GFGbs2re2NqhdozUg==} - engines: {node: '>= 0.4'} + reflect.getprototypeof@1.0.6: dependencies: call-bind: 1.0.7 define-properties: 1.2.1 @@ -19328,60 +22601,39 @@ packages: get-intrinsic: 1.2.4 globalthis: 1.0.3 which-builtin-type: 1.1.3 - dev: true - /refractor@3.6.0: - resolution: {integrity: sha512-MY9W41IOWxxk31o+YvFCNyNzdkc9M20NoZK5vq6jkv4I/uh2zkWcfudj0Q1fovjUQJrNewS9NMzeTtqPf+n5EA==} + refractor@3.6.0: dependencies: hastscript: 6.0.0 parse-entities: 2.0.0 prismjs: 1.27.0 - dev: true - /regenerator-runtime@0.13.11: - resolution: {integrity: sha512-kY1AZVr2Ra+t+piVaJ4gxaFaReZVH40AKNo7UCX6W+dEwBo/2oZJzqfuN1qLq1oL45o56cPaTXELwrTh8Fpggg==} + regenerator-runtime@0.13.11: {} - /regenerator-runtime@0.14.1: - resolution: {integrity: sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw==} - dev: true + regenerator-runtime@0.14.1: {} - /regexp-tree@0.1.27: - resolution: {integrity: sha512-iETxpjK6YoRWJG5o6hXLwvjYAoW+FEZn9os0PD/b6AP6xQwsa/Y7lCVgIixBbUPMfhu+i2LtdeAqVTgGlQarfA==} - hasBin: true - dev: true + regexp-tree@0.1.27: {} - /regexp.prototype.flags@1.4.3: - resolution: {integrity: sha512-fjggEOO3slI6Wvgjwflkc4NFRCTZAu5CnNfBd5qOMYhWdn67nJBBu34/TkD++eeFmd8C9r9jfXJ27+nSiRkSUA==} - engines: {node: '>= 0.4'} + regexp.prototype.flags@1.4.3: dependencies: call-bind: 1.0.7 define-properties: 1.1.4 functions-have-names: 1.2.3 - dev: true - /regexp.prototype.flags@1.5.2: - resolution: {integrity: sha512-NcDiDkTLuPR+++OCKB0nWafEmhg/Da8aUPLPMQbK+bxKKCm1/S5he+AqYa4PlMCVBalb4/yxIRub6qkEx5yJbw==} - engines: {node: '>= 0.4'} + regexp.prototype.flags@1.5.2: dependencies: call-bind: 1.0.7 define-properties: 1.2.1 es-errors: 1.3.0 set-function-name: 2.0.2 - dev: true - /regjsparser@0.10.0: - resolution: {integrity: sha512-qx+xQGZVsy55CH0a1hiVwHmqjLryfh7wQyF5HO07XJ9f7dQMY/gPQHhlyDkIzJKC+x2fUCpCcUODUUUFrm7SHA==} - hasBin: true + regjsparser@0.10.0: dependencies: jsesc: 0.5.0 - dev: true - /remark-footnotes@2.0.0: - resolution: {integrity: sha512-3Clt8ZMH75Ayjp9q4CorNeyjwIxHFcTkaektplKGl2A1jNGEUey8cKL0ZC5vJwfcD5GFGsNLImLG/NGzWIzoMQ==} - dev: true + remark-footnotes@2.0.0: {} - /remark-gfm@4.0.0: - resolution: {integrity: sha512-U92vJgBPkbw4Zfu/IiW2oTZLSL3Zpv+uI7My2eq8JxKgqraFdU8YUGicEJCEgSbeaG+QDFqIcwwfMTOEelPxuA==} + remark-gfm@4.0.0: dependencies: '@types/mdast': 4.0.1 mdast-util-gfm: 3.0.0 @@ -19391,10 +22643,8 @@ packages: unified: 11.0.3 transitivePeerDependencies: - supports-color - dev: true - /remark-mdx@1.6.22: - resolution: {integrity: sha512-phMHBJgeV76uyFkH4rvzCftLfKCr2RZuF+/gmVcaKrpsihyzmhXjA0BEMDaPTXG5y8qZOKPVo83NAOX01LPnOQ==} + remark-mdx@1.6.22: dependencies: '@babel/core': 7.12.9 '@babel/helper-plugin-utils': 7.10.4 @@ -19406,10 +22656,8 @@ packages: unified: 9.2.0 transitivePeerDependencies: - supports-color - dev: true - /remark-parse@11.0.0: - resolution: {integrity: sha512-FCxlKLNGknS5ba/1lmpYijMUzX2esxW5xQqjWxw2eHFfS2MSdaHVINFmhjo+qN1WhZhNimq0dZATN9pH0IDrpA==} + remark-parse@11.0.0: dependencies: '@types/mdast': 4.0.1 mdast-util-from-markdown: 2.0.0 @@ -19417,10 +22665,8 @@ packages: unified: 11.0.3 transitivePeerDependencies: - supports-color - dev: true - /remark-parse@8.0.3: - resolution: {integrity: sha512-E1K9+QLGgggHxCQtLt++uXltxEprmWzNfg+MxpfHsZlrddKzZ/hZyWHDbK3/Ap8HJQqYJRXP+jHczdL6q6i85Q==} + remark-parse@8.0.3: dependencies: ccount: 1.1.0 collapse-white-space: 1.0.6 @@ -19438,152 +22684,95 @@ packages: unist-util-remove-position: 2.0.1 vfile-location: 3.2.0 xtend: 4.0.2 - dev: true - /remark-rehype@11.0.0: - resolution: {integrity: sha512-vx8x2MDMcxuE4lBmQ46zYUDfcFMmvg80WYX+UNLeG6ixjdCCLcw1lrgAukwBTuOFsS78eoAedHGn9sNM0w7TPw==} + remark-rehype@11.0.0: dependencies: '@types/hast': 3.0.1 '@types/mdast': 4.0.1 mdast-util-to-hast: 13.0.2 unified: 11.0.3 vfile: 6.0.1 - dev: true - /remark-squeeze-paragraphs@4.0.0: - resolution: {integrity: sha512-8qRqmL9F4nuLPIgl92XUuxI3pFxize+F1H0e/W3llTk0UsjJaj01+RrirkMw7P21RKe4X6goQhYRSvNWX+70Rw==} + remark-squeeze-paragraphs@4.0.0: dependencies: mdast-squeeze-paragraphs: 4.0.0 - dev: true - /remark-stringify@11.0.0: - resolution: {integrity: sha512-1OSmLd3awB/t8qdoEOMazZkNsfVTeY4fTsgzcQFdXNq8ToTN4ZGwrMnlda4K6smTFKD+GRV6O48i6Z4iKgPPpw==} + remark-stringify@11.0.0: dependencies: '@types/mdast': 4.0.1 mdast-util-to-markdown: 2.1.0 unified: 11.0.3 - dev: true - /repeat-string@1.6.1: - resolution: {integrity: sha512-PV0dzCYDNfRi1jCDbJzpW7jNNDRuCOG/jI5ctQcGKt/clZD+YcPS3yIlWuTJMmESC8aevCFmWJy5wjAFgNqN6w==} - engines: {node: '>=0.10'} - dev: true + repeat-string@1.6.1: {} - /require-directory@2.1.1: - resolution: {integrity: sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==} - engines: {node: '>=0.10.0'} + require-directory@2.1.1: {} - /require-from-string@2.0.2: - resolution: {integrity: sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==} - engines: {node: '>=0.10.0'} - dev: true + require-from-string@2.0.2: {} - /require-in-the-middle@7.2.0: - resolution: {integrity: sha512-3TLx5TGyAY6AOqLBoXmHkNql0HIf2RGbuMgCDT2WO/uGVAPJs6h7Kl+bN6TIZGd9bWhWPwnDnTHGtW8Iu77sdw==} - engines: {node: '>=8.6.0'} + require-in-the-middle@7.2.0: dependencies: debug: 4.3.4 module-details-from-path: 1.0.3 resolve: 1.22.8 transitivePeerDependencies: - supports-color - dev: false - /require-main-filename@2.0.0: - resolution: {integrity: sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==} + require-main-filename@2.0.0: {} - /requires-port@1.0.0: - resolution: {integrity: sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ==} + requires-port@1.0.0: {} - /resolve-alpn@1.2.1: - resolution: {integrity: sha512-0a1F4l73/ZFZOakJnQ3FvkJ2+gSTQWz/r2KE5OdDY0TxPm5h4GkqkWWfM47T7HsbnOtcJVEF4epCVy6u7Q3K+g==} - dev: false + resolve-alpn@1.2.1: {} - /resolve-cwd@3.0.0: - resolution: {integrity: sha512-OrZaX2Mb+rJCpH/6CpSqt9xFVpN++x01XnN2ie9g6P5/3xelLAkXWVADpdz1IHD/KFfEXyE6V0U01OQ3UO2rEg==} - engines: {node: '>=8'} + resolve-cwd@3.0.0: dependencies: resolve-from: 5.0.0 - dev: true - /resolve-dir@0.1.1: - resolution: {integrity: sha512-QxMPqI6le2u0dCLyiGzgy92kjkkL6zO0XyvHzjdTNH3zM6e5Hz3BwG6+aEyNgiQ5Xz6PwTwgQEj3U50dByPKIA==} - engines: {node: '>=0.10.0'} + resolve-dir@0.1.1: dependencies: expand-tilde: 1.2.2 global-modules: 0.2.3 - dev: true - /resolve-from@4.0.0: - resolution: {integrity: sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==} - engines: {node: '>=4'} - dev: true + resolve-from@4.0.0: {} - /resolve-from@5.0.0: - resolution: {integrity: sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==} - engines: {node: '>=8'} - dev: true + resolve-from@5.0.0: {} - /resolve-path@1.4.0: - resolution: {integrity: sha1-xL2p9e+y/OZSR4c6s2u02DT+Fvc=} - engines: {node: '>= 0.8'} + resolve-path@1.4.0: dependencies: http-errors: 1.6.3 path-is-absolute: 1.0.1 - dev: false - /resolve-pkg-maps@1.0.0: - resolution: {integrity: sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw==} - dev: true + resolve-pkg-maps@1.0.0: {} - /resolve.exports@2.0.1: - resolution: {integrity: sha512-OEJWVeimw8mgQuj3HfkNl4KqRevH7lzeQNaWRPfx0PPse7Jk6ozcsG4FKVgtzDsC1KUF+YlTHh17NcgHOPykLw==} - engines: {node: '>=10'} - dev: true + resolve.exports@2.0.1: {} - /resolve@1.22.2: - resolution: {integrity: sha512-Sb+mjNHOULsBv818T40qSPeRiuWLyaGMa5ewydRLFimneixmVy2zdivRl+AF6jaYPC8ERxGDmFSiqui6SfPd+g==} - hasBin: true + resolve@1.22.2: dependencies: is-core-module: 2.12.1 path-parse: 1.0.7 supports-preserve-symlinks-flag: 1.0.0 - dev: true - /resolve@1.22.8: - resolution: {integrity: sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw==} - hasBin: true + resolve@1.22.8: dependencies: is-core-module: 2.13.1 path-parse: 1.0.7 supports-preserve-symlinks-flag: 1.0.0 - /resolve@2.0.0-next.5: - resolution: {integrity: sha512-U7WjGVG9sH8tvjW5SmGbQuui75FiyjAX72HX15DwBBwF9dNiQZRQAg9nnPhYy+TUnE0+VcrttuvNI8oSxZcocA==} - hasBin: true + resolve@2.0.0-next.5: dependencies: is-core-module: 2.13.1 path-parse: 1.0.7 supports-preserve-symlinks-flag: 1.0.0 - dev: true - /responselike@3.0.0: - resolution: {integrity: sha512-40yHxbNcl2+rzXvZuVkrYohathsSJlMTXKryG5y8uciHv1+xDLHQpgjG64JUO9nrEq2jGLH6IZ8BcZyw3wrweg==} - engines: {node: '>=14.16'} + responselike@3.0.0: dependencies: lowercase-keys: 3.0.0 - dev: false - /restore-cursor@4.0.0: - resolution: {integrity: sha512-I9fPXU9geO9bHOt9pHHOhOkYerIMsmVaWB0rA2AI9ERh/+x/i7MV5HKBNrg+ljO5eoPVgCcnFuRjJ9uH6I/3eg==} - engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + restore-cursor@4.0.0: dependencies: onetime: 5.1.2 signal-exit: 3.0.7 - /retry-request@7.0.2: - resolution: {integrity: sha512-dUOvLMJ0/JJYEn8NrpOaGNE7X3vpI5XlZS/u0ANjqtcZVKnIxP7IgCFwrKTxENw29emmwug53awKtaMm4i9g5w==} - engines: {node: '>=14'} + retry-request@7.0.2: dependencies: '@types/request': 2.48.12 extend: 3.0.2 @@ -19591,39 +22780,22 @@ packages: transitivePeerDependencies: - encoding - supports-color - dev: false - /retry@0.13.1: - resolution: {integrity: sha512-XQBQ3I8W1Cge0Seh+6gjj03LbmRFWuoszgK9ooCpwYIrhhoO80pfq4cUkU5DkknwfOfFteRwlZ56PYOGYyFWdg==} - engines: {node: '>= 4'} - dev: false + retry@0.13.1: {} - /reusify@1.0.4: - resolution: {integrity: sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==} - engines: {iojs: '>=1.0.0', node: '>=0.10.0'} - dev: true + reusify@1.0.4: {} - /rfdc@1.3.0: - resolution: {integrity: sha512-V2hovdzFbOi77/WajaSMXk2OLm+xNIeQdMMuB7icj7bk6zi2F8GGAxigcnDFpJHbNyNcgyJDiP+8nOrY5cZGrA==} + rfdc@1.3.0: {} - /rimraf@3.0.2: - resolution: {integrity: sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==} - hasBin: true + rimraf@3.0.2: dependencies: glob: 7.2.3 - dev: true - /rimraf@5.0.5: - resolution: {integrity: sha512-CqDakW+hMe/Bz202FPEymy68P+G50RfMQK+Qo5YUqc9SPipvbGjCGKd0RSKEelbsfQuw3g5NZDSrlZZAJurH1A==} - engines: {node: '>=14'} - hasBin: true + rimraf@5.0.5: dependencies: glob: 10.3.12 - dev: false - /roarr@7.11.0: - resolution: {integrity: sha512-DKiMaEYHoOZ0JyD4Ohr5KRnqybQ162s3ZL/WNO9oy6EUszYvpp0eLYJErc/U4NI96HYnHsbROhFaH4LYuJPnDg==} - engines: {node: '>=12.0'} + roarr@7.11.0: dependencies: boolean: 3.1.4 fast-json-stringify: 2.7.12 @@ -19632,48 +22804,27 @@ packages: globalthis: 1.0.2 semver-compare: 1.0.0 - /roarr@7.21.1: - resolution: {integrity: sha512-3niqt5bXFY1InKU8HKWqqYTYjtrBaxBMnXELXCXUYgtNYGUtZM5rB46HIC430AyacL95iEniGf7RgqsesykLmQ==} - engines: {node: '>=18.0'} + roarr@7.21.1: dependencies: fast-printf: 1.6.9 safe-stable-stringify: 2.4.3 semver-compare: 1.0.0 - /rollup-plugin-output-size@1.3.0(rollup@4.12.0): - resolution: {integrity: sha512-OrTfhj8mxFAO4Yp7OEWwI388uhsiBNDCpfD6tOmcqPfNs5+CWZPDtVmTRZrmXMWfv8skWCOm5ToO4UPy7eRqYg==} - engines: {node: '>=14.16.0'} - peerDependencies: - rollup: ^2.0.0 || ^3.0.0 || ^4.0.0 - peerDependenciesMeta: - rollup: - optional: true + rollup-plugin-output-size@1.3.0(rollup@4.12.0): dependencies: colorette: 2.0.20 gzip-size: 7.0.0 pretty-bytes: 6.1.1 rollup: 4.12.0 - dev: true - /rollup-plugin-output-size@1.3.0(rollup@4.14.3): - resolution: {integrity: sha512-OrTfhj8mxFAO4Yp7OEWwI388uhsiBNDCpfD6tOmcqPfNs5+CWZPDtVmTRZrmXMWfv8skWCOm5ToO4UPy7eRqYg==} - engines: {node: '>=14.16.0'} - peerDependencies: - rollup: ^2.0.0 || ^3.0.0 || ^4.0.0 - peerDependenciesMeta: - rollup: - optional: true + rollup-plugin-output-size@1.3.0(rollup@4.14.3): dependencies: colorette: 2.0.20 gzip-size: 7.0.0 pretty-bytes: 6.1.1 rollup: 4.14.3 - dev: true - /rollup@4.12.0: - resolution: {integrity: sha512-wz66wn4t1OHIJw3+XU7mJJQV/2NAfw5OAk6G6Hoo3zcvz/XOfQ52Vgi+AN4Uxoxi0KBBwk2g8zPrTDA4btSB/Q==} - engines: {node: '>=18.0.0', npm: '>=8.0.0'} - hasBin: true + rollup@4.12.0: dependencies: '@types/estree': 1.0.5 optionalDependencies: @@ -19691,12 +22842,8 @@ packages: '@rollup/rollup-win32-ia32-msvc': 4.12.0 '@rollup/rollup-win32-x64-msvc': 4.12.0 fsevents: 2.3.3 - dev: true - /rollup@4.14.3: - resolution: {integrity: sha512-ag5tTQKYsj1bhrFC9+OEWqb5O6VYgtQDO9hPDBMmIbePwhfSr+ExlcU741t8Dhw5DkPCQf6noz0jb36D6W9/hw==} - engines: {node: '>=18.0.0', npm: '>=8.0.0'} - hasBin: true + rollup@4.14.3: dependencies: '@types/estree': 1.0.5 optionalDependencies: @@ -19717,69 +22864,47 @@ packages: '@rollup/rollup-win32-ia32-msvc': 4.14.3 '@rollup/rollup-win32-x64-msvc': 4.14.3 fsevents: 2.3.3 - dev: true - /run-async@2.4.1: - resolution: {integrity: sha512-tvVnVv01b8c1RrA6Ep7JkStj85Guv/YrMcwqYQnwjsAS2cTmmPGBBjAjpCW7RrSodNSoE2/qg9O4bceNvUuDgQ==} - engines: {node: '>=0.12.0'} - dev: false + run-async@2.4.1: {} - /run-parallel@1.2.0: - resolution: {integrity: sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==} + run-parallel@1.2.0: dependencies: queue-microtask: 1.2.3 - dev: true - /rxjs@7.8.0: - resolution: {integrity: sha512-F2+gxDshqmIub1KdvZkaEfGDwLNpPvk9Fs6LD/MyQxNgMds/WH9OdDDXOmxUZpME+iSK3rQCctkL0DYyytUqMg==} + rxjs@7.8.0: dependencies: tslib: 2.5.0 - /rxjs@7.8.1: - resolution: {integrity: sha512-AA3TVj+0A2iuIoQkWEK/tqFjBq2j+6PO6Y0zJcvzLAFhEFIO3HL0vls9hWLncZbAAbK0mar7oZ4V079I/qPMxg==} + rxjs@7.8.1: dependencies: tslib: 2.6.2 - dev: true - /safe-array-concat@1.1.2: - resolution: {integrity: sha512-vj6RsCsWBCf19jIeHEfkRMw8DPiBb+DMXklQ/1SGDHOMlHdPUkZXFQ2YdplS23zESTijAcurb1aSgJA3AgMu1Q==} - engines: {node: '>=0.4'} + safe-array-concat@1.1.2: dependencies: call-bind: 1.0.7 get-intrinsic: 1.2.4 has-symbols: 1.0.3 isarray: 2.0.5 - dev: true - /safe-buffer@5.2.1: - resolution: {integrity: sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==} + safe-buffer@5.2.1: {} - /safe-regex-test@1.0.0: - resolution: {integrity: sha512-JBUUzyOgEwXQY1NuPtvcj/qcBDbDmEvWufhlnXZIm75DEHp+afM1r1ujJpJsV/gSM4t59tpDyPi1sd6ZaPFfsA==} + safe-regex-test@1.0.0: dependencies: call-bind: 1.0.7 get-intrinsic: 1.2.4 is-regex: 1.1.4 - dev: true - /safe-regex-test@1.0.3: - resolution: {integrity: sha512-CdASjNJPvRa7roO6Ra/gLYBTzYzzPyyBXxIMdGW3USQLyjWEls2RgW5UBTXaQVp+OrpeCK3bLem8smtmheoRuw==} - engines: {node: '>= 0.4'} + safe-regex-test@1.0.3: dependencies: call-bind: 1.0.7 es-errors: 1.3.0 is-regex: 1.1.4 - dev: true - /safe-stable-stringify@2.4.3: - resolution: {integrity: sha512-e2bDA2WJT0wxseVd4lsDP4+3ONX6HpMXQa1ZhFQ7SU+GjvORCmShbCMltrtIDfkYhVHrOcPtj+KhmDBdPdZD1g==} - engines: {node: '>=10'} + safe-stable-stringify@2.4.3: {} - /safer-buffer@2.1.2: - resolution: {integrity: sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==} + safer-buffer@2.1.2: {} - /samlify@2.8.11: - resolution: {integrity: sha512-EDO9CMba0rtHSek2NyUcS8brIxK1E521X5fT+1qLKTRkm1dddITeuPqU8/by4Lcf95ngMKjsn5Z600eVhXDqxQ==} + samlify@2.8.11: dependencies: '@authenio/xml-encryption': 2.0.2 '@xmldom/xmldom': 0.8.7 @@ -19792,73 +22917,44 @@ packages: xml-crypto: 3.0.1 xml-escape: 1.1.0 xpath: 0.0.32 - dev: false - /sass@1.56.1: - resolution: {integrity: sha512-VpEyKpyBPCxE7qGDtOcdJ6fFbcpOM+Emu7uZLxVrkX8KVU/Dp5UF7WLvzqRuUhB6mqqQt1xffLoG+AndxTZrCQ==} - engines: {node: '>=12.0.0'} - hasBin: true + sass@1.56.1: dependencies: chokidar: 3.5.3 immutable: 4.1.0 source-map-js: 1.0.2 - dev: true - /sax@1.2.4: - resolution: {integrity: sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw==} - dev: false + sax@1.2.4: {} - /saxes@6.0.0: - resolution: {integrity: sha512-xAg7SOnEhrm5zI3puOOKyy1OMcMlIJZYNJY7xLBwSze0UjhPLnWfj2GF2EpT0jmzaJKIWKHLsaSSajf35bcYnA==} - engines: {node: '>=v12.22.7'} + saxes@6.0.0: dependencies: xmlchars: 2.2.0 - dev: true - /scheduler@0.23.0: - resolution: {integrity: sha512-CtuThmgHNg7zIZWAXi3AsyIzA3n4xx7aNyjwC2VJldO2LMVDhFK+63xGqq6CsJH4rTAt6/M+N4GhZiDYPx9eUw==} + scheduler@0.23.0: dependencies: loose-envify: 1.4.0 - dev: true - /semver-compare@1.0.0: - resolution: {integrity: sha512-YM3/ITh2MJ5MtzaM429anh+x2jiLVjqILF4m4oyQB18W7Ggea7BfqdH/wGMK7dDiMghv/6WG7znWMwUDzJiXow==} + semver-compare@1.0.0: {} - /semver@5.7.2: - resolution: {integrity: sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==} - hasBin: true + semver@5.7.2: {} - /semver@6.3.1: - resolution: {integrity: sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==} - hasBin: true - dev: true + semver@6.3.1: {} - /semver@7.5.2: - resolution: {integrity: sha512-SoftuTROv/cRjCze/scjGyiDtcUyxw1rgYQSZY7XTmtR5hX+dm76iDbTH8TkLPHCQmlbQVSSbNZCPM2hb0knnQ==} - engines: {node: '>=10'} - hasBin: true + semver@7.5.2: dependencies: lru-cache: 6.0.0 - /semver@7.6.0: - resolution: {integrity: sha512-EnwXhrlwXMk9gKu5/flx5sv/an57AkRplG3hTK68W7FRDN+k+OWBj65M7719OkA82XLBxrcX0KSHj+X5COhOVg==} - engines: {node: '>=10'} - hasBin: true + semver@7.6.0: dependencies: lru-cache: 6.0.0 - /serialize-error@11.0.3: - resolution: {integrity: sha512-2G2y++21dhj2R7iHAdd0FIzjGwuKZld+7Pl/bTU6YIkrC2ZMbVUjm+luj6A6V34Rv9XfKJDKpTWu9W4Gse1D9g==} - engines: {node: '>=14.16'} + serialize-error@11.0.3: dependencies: type-fest: 2.19.0 - /set-blocking@2.0.0: - resolution: {integrity: sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw==} + set-blocking@2.0.0: {} - /set-function-length@1.2.2: - resolution: {integrity: sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==} - engines: {node: '>= 0.4'} + set-function-length@1.2.2: dependencies: define-data-property: 1.1.4 es-errors: 1.3.0 @@ -19867,87 +22963,55 @@ packages: gopd: 1.0.1 has-property-descriptors: 1.0.2 - /set-function-name@2.0.2: - resolution: {integrity: sha512-7PGFlmtwsEADb0WYyvCMa1t+yke6daIG4Wirafur5kcf+MhUnPms1UeR0CKQdTZD81yESwMHbtn+TR+dMviakQ==} - engines: {node: '>= 0.4'} + set-function-name@2.0.2: dependencies: define-data-property: 1.1.4 es-errors: 1.3.0 functions-have-names: 1.2.3 has-property-descriptors: 1.0.2 - dev: true - /setprototypeof@1.1.0: - resolution: {integrity: sha512-BvE/TwpZX4FXExxOxZyRGQQv651MSwmWKZGqvmPcRIjDqWub67kTKuIMx43cZZrS/cBBzwBcNDWoFxt2XEFIpQ==} - dev: false + setprototypeof@1.1.0: {} - /setprototypeof@1.2.0: - resolution: {integrity: sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==} + setprototypeof@1.2.0: {} - /shebang-command@1.2.0: - resolution: {integrity: sha512-EV3L1+UQWGor21OmnvojK36mhg+TyIKDh3iFBKBohr5xeXIhNBcx8oWdgkTEEQ+BEFFYdLRuqMfd5L84N1V5Vg==} - engines: {node: '>=0.10.0'} + shebang-command@1.2.0: dependencies: shebang-regex: 1.0.0 - dev: true - /shebang-command@2.0.0: - resolution: {integrity: sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==} - engines: {node: '>=8'} + shebang-command@2.0.0: dependencies: shebang-regex: 3.0.0 - /shebang-regex@1.0.0: - resolution: {integrity: sha512-wpoSFAxys6b2a2wHZ1XpDSgD7N9iVjg29Ph9uV/uaP9Ex/KXlkTZTeddxDPSYQpgvzKLGJke2UU0AzoGCjNIvQ==} - engines: {node: '>=0.10.0'} - dev: true + shebang-regex@1.0.0: {} - /shebang-regex@3.0.0: - resolution: {integrity: sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==} - engines: {node: '>=8'} + shebang-regex@3.0.0: {} - /shell-quote@1.7.3: - resolution: {integrity: sha512-Vpfqwm4EnqGdlsBFNmHhxhElJYrdfcxPThu+ryKS5J8L/fhAwLazFZtq+S+TWZ9ANj2piSQLGj6NQg+lKPmxrw==} - dev: true + shell-quote@1.7.3: {} - /shimmer@1.2.1: - resolution: {integrity: sha512-sQTKC1Re/rM6XyFM6fIAGHRPVGvyXfgzIDvzoq608vM+jeyVD0Tu1E6Np0Kc2zAIFWIj963V2800iF/9LPieQw==} - dev: false + shimmer@1.2.1: {} - /side-channel@1.0.6: - resolution: {integrity: sha512-fDW/EZ6Q9RiO8eFG8Hj+7u/oW+XrPTIChwCOM2+th2A6OblDtYYIpve9m+KvI9Z4C9qSEXlaGR6bTEYHReuglA==} - engines: {node: '>= 0.4'} + side-channel@1.0.6: dependencies: call-bind: 1.0.7 es-errors: 1.3.0 get-intrinsic: 1.2.4 object-inspect: 1.13.1 - /siginfo@2.0.0: - resolution: {integrity: sha512-ybx0WO1/8bSBLEWXZvEd7gMW3Sn3JFlW3TvX1nREbDLRNQNaeNN8WK0meBwPdAaOI7TtRRRJn/Es1zhrrCHu7g==} - dev: true + siginfo@2.0.0: {} - /signal-exit@3.0.7: - resolution: {integrity: sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==} + signal-exit@3.0.7: {} - /signal-exit@4.1.0: - resolution: {integrity: sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==} - engines: {node: '>=14'} + signal-exit@4.1.0: {} - /simple-swizzle@0.2.2: - resolution: {integrity: sha512-JA//kQgZtbuY83m+xT+tXJkmJncGMTFT+C+g2h2R9uxkYIrE2yy9sgmcLhCnw57/WSD+Eh3J97FPEDFnbXnDUg==} + simple-swizzle@0.2.2: dependencies: is-arrayish: 0.3.2 - /simple-update-notifier@2.0.0: - resolution: {integrity: sha512-a2B9Y0KlNXl9u/vsW6sTIu9vGEpfKu2wRV6l1H3XEas/0gUIzGzBoP/IouTcUQbm9JWZLH3COxyn03TYlFax6w==} - engines: {node: '>=10'} + simple-update-notifier@2.0.0: dependencies: semver: 7.6.0 - dev: true - /sinon@17.0.0: - resolution: {integrity: sha512-p4lJiYKBoOEVUxxVIC9H1MM2znG1/c8gud++I2BauJA5hsz7hHsst35eurNWXTusBsIq66FzOQbZ/uMdpvbPIQ==} + sinon@17.0.0: dependencies: '@sinonjs/commons': 3.0.0 '@sinonjs/fake-timers': 11.2.2 @@ -19955,43 +23019,25 @@ packages: diff: 5.1.0 nise: 5.1.5 supports-color: 7.2.0 - dev: true - /sisteransi@1.0.5: - resolution: {integrity: sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg==} - dev: true + sisteransi@1.0.5: {} - /slash@3.0.0: - resolution: {integrity: sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==} - engines: {node: '>=8'} - dev: true + slash@3.0.0: {} - /slice-ansi@4.0.0: - resolution: {integrity: sha512-qMCMfhY040cVHT43K9BFygqYbUPFZKHOg7K73mtTWJRb8pyP3fzf4Ixd5SzdEJQ6MRUg/WBnOLxghZtKKurENQ==} - engines: {node: '>=10'} + slice-ansi@4.0.0: dependencies: ansi-styles: 4.3.0 astral-regex: 2.0.0 is-fullwidth-code-point: 3.0.0 - dev: true - /slice-ansi@5.0.0: - resolution: {integrity: sha512-FC+lgizVPfie0kkhqUScwRu1O/lF6NOgJmlCgK+/LYxDCTk8sGelYaHDhFcDN+Sn3Cv+3VSa4Byeo+IMCzpMgQ==} - engines: {node: '>=12'} + slice-ansi@5.0.0: dependencies: ansi-styles: 6.2.1 is-fullwidth-code-point: 4.0.0 - dev: true - /smart-buffer@4.2.0: - resolution: {integrity: sha512-94hK0Hh8rPqQl2xXc3HsaBoOXKV20MToPkcXvwbISWLEs+64sBq5kFgn2kJDHb1Pry9yrP0dxrCI9RRci7RXKg==} - engines: {node: '>= 6.0.0', npm: '>= 3.0.0'} - dev: true + smart-buffer@4.2.0: {} - /smartwrap@2.0.2: - resolution: {integrity: sha512-vCsKNQxb7PnCNd2wY1WClWifAc2lwqsG8OaswpJkVJsvMGcnEntdTCDajZCkk93Ay1U3t/9puJmb525Rg5MZBA==} - engines: {node: '>=6'} - hasBin: true + smartwrap@2.0.2: dependencies: array.prototype.flat: 1.3.1 breakword: 1.0.5 @@ -19999,274 +23045,161 @@ packages: strip-ansi: 6.0.1 wcwidth: 1.0.1 yargs: 15.4.1 - dev: true - /snake-case@3.0.4: - resolution: {integrity: sha512-LAOh4z89bGQvl9pFfNF8V146i7o7/CqFPbqzYgP+yYzDIDeS9HaNFtXABamRW+AQzEVODcvE79ljJ+8a9YSdMg==} + snake-case@3.0.4: dependencies: dot-case: 3.0.4 tslib: 2.6.2 - dev: false - /snake-case@4.0.0: - resolution: {integrity: sha512-slvG6efKZ3GYUUZdhPOq/lLIqutwQ4TdPViD1VKqsbf0u76U/aPRswPKjOaAS9T7fAPmRmXuN6C/nM0xsMaFLQ==} - deprecated: Use `change-case` + snake-case@4.0.0: dependencies: no-case: 4.0.0 - dev: false - /snakecase-keys@8.0.0: - resolution: {integrity: sha512-qS7XvESuFxskrmD8/O9tOMdLdV9YTuPfNLdRJIvNJKNEZtH9XVPwmZioROwl4TsVDbOFqlQ/o7pURuF8MnjYsg==} - engines: {node: '>=18'} + snakecase-keys@8.0.0: dependencies: map-obj: 4.3.0 snake-case: 3.0.4 type-fest: 4.15.0 - dev: false - /socks-proxy-agent@8.0.2: - resolution: {integrity: sha512-8zuqoLv1aP/66PHF5TqwJ7Czm3Yv32urJQHrVyhD7mmA6d61Zv8cIXQYPTWwmg6qlupnPvs/QKDmfa4P/qct2g==} - engines: {node: '>= 14'} + socks-proxy-agent@8.0.2: dependencies: agent-base: 7.1.0 debug: 4.3.4 socks: 2.7.1 transitivePeerDependencies: - supports-color - dev: true - /socks@2.7.1: - resolution: {integrity: sha512-7maUZy1N7uo6+WVEX6psASxtNlKaNVMlGQKkG/63nEDdLOWNbiUMoLK7X4uYoLhQstau72mLgfEWcXcwsaHbYQ==} - engines: {node: '>= 10.13.0', npm: '>= 3.0.0'} + socks@2.7.1: dependencies: ip: 2.0.1 smart-buffer: 4.2.0 - dev: true - /source-map-js@1.0.2: - resolution: {integrity: sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw==} - engines: {node: '>=0.10.0'} - dev: true + source-map-js@1.0.2: {} - /source-map-js@1.2.0: - resolution: {integrity: sha512-itJW8lvSA0TXEphiRoawsCksnlf8SyvmFzIhltqAHluXd88pkCd+cXJVHTDwdCr0IzwptSm035IHQktUu1QUMg==} - engines: {node: '>=0.10.0'} - dev: true + source-map-js@1.2.0: {} - /source-map-support@0.5.13: - resolution: {integrity: sha512-SHSKFHadjVA5oR4PPqhtAVdcBWwRYVd6g6cAXnIbRiIwc2EhPrTuKUBdSLvlEKyIP3GCf89fltvcZiP9MMFA1w==} + source-map-support@0.5.13: dependencies: buffer-from: 1.1.2 source-map: 0.6.1 - dev: true - /source-map@0.5.7: - resolution: {integrity: sha512-LbrmJOMUSdEVxIKvdcJzQC+nQhe8FUZQTXQy6+I75skNgn3OoQ0DZA8YnFa7gp8tqtL3KPf1kmo0R5DoApeSGQ==} - engines: {node: '>=0.10.0'} - dev: true + source-map@0.5.7: {} - /source-map@0.6.1: - resolution: {integrity: sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==} - engines: {node: '>=0.10.0'} - dev: true + source-map@0.6.1: {} - /source-map@0.8.0-beta.0: - resolution: {integrity: sha512-2ymg6oRBpebeZi9UUNsgQ89bhx01TcTkmNTGnNO88imTmbSgy4nfujrgVEFKWpMTEGA11EDkTt7mqObTPdigIA==} - engines: {node: '>= 8'} + source-map@0.8.0-beta.0: dependencies: whatwg-url: 7.1.0 - /space-separated-tokens@1.1.5: - resolution: {integrity: sha512-q/JSVd1Lptzhf5bkYm4ob4iWPjx0KiRe3sRFBNrVqbJkFaBm5vbbowy1mymoPNLRa52+oadOhJ+K49wsSeSjTA==} - dev: true + space-separated-tokens@1.1.5: {} - /space-separated-tokens@2.0.1: - resolution: {integrity: sha512-ekwEbFp5aqSPKaqeY1PGrlGQxPNaq+Cnx4+bE2D8sciBQrHpbwoBbawqTN2+6jPs9IdWxxiUcN0K2pkczD3zmw==} - dev: true + space-separated-tokens@2.0.1: {} - /spawnd@10.0.0: - resolution: {integrity: sha512-6GKcakMTryb5b1SWCvdubCDHEsR2k+5VZUD5G19umZRarkvj1RyCGyizcqhjewI7cqZo8fTVD8HpnDZbVOLMtg==} - engines: {node: '>=16'} + spawnd@10.0.0: dependencies: signal-exit: 4.1.0 tree-kill: 1.2.2 - dev: true - /spawndamnit@2.0.0: - resolution: {integrity: sha512-j4JKEcncSjFlqIwU5L/rp2N5SIPsdxaRsIv678+TZxZ0SRDJTm8JrxJMjE/XuiEZNEir3S8l0Fa3Ke339WI4qA==} + spawndamnit@2.0.0: dependencies: cross-spawn: 5.1.0 signal-exit: 3.0.7 - dev: true - /spdx-correct@3.2.0: - resolution: {integrity: sha512-kN9dJbvnySHULIluDHy32WHRUu3Og7B9sbY7tsFLctQkIqnMh3hErYgdMjTYuqmcXX+lK5T1lnUt3G7zNswmZA==} + spdx-correct@3.2.0: dependencies: spdx-expression-parse: 3.0.1 spdx-license-ids: 3.0.13 - dev: true - /spdx-exceptions@2.3.0: - resolution: {integrity: sha512-/tTrYOC7PPI1nUAgx34hUpqXuyJG+DTHJTnIULG4rDygi4xu/tfgmq1e1cIRwRzwZgo4NLySi+ricLkZkw4i5A==} - dev: true + spdx-exceptions@2.3.0: {} - /spdx-expression-parse@3.0.1: - resolution: {integrity: sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q==} + spdx-expression-parse@3.0.1: dependencies: spdx-exceptions: 2.3.0 spdx-license-ids: 3.0.13 - dev: true - /spdx-license-ids@3.0.13: - resolution: {integrity: sha512-XkD+zwiqXHikFZm4AX/7JSCXA98U5Db4AFd5XUg/+9UNtnH75+Z9KxtpYiJZx36mUDVOwH83pl7yvCer6ewM3w==} - dev: true + spdx-license-ids@3.0.13: {} - /split-on-first@3.0.0: - resolution: {integrity: sha512-qxQJTx2ryR0Dw0ITYyekNQWpz6f8dGd7vffGNflQQ3Iqj9NJ6qiZ7ELpZsJ/QBhIVAiDfXdag3+Gp8RvWa62AA==} - engines: {node: '>=12'} - dev: false + split-on-first@3.0.0: {} - /split2@3.2.2: - resolution: {integrity: sha512-9NThjpgZnifTkJpzTZ7Eue85S49QwpNhZTq6GRJwObb6jnLFNGB7Qm73V5HewTROPyxD0C29xqmaI68bQtV+hg==} + split2@3.2.2: dependencies: readable-stream: 3.6.2 - /split2@4.2.0: - resolution: {integrity: sha512-UcjcJOWknrNkF6PLX83qcHM6KHgVKNkV62Y8a5uYDVv9ydGQVwAHMKqHdJje1VTWpljG0WYpCDhrCdAOYH4TWg==} - engines: {node: '>= 10.x'} - dev: true + split2@4.2.0: {} - /sprintf-js@1.0.3: - resolution: {integrity: sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==} - dev: true + sprintf-js@1.0.3: {} - /sql-parse@0.1.5: - resolution: {integrity: sha512-e2ExBX6iDHoCDC1zN2NvZV49UMhKVLvvwrDjzSVHFS3TKHKtIpl2nMDQkdlbTjDVvf2bxRYBq9iXAAMZvZpGVA==} - engines: {node: '>=0.10'} - dev: true + sql-parse@0.1.5: {} - /srcset@4.0.0: - resolution: {integrity: sha512-wvLeHgcVHKO8Sc/H/5lkGreJQVeYMm9rlmt8PuR1xE31rIuXhuzznUUqAt8MqLhB3MqJdFzlNAfpcWnxiFUcPw==} - engines: {node: '>=12'} - dev: true + srcset@4.0.0: {} - /stable@0.1.8: - resolution: {integrity: sha512-ji9qxRnOVfcuLDySj9qzhGSEFVobyt1kIOSkj1qZzYLzq7Tos/oUUWvotUPQLlrsidqsK6tBH89Bc9kL5zHA6w==} - deprecated: 'Modern JS already guarantees Array#sort() is a stable sort, so this library is deprecated. See the compatibility table on MDN: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/sort#browser_compatibility' - dev: true + stable@0.1.8: {} - /stack-chain@1.3.7: - resolution: {integrity: sha512-D8cWtWVdIe/jBA7v5p5Hwl5yOSOrmZPWDPe2KxQ5UAGD+nxbxU0lKXA4h85Ta6+qgdKVL3vUxsbIZjc1kBG7ug==} - dev: false + stack-chain@1.3.7: {} - /stack-utils@2.0.5: - resolution: {integrity: sha512-xrQcmYhOsn/1kX+Vraq+7j4oE2j/6BFscZ0etmYg81xuM8Gq0022Pxb8+IqgOFUIaxHs0KaSb7T1+OegiNrNFA==} - engines: {node: '>=10'} + stack-utils@2.0.5: dependencies: escape-string-regexp: 2.0.0 - dev: true - /stackback@0.0.2: - resolution: {integrity: sha512-1XMJE5fQo1jGH6Y/7ebnwPOBEkIEnT4QF32d5R1+VXdXveM0IBMJt8zfaxX1P3QhVwrYe+576+jkANtSS2mBbw==} - dev: true + stackback@0.0.2: {} - /state-local@1.0.7: - resolution: {integrity: sha512-HTEHMNieakEnoe33shBYcZ7NX83ACUjCu8c40iOGEZsngj9zRnkqS9j1pqQPXwobB0ZcVTk27REb7COQ0UR59w==} - dev: true + state-local@1.0.7: {} - /state-toggle@1.0.3: - resolution: {integrity: sha512-d/5Z4/2iiCnHw6Xzghyhb+GcmF89bxwgXG60wjIiZaxnymbyOmI8Hk4VqHXiVVp6u2ysaskFfXg3ekCj4WNftQ==} - dev: true + state-toggle@1.0.3: {} - /statuses@1.5.0: - resolution: {integrity: sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow=} - engines: {node: '>= 0.6'} + statuses@1.5.0: {} - /statuses@2.0.1: - resolution: {integrity: sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==} - engines: {node: '>= 0.8'} - dev: false + statuses@2.0.1: {} - /std-env@3.7.0: - resolution: {integrity: sha512-JPbdCEQLj1w5GilpiHAx3qJvFndqybBysA3qUOnznweH4QbNYUsW/ea8QzSrnh0vNsezMMw5bcVool8lM0gwzg==} - dev: true + std-env@3.7.0: {} - /stdin-discarder@0.2.2: - resolution: {integrity: sha512-UhDfHmA92YAlNnCfhmq0VeNL5bDbiZGg7sZ2IvPsXubGkiNa9EC+tUTsjBRsYUAz87btI6/1wf4XoVvQ3uRnmQ==} - engines: {node: '>=18'} - dev: false + stdin-discarder@0.2.2: {} - /stream-events@1.0.5: - resolution: {integrity: sha512-E1GUzBSgvct8Jsb3v2X15pjzN1tYebtbLaMg+eBOUOAxgbLoSbT2NS91ckc5lJD1KfLjId+jXJRgo0qnV5Nerg==} + stream-events@1.0.5: dependencies: stubs: 3.0.0 - dev: false - /stream-shift@1.0.3: - resolution: {integrity: sha512-76ORR0DO1o1hlKwTbi/DM3EXWGf3ZJYO8cXX5RJwnul2DEg2oyoZyjLNoQM8WsvZiFKCRfC1O0J7iCvie3RZmQ==} - dev: false + stream-shift@1.0.3: {} - /stream-transform@2.1.3: - resolution: {integrity: sha512-9GHUiM5hMiCi6Y03jD2ARC1ettBXkQBoQAe7nJsPknnI0ow10aXjTnew8QtYQmLjzn974BnmWEAJgCY6ZP1DeQ==} + stream-transform@2.1.3: dependencies: mixme: 0.5.4 - dev: true - /streamx@2.15.1: - resolution: {integrity: sha512-fQMzy2O/Q47rgwErk/eGeLu/roaFWV0jVsogDmrszM9uIw8L5OA+t+V93MgYlufNptfjmYR1tOMWhei/Eh7TQA==} + streamx@2.15.1: dependencies: fast-fifo: 1.3.2 queue-tick: 1.0.1 - dev: true - /string-argv@0.3.2: - resolution: {integrity: sha512-aqD2Q0144Z+/RqG52NeHEkZauTAUWJO8c6yTftGJKO3Tja5tUgIfmIl6kExvhtxSDP7fXB6DvzkfMpCd/F3G+Q==} - engines: {node: '>=0.6.19'} - dev: true + string-argv@0.3.2: {} - /string-hash@1.1.3: - resolution: {integrity: sha1-6Kr8CsGFW0Zmkp7X3RJ1311sgRs=} - dev: true + string-hash@1.1.3: {} - /string-length@4.0.2: - resolution: {integrity: sha512-+l6rNN5fYHNhZZy41RXsYptCjA2Igmq4EG7kZAYFQI1E1VTXarr6ZPXBg6eq7Y6eK4FEhY6AJlyuFIb/v/S0VQ==} - engines: {node: '>=10'} + string-length@4.0.2: dependencies: char-regex: 1.0.2 strip-ansi: 6.0.1 - dev: true - /string-similarity@4.0.4: - resolution: {integrity: sha512-/q/8Q4Bl4ZKAPjj8WerIBJWALKkaPRfrvhfF8k/B23i4nzrlRj2/go1m90In7nG/3XDSbOo0+pu6RvCTM9RGMQ==} + string-similarity@4.0.4: {} - /string-width@4.2.3: - resolution: {integrity: sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==} - engines: {node: '>=8'} + string-width@4.2.3: dependencies: emoji-regex: 8.0.0 is-fullwidth-code-point: 3.0.0 strip-ansi: 6.0.1 - /string-width@5.1.2: - resolution: {integrity: sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==} - engines: {node: '>=12'} + string-width@5.1.2: dependencies: eastasianwidth: 0.2.0 emoji-regex: 9.2.2 strip-ansi: 7.1.0 - /string-width@7.0.0: - resolution: {integrity: sha512-GPQHj7row82Hjo9hKZieKcHIhaAIKOJvFSIZXuCU9OASVZrMNUaZuz++SPVrBjnLsnk4k+z9f2EIypgxf2vNFw==} - engines: {node: '>=18'} + string-width@7.0.0: dependencies: emoji-regex: 10.3.0 get-east-asian-width: 1.2.0 strip-ansi: 7.1.0 - dev: false - /string.prototype.matchall@4.0.11: - resolution: {integrity: sha512-NUdh0aDavY2og7IbBPenWqR9exH+E26Sv8e0/eTe1tltDGZL+GtBkDAnnyBtmekfK6/Dq3MkcGtzXFEd1LQrtg==} - engines: {node: '>= 0.4'} + string.prototype.matchall@4.0.11: dependencies: call-bind: 1.0.7 define-properties: 1.2.1 @@ -20280,179 +23213,107 @@ packages: regexp.prototype.flags: 1.5.2 set-function-name: 2.0.2 side-channel: 1.0.6 - dev: true - /string.prototype.trim@1.2.9: - resolution: {integrity: sha512-klHuCNxiMZ8MlsOihJhJEBJAiMVqU3Z2nEXWfWnIqjN0gEFS9J9+IxKozWWtQGcgoa1WUZzLjKPTr4ZHNFTFxw==} - engines: {node: '>= 0.4'} + string.prototype.trim@1.2.9: dependencies: call-bind: 1.0.7 define-properties: 1.2.1 es-abstract: 1.23.3 es-object-atoms: 1.0.0 - dev: true - /string.prototype.trimend@1.0.5: - resolution: {integrity: sha512-I7RGvmjV4pJ7O3kdf+LXFpVfdNOxtCW/2C8f6jNiW4+PQchwxkCDzlk1/7p+Wl4bqFIZeF47qAHXLuHHWKAxog==} + string.prototype.trimend@1.0.5: dependencies: call-bind: 1.0.7 define-properties: 1.1.4 es-abstract: 1.20.4 - dev: true - /string.prototype.trimend@1.0.8: - resolution: {integrity: sha512-p73uL5VCHCO2BZZ6krwwQE3kCzM7NKmis8S//xEC6fQonchbum4eP6kR4DLEjQFO3Wnj3Fuo8NM0kOSjVdHjZQ==} + string.prototype.trimend@1.0.8: dependencies: call-bind: 1.0.7 define-properties: 1.2.1 es-object-atoms: 1.0.0 - dev: true - /string.prototype.trimstart@1.0.5: - resolution: {integrity: sha512-THx16TJCGlsN0o6dl2o6ncWUsdgnLRSA23rRE5pyGBw/mLr3Ej/R2LaqCtgP8VNMGZsvMWnf9ooZPyY2bHvUFg==} + string.prototype.trimstart@1.0.5: dependencies: call-bind: 1.0.7 define-properties: 1.1.4 es-abstract: 1.20.4 - dev: true - /string.prototype.trimstart@1.0.8: - resolution: {integrity: sha512-UXSH262CSZY1tfu3G3Secr6uGLCFVPMhIqHjlgCUtCCcgihYc/xKs9djMTMUOb2j1mVSeU8EU6NWc/iQKU6Gfg==} - engines: {node: '>= 0.4'} + string.prototype.trimstart@1.0.8: dependencies: call-bind: 1.0.7 define-properties: 1.2.1 es-object-atoms: 1.0.0 - dev: true - /string_decoder@1.3.0: - resolution: {integrity: sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==} + string_decoder@1.3.0: dependencies: safe-buffer: 5.2.1 - /strip-ansi@6.0.1: - resolution: {integrity: sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==} - engines: {node: '>=8'} + strip-ansi@6.0.1: dependencies: ansi-regex: 5.0.1 - /strip-ansi@7.0.1: - resolution: {integrity: sha512-cXNxvT8dFNRVfhVME3JAe98mkXDYN2O1l7jmcwMnOslDeESg1rF/OZMtK0nRAhiari1unG5cD4jG3rapUAkLbw==} - engines: {node: '>=12'} + strip-ansi@7.0.1: dependencies: ansi-regex: 6.0.1 - dev: false - /strip-ansi@7.1.0: - resolution: {integrity: sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==} - engines: {node: '>=12'} + strip-ansi@7.1.0: dependencies: ansi-regex: 6.0.1 - /strip-bom@3.0.0: - resolution: {integrity: sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==} - engines: {node: '>=4'} - dev: true + strip-bom@3.0.0: {} - /strip-bom@4.0.0: - resolution: {integrity: sha512-3xurFv5tEgii33Zi8Jtp55wEIILR9eh34FAW00PZf+JnSsTmV/ioewSgQl97JHvgjoRGwPShsWm+IdrxB35d0w==} - engines: {node: '>=8'} - dev: true + strip-bom@4.0.0: {} - /strip-final-newline@2.0.0: - resolution: {integrity: sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==} - engines: {node: '>=6'} - dev: true + strip-final-newline@2.0.0: {} - /strip-final-newline@3.0.0: - resolution: {integrity: sha512-dOESqjYr96iWYylGObzd39EuNTa5VJxyvVAEm5Jnh7KGo75V43Hk1odPQkNDyXNmUR6k+gEiDVXnjB8HJ3crXw==} - engines: {node: '>=12'} - dev: true + strip-final-newline@3.0.0: {} - /strip-indent@3.0.0: - resolution: {integrity: sha512-laJTa3Jb+VQpaC6DseHhF7dXVqHTfJPCRDaEbid/drOhgitgYku/letMUqOXFoWV0zIIUbjpdH2t+tYj4bQMRQ==} - engines: {node: '>=8'} + strip-indent@3.0.0: dependencies: min-indent: 1.0.1 - dev: true - /strip-indent@4.0.0: - resolution: {integrity: sha512-mnVSV2l+Zv6BLpSD/8V87CW/y9EmmbYzGCIavsnsI6/nwn26DwffM/yztm30Z/I2DY9wdS3vXVCMnHDgZaVNoA==} - engines: {node: '>=12'} + strip-indent@4.0.0: dependencies: min-indent: 1.0.1 - dev: true - /strip-json-comments@3.1.1: - resolution: {integrity: sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==} - engines: {node: '>=8'} - dev: true + strip-json-comments@3.1.1: {} - /strip-literal@2.0.0: - resolution: {integrity: sha512-f9vHgsCWBq2ugHAkGMiiYY+AYG0D/cbloKKg0nhaaaSNsujdGIpVXCNsrJpCKr5M0f4aI31mr13UjY6GAuXCKA==} + strip-literal@2.0.0: dependencies: js-tokens: 8.0.3 - dev: true - /strnum@1.0.5: - resolution: {integrity: sha512-J8bbNyKKXl5qYcR36TIO8W3mVGVHrmmxsd5PAItGkmyzwJvybiw2IVq5nqd0i4LSNSkB/sx9VHllbfFdr9k1JA==} - dev: false + strnum@1.0.5: {} - /stubs@3.0.0: - resolution: {integrity: sha512-PdHt7hHUJKxvTCgbKX9C1V/ftOcjJQgz8BZwNfV5c4B6dcGqlpelTbJ999jBGZ2jYiPAwcX5dP6oBwVlBlUbxw==} - dev: false + stubs@3.0.0: {} - /style-search@0.1.0: - resolution: {integrity: sha512-Dj1Okke1C3uKKwQcetra4jSuk0DqbzbYtXipzFlFMZtowbF1x7BKJwB9AayVMyFARvU8EDrZdcax4At/452cAg==} - dev: true + style-search@0.1.0: {} - /style-to-object@0.3.0: - resolution: {integrity: sha512-CzFnRRXhzWIdItT3OmF8SQfWyahHhjq3HwcMNCNLn+N7klOOqPjMeG/4JSu77D7ypZdGvSzvkrbyeTMizz2VrA==} + style-to-object@0.3.0: dependencies: inline-style-parser: 0.1.1 - dev: true - /style-to-object@0.4.2: - resolution: {integrity: sha512-1JGpfPB3lo42ZX8cuPrheZbfQ6kqPPnPHlKMyeRYtfKD+0jG+QsXgXN57O/dvJlzlB2elI6dGmrPnl5VPQFPaA==} + style-to-object@0.4.2: dependencies: inline-style-parser: 0.1.1 - dev: true - /stylelint-config-xo@0.22.0(stylelint@15.11.0): - resolution: {integrity: sha512-E4IoDwgJqG+Q3LjeZGXNi3uOXOH5Sx6mCyxp1V4eaAm1DhuA+3X40c2GtobEIHfCv6itN/T3QKRb4V4/snIxUg==} - engines: {node: '>=16'} - peerDependencies: - stylelint: '>=14 || ^16.0.0' + stylelint-config-xo@0.22.0(stylelint@15.11.0): dependencies: stylelint: 15.11.0(typescript@5.3.3) stylelint-declaration-block-no-ignored-properties: 2.8.0(stylelint@15.11.0) stylelint-order: 6.0.4(stylelint@15.11.0) - dev: true - /stylelint-declaration-block-no-ignored-properties@2.8.0(stylelint@15.11.0): - resolution: {integrity: sha512-Ws8Cav7Y+SPN0JsV407LrnNXWOrqGjxShf+37GBtnU/C58Syve9c0+I/xpLcFOosST3ternykn3Lp77f3ITnFw==} - engines: {node: '>=6'} - peerDependencies: - stylelint: ^7.0.0 || ^8.0.0 || ^9.0.0 || ^10.0.0 || ^11.0.0 || ^12.0.0 || ^13.0.0 || ^14.0.0 || ^15.0.0 || ^16.0.0 + stylelint-declaration-block-no-ignored-properties@2.8.0(stylelint@15.11.0): dependencies: stylelint: 15.11.0(typescript@5.3.3) - dev: true - /stylelint-order@6.0.4(stylelint@15.11.0): - resolution: {integrity: sha512-0UuKo4+s1hgQ/uAxlYU4h0o0HS4NiQDud0NAUNI0aa8FJdmYHA5ZZTFHiV5FpmE3071e9pZx5j0QpVJW5zOCUA==} - peerDependencies: - stylelint: ^14.0.0 || ^15.0.0 || ^16.0.1 || ^16.0.0 + stylelint-order@6.0.4(stylelint@15.11.0): dependencies: postcss: 8.4.38 postcss-sorting: 8.0.2(postcss@8.4.38) stylelint: 15.11.0(typescript@5.3.3) - dev: true - /stylelint-scss@6.2.1(stylelint@15.11.0): - resolution: {integrity: sha512-ZoGLbVb1keZYRVGQlhB8G6sZOoNqw61whzzzGFWp05N12ErqLFfBv3JPrXiMLZaW98sBS7K/vUQhRnvUj4vwdw==} - engines: {node: '>=18.12.0'} - peerDependencies: - stylelint: ^16.0.2 || ^16.0.0 + stylelint-scss@6.2.1(stylelint@15.11.0): dependencies: known-css-properties: 0.29.0 postcss-media-query-parser: 0.2.3 @@ -20460,12 +23321,8 @@ packages: postcss-selector-parser: 6.0.16 postcss-value-parser: 4.2.0 stylelint: 15.11.0(typescript@5.3.3) - dev: true - /stylelint@15.11.0(typescript@5.3.3): - resolution: {integrity: sha512-78O4c6IswZ9TzpcIiQJIN49K3qNoXTM8zEJzhaTE/xRTCZswaovSEVIa/uwbOltZrk16X4jAxjaOhzz/hTm1Kw==} - engines: {node: ^14.13.1 || >=16.0.0} - hasBin: true + stylelint@15.11.0(typescript@5.3.3): dependencies: '@csstools/css-parser-algorithms': 2.6.1(@csstools/css-tokenizer@2.2.4) '@csstools/css-tokenizer': 2.2.4 @@ -20510,11 +23367,8 @@ packages: transitivePeerDependencies: - supports-color - typescript - dev: true - /superagent@9.0.1: - resolution: {integrity: sha512-CcRSdb/P2oUVaEpQ87w9Obsl+E9FruRd6b2b7LdiBtJoyMr2DQt7a89anAfiX/EL59j9b2CbRFvf2S91DhuCww==} - engines: {node: '>=14.18.0'} + superagent@9.0.1: dependencies: component-emitter: 1.3.0 cookiejar: 2.1.4 @@ -20528,67 +23382,40 @@ packages: semver: 7.6.0 transitivePeerDependencies: - supports-color - dev: true - /superstruct@1.0.3: - resolution: {integrity: sha512-8iTn3oSS8nRGn+C2pgXSKPI3jmpm6FExNazNpjvqS6ZUJQCej3PUXEKM8NjHBOs54ExM+LPW/FBRhymrdcCiSg==} - engines: {node: '>=14.0.0'} - dev: true + superstruct@1.0.3: {} - /supertest@7.0.0: - resolution: {integrity: sha512-qlsr7fIC0lSddmA3tzojvzubYxvlGtzumcdHgPwbFWMISQwL22MhM2Y3LNt+6w9Yyx7559VW5ab70dgphm8qQA==} - engines: {node: '>=14.18.0'} + supertest@7.0.0: dependencies: methods: 1.1.2 superagent: 9.0.1 transitivePeerDependencies: - supports-color - dev: true - /supports-color@5.5.0: - resolution: {integrity: sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==} - engines: {node: '>=4'} + supports-color@5.5.0: dependencies: has-flag: 3.0.0 - /supports-color@7.2.0: - resolution: {integrity: sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==} - engines: {node: '>=8'} + supports-color@7.2.0: dependencies: has-flag: 4.0.0 - dev: true - /supports-color@8.1.1: - resolution: {integrity: sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==} - engines: {node: '>=10'} + supports-color@8.1.1: dependencies: has-flag: 4.0.0 - dev: true - /supports-hyperlinks@3.0.0: - resolution: {integrity: sha512-QBDPHyPQDRTy9ku4URNGY5Lah8PAaXs6tAAwp55sL5WCsSW7GIfdf6W5ixfziW+t7wh3GVvHyHHyQ1ESsoRvaA==} - engines: {node: '>=14.18'} + supports-hyperlinks@3.0.0: dependencies: has-flag: 4.0.0 supports-color: 7.2.0 - dev: true - /supports-preserve-symlinks-flag@1.0.0: - resolution: {integrity: sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==} - engines: {node: '>= 0.4'} + supports-preserve-symlinks-flag@1.0.0: {} - /svg-parser@2.0.4: - resolution: {integrity: sha512-e4hG1hRwoOdRb37cIMSgzNsxyzKfayW6VOflrwvR+/bzrkyxY/31WkbgnQpgtrNp1SdpJvpUAGTa/ZoiPNDuRQ==} - dev: true + svg-parser@2.0.4: {} - /svg-tags@1.0.0: - resolution: {integrity: sha512-ovssysQTa+luh7A5Weu3Rta6FJlFBBbInjOh722LIt6klpU2/HtdUbszju/G4devcvk8PGt7FCLv5wftu3THUA==} - dev: true + svg-tags@1.0.0: {} - /svgo@2.8.0: - resolution: {integrity: sha512-+N/Q9kV1+F+UeWYoSiULYo4xYSDQlTgb+ayMobAXPwMnLvop7oxKMo9OzIrX5x3eS4L4f2UHhc9axXwY8DpChg==} - engines: {node: '>=10.13.0'} - hasBin: true + svgo@2.8.0: dependencies: '@trysound/sax': 0.2.0 commander: 7.2.0 @@ -20597,66 +23424,44 @@ packages: csso: 4.2.0 picocolors: 1.0.0 stable: 0.1.8 - dev: true - /swr@2.2.0(react@18.2.0): - resolution: {integrity: sha512-AjqHOv2lAhkuUdIiBu9xbuettzAzWXmCEcLONNKJRba87WAefz8Ca9d6ds/SzrPc235n1IxWYdhJ2zF3MNUaoQ==} - peerDependencies: - react: ^16.11.0 || ^17.0.0 || ^18.0.0 + swr@2.2.0(react@18.2.0): dependencies: react: 18.2.0 use-sync-external-store: 1.2.0(react@18.2.0) - dev: true - /symbol-tree@3.2.4: - resolution: {integrity: sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw==} - dev: true + symbol-tree@3.2.4: {} - /synckit@0.8.8: - resolution: {integrity: sha512-HwOKAP7Wc5aRGYdKH+dw0PRRpbO841v2DENBtjnR5HFWoiNByAl7vrx3p0G/rCyYXQsrxqtX48TImFtPcIHSpQ==} - engines: {node: ^14.18.0 || >=16.0.0} + synckit@0.8.8: dependencies: '@pkgr/core': 0.1.1 tslib: 2.6.2 - dev: true - /table@6.8.1: - resolution: {integrity: sha512-Y4X9zqrCftUhMeH2EptSSERdVKt/nEdijTOacGD/97EKjhQ/Qs8RTlEGABSJNNN8lac9kheH+af7yAkEWlgneA==} - engines: {node: '>=10.0.0'} + table@6.8.1: dependencies: ajv: 8.12.0 lodash.truncate: 4.4.2 slice-ansi: 4.0.0 string-width: 4.2.3 strip-ansi: 6.0.1 - dev: true - /tapable@2.2.1: - resolution: {integrity: sha512-GNzQvQTOIP6RyTfE2Qxb8ZVlNmw0n88vp1szwWRimP02mnTsx3Wtn5qRdqY9w2XduFNUgvOwhNnQsjwCp+kqaQ==} - engines: {node: '>=6'} - dev: true + tapable@2.2.1: {} - /tar-fs@3.0.5: - resolution: {integrity: sha512-JOgGAmZyMgbqpLwct7ZV8VzkEB6pxXFBVErLtb+XCOqzc6w1xiWKI9GVd6bwk68EX7eJ4DWmfXVmq8K2ziZTGg==} + tar-fs@3.0.5: dependencies: pump: 3.0.0 tar-stream: 3.1.6 optionalDependencies: bare-fs: 2.2.3 bare-path: 2.1.1 - dev: true - /tar-stream@3.1.6: - resolution: {integrity: sha512-B/UyjYwPpMBv+PaFSWAmtYjwdrlEaZQEhMIBFNC5oEG8lpiW8XjcSdmEaClj28ArfKScKHs2nshz3k2le6crsg==} + tar-stream@3.1.6: dependencies: b4a: 1.6.4 fast-fifo: 1.3.2 streamx: 2.15.1 - dev: true - /tar@7.0.1: - resolution: {integrity: sha512-IjMhdQMZFpKsHEQT3woZVxBtCQY+0wk3CVxdRkGXEgyGa0dNS/ehPvOMr2nmfC7x5Zj2N+l6yZUpmICjLGS35w==} - engines: {node: '>=18'} + tar@7.0.1: dependencies: '@isaacs/fs-minipass': 4.0.1 chownr: 3.0.0 @@ -20664,11 +23469,8 @@ packages: minizlib: 3.0.1 mkdirp: 3.0.1 yallist: 5.0.0 - dev: false - /teeny-request@9.0.0: - resolution: {integrity: sha512-resvxdc6Mgb7YEThw6G6bExlXKkv6+YbuzGg9xuXxSgxJF7Ozs+o8Y9+2R3sArdWdW8nOokoQb1yrpFB0pQK2g==} - engines: {node: '>=14'} + teeny-request@9.0.0: dependencies: http-proxy-agent: 5.0.0 https-proxy-agent: 5.0.1 @@ -20678,194 +23480,99 @@ packages: transitivePeerDependencies: - encoding - supports-color - dev: false - /term-size@2.2.1: - resolution: {integrity: sha512-wK0Ri4fOGjv/XPy8SBHZChl8CM7uMc5VML7SqiQ0zG7+J5Vr+RMQDoHa2CNT6KHUnTGIXH34UDMkPzAUyapBZg==} - engines: {node: '>=8'} - dev: true + term-size@2.2.1: {} - /test-exclude@6.0.0: - resolution: {integrity: sha512-cAGWPIyOHU6zlmg88jwm7VRyXnMN7iV68OGAbYDk/Mh/xC/pzVPlQtY6ngoIH/5/tciuhGfvESU8GrHrcxD56w==} - engines: {node: '>=8'} + test-exclude@6.0.0: dependencies: '@istanbuljs/schema': 0.1.3 glob: 7.2.3 minimatch: 3.1.2 - dev: true - /text-encoder@0.0.4: - resolution: {integrity: sha512-12gllbNnC0Zdh9r+LCpEwpUdvncaE9hfUmCVm2ryCH1LEVUZbS6NdRq8omEgJI0zKgaGFTjwQVHbglGDCIbmNA==} - dev: true + text-encoder@0.0.4: {} - /text-extensions@2.4.0: - resolution: {integrity: sha512-te/NtwBwfiNRLf9Ijqx3T0nlqZiQ2XrrtBvu+cLL8ZRrGkO0NHTug8MYFKyoSrv/sHTaSKfilUkizV6XhxMJ3g==} - engines: {node: '>=8'} - dev: true + text-extensions@2.4.0: {} - /text-table@0.2.0: - resolution: {integrity: sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==} - dev: true + text-table@0.2.0: {} - /thirty-two@1.0.2: - resolution: {integrity: sha512-OEI0IWCe+Dw46019YLl6V10Us5bi574EvlJEOcAkB29IzQ/mYD1A6RyNHLjZPiHCmuodxvgF6U+vZO1L15lxVA==} - engines: {node: '>=0.2.6'} - dev: false + thirty-two@1.0.2: {} - /through2@4.0.2: - resolution: {integrity: sha512-iOqSav00cVxEEICeD7TjLB1sueEL+81Wpzp2bY17uZjZN0pWZPuo4suZ/61VujxmqSGFfgOcNuTZ85QJwNZQpw==} + through2@4.0.2: dependencies: readable-stream: 3.6.2 - /through@2.3.8: - resolution: {integrity: sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==} + through@2.3.8: {} - /timsort@0.3.0: - resolution: {integrity: sha512-qsdtZH+vMoCARQtyod4imc2nIJwg9Cc7lPRrw9CzF8ZKR0khdr8+2nX80PBhET3tcyTtJDxAffGh2rXH4tyU8A==} - dev: true + timsort@0.3.0: {} - /tiny-cookie@2.4.1: - resolution: {integrity: sha512-h8ueaMyvUd/9ZfRqCfa1t+0tXqfVFhdK8WpLHz8VXMqsiaj3Sqg64AOCH/xevLQGZk0ZV+/75ouITdkvp3taVA==} + tiny-cookie@2.4.1: {} - /tinybench@2.6.0: - resolution: {integrity: sha512-N8hW3PG/3aOoZAN5V/NSAEDz0ZixDSSt5b/a05iqtpgfLWMSVuCo7w0k2vVvEjdrIoeGqZzweX2WlyioNIHchA==} - dev: true + tinybench@2.6.0: {} - /tinycolor2@1.6.0: - resolution: {integrity: sha512-XPaBkWQJdsf3pLKJV9p4qN/S+fm2Oj8AIPo1BTUhg5oxkvm9+SVEGFdhyOz7tTdUTfvxMiAs4sp6/eZO2Ew+pw==} - dev: true + tinycolor2@1.6.0: {} - /tinypool@0.8.2: - resolution: {integrity: sha512-SUszKYe5wgsxnNOVlBYO6IC+8VGWdVGZWAqUxp3UErNBtptZvWbwyUOyzNL59zigz2rCA92QiL3wvG+JDSdJdQ==} - engines: {node: '>=14.0.0'} - dev: true + tinypool@0.8.2: {} - /tinyspy@2.2.1: - resolution: {integrity: sha512-KYad6Vy5VDWV4GH3fjpseMQ/XU2BhIYP7Vzd0LG44qRWm/Yt2WCOTicFdvmgo6gWaqooMQCawTtILVQJupKu7A==} - engines: {node: '>=14.0.0'} - dev: true + tinyspy@2.2.1: {} - /titleize@4.0.0: - resolution: {integrity: sha512-ZgUJ1K83rhdu7uh7EHAC2BgY5DzoX8V5rTvoWI4vFysggi6YjLe5gUXABPWAU7VkvGP7P/0YiWq+dcPeYDsf1g==} - engines: {node: '>=18'} - dev: true + titleize@4.0.0: {} - /tmp@0.0.33: - resolution: {integrity: sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==} - engines: {node: '>=0.6.0'} + tmp@0.0.33: dependencies: os-tmpdir: 1.0.2 - /tmpl@1.0.5: - resolution: {integrity: sha512-3f0uOEAQwIqGuWW2MVzYg8fV/QNnc/IpuJNG837rLuczAaLVHslWHZQj4IGiEl5Hs3kkbhwL9Ab7Hrsmuj+Smw==} - dev: true + tmpl@1.0.5: {} - /to-fast-properties@2.0.0: - resolution: {integrity: sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog==} - engines: {node: '>=4'} - dev: true + to-fast-properties@2.0.0: {} - /to-regex-range@5.0.1: - resolution: {integrity: sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==} - engines: {node: '>=8.0'} + to-regex-range@5.0.1: dependencies: is-number: 7.0.0 - dev: true - /toidentifier@1.0.1: - resolution: {integrity: sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==} - engines: {node: '>=0.6'} + toidentifier@1.0.1: {} - /touch@3.1.0: - resolution: {integrity: sha512-WBx8Uy5TLtOSRtIq+M03/sKDrXCLHxwDcquSP2c43Le03/9serjQBIztjRz6FkJez9D/hleyAXTBGLwwZUw9lA==} - hasBin: true + touch@3.1.0: dependencies: nopt: 1.0.10 - dev: true - /tough-cookie@4.1.3: - resolution: {integrity: sha512-aX/y5pVRkfRnfmuX+OdbSdXvPe6ieKX/G2s7e98f4poJHnqH3281gDPm/metm6E/WRamfx7WC4HUqkWHfQHprw==} - engines: {node: '>=6'} + tough-cookie@4.1.3: dependencies: psl: 1.9.0 punycode: 2.3.0 universalify: 0.2.0 url-parse: 1.5.10 - dev: true - /tr46@0.0.3: - resolution: {integrity: sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==} - dev: false + tr46@0.0.3: {} - /tr46@1.0.1: - resolution: {integrity: sha512-dTpowEjclQ7Kgx5SdBkqRzVhERQXov8/l9Ft9dVM9fmg0W0KQSVaXX9T4i6twCPNtYiZM53lpSSUAwJbFPOHxA==} + tr46@1.0.1: dependencies: punycode: 2.3.0 - /tr46@3.0.0: - resolution: {integrity: sha512-l7FvfAHlcmulp8kr+flpQZmVwtu7nfRV7NZujtN0OqES8EL4O4e0qqzL0DC5gAvx/ZC/9lk6rhcUwYvkBnBnYA==} - engines: {node: '>=12'} + tr46@3.0.0: dependencies: punycode: 2.3.0 - dev: true - /tree-kill@1.2.2: - resolution: {integrity: sha512-L0Orpi8qGpRG//Nd+H90vFB+3iHnue1zSSGmNOOCh1GLJ7rUKVwV2HvijphGQS2UmhUZewS9VgvxYIdgr+fG1A==} - hasBin: true - dev: true + tree-kill@1.2.2: {} - /trim-lines@3.0.1: - resolution: {integrity: sha512-kRj8B+YHZCc9kQYdWfJB2/oUl9rA99qbowYYBtr4ui4mZyAQ2JpvVBd/6U2YloATfqBhBTSMhTpgBHtU0Mf3Rg==} - dev: true + trim-lines@3.0.1: {} - /trim-newlines@3.0.1: - resolution: {integrity: sha512-c1PTsA3tYrIsLGkJkzHF+w9F2EyxfXGo4UyJc4pFL++FMjnq0HJS69T3M7d//gKrFKwy429bouPescbjecU+Zw==} - engines: {node: '>=8'} - dev: true + trim-newlines@3.0.1: {} - /trim-newlines@4.1.1: - resolution: {integrity: sha512-jRKj0n0jXWo6kh62nA5TEh3+4igKDXLvzBJcPpiizP7oOolUrYIxmVBG9TOtHYFHoddUk6YvAkGeGoSVTXfQXQ==} - engines: {node: '>=12'} - dev: true + trim-newlines@4.1.1: {} - /trim-trailing-lines@1.1.4: - resolution: {integrity: sha512-rjUWSqnfTNrjbB9NQWfPMH/xRK1deHeGsHoVfpxJ++XeYXE0d6B1En37AHfw3jtfTU7dzMzZL2jjpe8Qb5gLIQ==} - dev: true + trim-trailing-lines@1.1.4: {} - /trim@0.0.1: - resolution: {integrity: sha1-WFhUf2spB1fulczMZm+1AITEYN0=} - dev: true + trim@0.0.1: {} - /trough@1.0.5: - resolution: {integrity: sha512-rvuRbTarPXmMb79SmzEp8aqXNKcK+y0XaB298IXueQ8I2PsrATcPBCSPyK/dDNa2iWOhKlfNnOjdAOTBU/nkFA==} - dev: true + trough@1.0.5: {} - /trough@2.1.0: - resolution: {integrity: sha512-AqTiAOLcj85xS7vQ8QkAV41hPDIJ71XJB4RCUrzo/1GM2CQwhkJGaf9Hgr7BOugMRpgGUrqRg/DrBDl4H40+8g==} - dev: true + trough@2.1.0: {} - /ts-api-utils@1.3.0(typescript@5.3.3): - resolution: {integrity: sha512-UQMIo7pb8WRomKR1/+MFVLTroIvDVtMX3K6OUir8ynLyzB8Jeriont2bTAtmNPa1ekAgN7YPDyf6V+ygrdU+eQ==} - engines: {node: '>=16'} - peerDependencies: - typescript: '>=4.2.0' + ts-api-utils@1.3.0(typescript@5.3.3): dependencies: typescript: 5.3.3 - dev: true - /ts-node@10.9.2(@swc/core@1.3.52)(@types/node@20.12.7)(typescript@5.3.3): - resolution: {integrity: sha512-f0FFpIdcHgn8zcPSbf1dRevwt047YMnaiJM3u2w2RewrB+fob/zePZcrOyQoLMMO7aBIddLcQIEK5dYjkLnGrQ==} - hasBin: true - peerDependencies: - '@swc/core': '>=1.2.50' - '@swc/wasm': '>=1.2.50' - '@types/node': '*' - typescript: '>=2.7' - peerDependenciesMeta: - '@swc/core': - optional: true - '@swc/wasm': - optional: true + ts-node@10.9.2(@swc/core@1.3.52)(@types/node@20.12.7)(typescript@5.3.3): dependencies: '@cspotcode/source-map-support': 0.8.1 '@swc/core': 1.3.52 @@ -20883,38 +23590,25 @@ packages: typescript: 5.3.3 v8-compile-cache-lib: 3.0.1 yn: 3.1.1 - dev: true - /tsconfig-paths@3.15.0: - resolution: {integrity: sha512-2Ac2RgzDe/cn48GvOe3M+o82pEFewD3UPbyoUHHdKasHwJKjds4fLXWf/Ux5kATBKN20oaFGu+jbElp1pos0mg==} + tsconfig-paths@3.15.0: dependencies: '@types/json5': 0.0.29 json5: 1.0.2 minimist: 1.2.8 strip-bom: 3.0.0 - dev: true - /tslib@1.14.1: - resolution: {integrity: sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==} - dev: false + tslib@1.14.1: {} - /tslib@2.4.1: - resolution: {integrity: sha512-tGyy4dAjRIEwI7BzsB0lynWgOpfqjUdq91XXAlIWD2OwKBH7oCl/GZG/HT4BOHrTlPMOASlMQ7veyTqpmRcrNA==} + tslib@2.4.1: {} - /tslib@2.5.0: - resolution: {integrity: sha512-336iVw3rtn2BUK7ORdIAHTyxHGRIHVReokCR3XjbckJMK7ms8FysBfhLR8IXnAgy7T0PTPNBWKiH514FOW/WSg==} + tslib@2.5.0: {} - /tslib@2.6.2: - resolution: {integrity: sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q==} + tslib@2.6.2: {} - /tsscmp@1.0.6: - resolution: {integrity: sha512-LxhtAkPDTkVCMQjt2h6eBVY28KCjikZqZfMcC15YBeNjkgUpdCfBu5HoiOTDu86v6smE8yOjyEktJ8hlbANHQA==} - engines: {node: '>=0.6.x'} + tsscmp@1.0.6: {} - /tty-table@4.1.6: - resolution: {integrity: sha512-kRj5CBzOrakV4VRRY5kUWbNYvo/FpOsz65DzI5op9P+cHov3+IqPbo1JE1ZnQGkHdZgNFDsrEjrfqqy/Ply9fw==} - engines: {node: '>=8.0.0'} - hasBin: true + tty-table@4.1.6: dependencies: chalk: 4.1.2 csv: 5.5.3 @@ -20923,114 +23617,61 @@ packages: strip-ansi: 6.0.1 wcwidth: 1.0.1 yargs: 17.7.2 - dev: true - /tunnel@0.0.6: - resolution: {integrity: sha512-1h/Lnq9yajKY2PEbBadPXj3VxsDDu844OnaAo52UVmIzIvwwtBPIuNvkjuzBlTWpfJyUbG3ez0KSBibQkj4ojg==} - engines: {node: '>=0.6.11 <=0.7.0 || >=0.7.3'} - dev: false + tunnel@0.0.6: {} - /tween-functions@1.2.0: - resolution: {integrity: sha512-PZBtLYcCLtEcjL14Fzb1gSxPBeL7nWvGhO5ZFPGqziCcr8uvHp0NDmdjBchp6KHL+tExcg0m3NISmKxhU394dA==} - dev: true + tween-functions@1.2.0: {} - /type-check@0.3.2: - resolution: {integrity: sha512-ZCmOJdvOWDBYJlzAoFkC+Q0+bUyEOS1ltgp1MGU03fqHG+dbi9tBFU2Rd9QKiDZFAYrhPh2JUf7rZRIuHRKtOg==} - engines: {node: '>= 0.8.0'} + type-check@0.3.2: dependencies: prelude-ls: 1.1.2 - dev: true - /type-check@0.4.0: - resolution: {integrity: sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==} - engines: {node: '>= 0.8.0'} + type-check@0.4.0: dependencies: prelude-ls: 1.2.1 - dev: true - /type-detect@4.0.8: - resolution: {integrity: sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==} - engines: {node: '>=4'} - dev: true + type-detect@4.0.8: {} - /type-fest@0.13.1: - resolution: {integrity: sha512-34R7HTnG0XIJcBSn5XhDd7nNFPRcXYRZrBB2O2jdKqYODldSzBAqzsWoZYYvduky73toYS/ESqxPvkDf/F0XMg==} - engines: {node: '>=10'} - dev: true + type-fest@0.13.1: {} - /type-fest@0.20.2: - resolution: {integrity: sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==} - engines: {node: '>=10'} - dev: true + type-fest@0.20.2: {} - /type-fest@0.21.3: - resolution: {integrity: sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==} - engines: {node: '>=10'} - dev: true + type-fest@0.21.3: {} - /type-fest@0.6.0: - resolution: {integrity: sha512-q+MB8nYR1KDLrgr4G5yemftpMC7/QLqVndBmEEdqzmNj5dcFOO4Oo8qlwZE3ULT3+Zim1F8Kq4cBnikNhlCMlg==} - engines: {node: '>=8'} - dev: true + type-fest@0.6.0: {} - /type-fest@0.8.1: - resolution: {integrity: sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==} - engines: {node: '>=8'} - dev: true + type-fest@0.8.1: {} - /type-fest@1.4.0: - resolution: {integrity: sha512-yGSza74xk0UG8k+pLh5oeoYirvIiWo5t0/o3zHHAO2tRDiZcxWP7fywNlXhqb6/r6sWvwi+RsyQMWhVLe4BVuA==} - engines: {node: '>=10'} - dev: true + type-fest@1.4.0: {} - /type-fest@2.19.0: - resolution: {integrity: sha512-RAH822pAdBgcNMAfWnCBU3CFZcfZ/i1eZjwFU/dsLKumyuuP3niueg2UAukXYF0E2AAoc82ZSSf9J0WQBinzHA==} - engines: {node: '>=12.20'} + type-fest@2.19.0: {} - /type-fest@3.13.1: - resolution: {integrity: sha512-tLq3bSNx+xSpwvAJnzrK0Ep5CLNWjvFTOp71URMaAEWBfRb9nnJiBoUe0tF8bI4ZFO3omgBR6NvnbzVUT3Ly4g==} - engines: {node: '>=14.16'} - dev: false + type-fest@3.13.1: {} - /type-fest@4.15.0: - resolution: {integrity: sha512-tB9lu0pQpX5KJq54g+oHOLumOx+pMep4RaM6liXh2PKmVRFF+/vAtUP0ZaJ0kOySfVNjF6doBWPHhBhISKdlIA==} - engines: {node: '>=16'} - dev: false + type-fest@4.15.0: {} - /type-fest@4.2.0: - resolution: {integrity: sha512-5zknd7Dss75pMSED270A1RQS3KloqRJA9XbXLe0eCxyw7xXFb3rd+9B0UQ/0E+LQT6lnrLviEolYORlRWamn4w==} - engines: {node: '>=16'} + type-fest@4.2.0: {} - /type-is@1.6.18: - resolution: {integrity: sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==} - engines: {node: '>= 0.6'} + type-is@1.6.18: dependencies: media-typer: 0.3.0 mime-types: 2.1.35 - /typed-array-buffer@1.0.2: - resolution: {integrity: sha512-gEymJYKZtKXzzBzM4jqa9w6Q1Jjm7x2d+sh19AdsD4wqnMPDYyvwpsIc2Q/835kHuo3BEQ7CjelGhfTsoBb2MQ==} - engines: {node: '>= 0.4'} + typed-array-buffer@1.0.2: dependencies: call-bind: 1.0.7 es-errors: 1.3.0 is-typed-array: 1.1.13 - dev: true - /typed-array-byte-length@1.0.1: - resolution: {integrity: sha512-3iMJ9q0ao7WE9tWcaYKIptkNBuOIcZCCT0d4MRvuuH88fEoEH62IuQe0OtraD3ebQEoTRk8XCBoknUNc1Y67pw==} - engines: {node: '>= 0.4'} + typed-array-byte-length@1.0.1: dependencies: call-bind: 1.0.7 for-each: 0.3.3 gopd: 1.0.1 has-proto: 1.0.3 is-typed-array: 1.1.13 - dev: true - /typed-array-byte-offset@1.0.2: - resolution: {integrity: sha512-Ous0vodHa56FviZucS2E63zkgtgrACj7omjwd/8lTEMEPFFyjfixMZ1ZXenpgCFBBt4EC1J2XsyVS2gkG0eTFA==} - engines: {node: '>= 0.4'} + typed-array-byte-offset@1.0.2: dependencies: available-typed-arrays: 1.0.7 call-bind: 1.0.7 @@ -21038,11 +23679,8 @@ packages: gopd: 1.0.1 has-proto: 1.0.3 is-typed-array: 1.1.13 - dev: true - /typed-array-length@1.0.6: - resolution: {integrity: sha512-/OxDN6OtAk5KBpGb28T+HZc2M+ADtvRxXrKKbUwtsLgdoxgX13hyy7ek6bFRl5+aBs2yZzB0c4CnQfAtVypW/g==} - engines: {node: '>= 0.4'} + typed-array-length@1.0.6: dependencies: call-bind: 1.0.7 for-each: 0.3.3 @@ -21050,63 +23688,39 @@ packages: has-proto: 1.0.3 is-typed-array: 1.1.13 possible-typed-array-names: 1.0.0 - dev: true - /typescript@5.0.2: - resolution: {integrity: sha512-wVORMBGO/FAs/++blGNeAVdbNKtIh1rbBL2EyQ1+J9lClJ93KiiKe8PmFIVdXhHcyv44SL9oglmfeSsndo0jRw==} - engines: {node: '>=12.20'} - hasBin: true - dev: true + typescript@5.0.2: {} - /typescript@5.3.3: - resolution: {integrity: sha512-pXWcraxM0uxAS+tN0AG/BF2TyqmHO014Z070UsJ+pFvYuRSq8KH8DmWpnbXe0pEPDHXZV3FcAbJkijJ5oNEnWw==} - engines: {node: '>=14.17'} - hasBin: true + typescript@5.3.3: {} - /ua-parser-js@1.0.37: - resolution: {integrity: sha512-bhTyI94tZofjo+Dn8SN6Zv8nBDvyXTymAdM3LDI/0IboIUwTu1rEhW7v2TfiVsoYWgkQ4kOVqnI8APUFbIQIFQ==} - dev: true + ua-parser-js@1.0.37: {} - /ufo@1.5.2: - resolution: {integrity: sha512-eiutMaL0J2MKdhcOM1tUy13pIrYnyR87fEd8STJQFrrAwImwvlXkxlZEjaKah8r2viPohld08lt73QfLG1NxMg==} - dev: true + ufo@1.5.2: {} - /unbox-primitive@1.0.2: - resolution: {integrity: sha512-61pPlCD9h51VoreyJ0BReideM3MDKMKnh6+V9L08331ipq6Q8OFXZYiqP6n/tbHx4s5I9uRhcye6BrbkizkBDw==} + unbox-primitive@1.0.2: dependencies: call-bind: 1.0.7 has-bigints: 1.0.2 has-symbols: 1.0.3 which-boxed-primitive: 1.0.2 - dev: true - /unbzip2-stream@1.4.3: - resolution: {integrity: sha512-mlExGW4w71ebDJviH16lQLtZS32VKqsSfk80GCfUlwT/4/hNRFsoscrF/c++9xinkMzECL1uL9DDwXqFWkruPg==} + unbzip2-stream@1.4.3: dependencies: buffer: 5.7.1 through: 2.3.8 - dev: true - /undefsafe@2.0.5: - resolution: {integrity: sha512-WxONCrssBM8TSPRqN5EmsjVrsv4A8X12J4ArBiiayv3DyyG3ZlIg6yysuuSYdZsVz3TKcTg2fd//Ujd4CHV1iA==} - dev: true + undefsafe@2.0.5: {} - /undici-types@5.26.5: - resolution: {integrity: sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==} + undici-types@5.26.5: {} - /unherit@1.1.3: - resolution: {integrity: sha512-Ft16BJcnapDKp0+J/rqFC3Rrk6Y/Ng4nzsC028k2jdDII/rdZ7Wd3pPT/6+vIIxRagwRc9K0IUX0Ra4fKvw+WQ==} + unherit@1.1.3: dependencies: inherits: 2.0.4 xtend: 4.0.2 - dev: true - /unicorn-magic@0.1.0: - resolution: {integrity: sha512-lRfVq8fE8gz6QMBuDM6a+LO3IAzTi05H6gCVaUpir2E1Rwpo4ZUog45KpNXKC/Mn3Yb9UDuHumeFTo9iV/D9FQ==} - engines: {node: '>=18'} + unicorn-magic@0.1.0: {} - /unified@11.0.3: - resolution: {integrity: sha512-jlCV402P+YDcFcB2VcN/n8JasOddqIiaxv118wNBoZXEhOn+lYG7BR4Bfg2BwxvlK58dwbuH2w7GX2esAjL6Mg==} + unified@11.0.3: dependencies: '@types/unist': 3.0.0 bail: 2.0.2 @@ -21115,10 +23729,8 @@ packages: is-plain-obj: 4.1.0 trough: 2.1.0 vfile: 6.0.1 - dev: true - /unified@9.2.0: - resolution: {integrity: sha512-vx2Z0vY+a3YoTj8+pttM3tiJHCwY5UFbYdiWrwBEbHmK8pvsPj2rtAX2BFfgXen8T39CJWblWRDT4L5WGXtDdg==} + unified@9.2.0: dependencies: '@types/unist': 2.0.6 bail: 1.0.5 @@ -21127,241 +23739,147 @@ packages: is-plain-obj: 2.1.0 trough: 1.0.5 vfile: 4.2.1 - dev: true - /unist-builder@2.0.3: - resolution: {integrity: sha512-f98yt5pnlMWlzP539tPc4grGMsFaQQlP/vM396b00jngsiINumNmsY8rkXjfoi1c6QaM8nQ3vaGDuoKWbe/1Uw==} - dev: true + unist-builder@2.0.3: {} - /unist-util-generated@1.1.6: - resolution: {integrity: sha512-cln2Mm1/CZzN5ttGK7vkoGw+RZ8VcUH6BtGbq98DDtRGquAAOXig1mrBQYelOwMXYS8rK+vZDyyojSjp7JX+Lg==} - dev: true + unist-util-generated@1.1.6: {} - /unist-util-is@4.1.0: - resolution: {integrity: sha512-ZOQSsnce92GrxSqlnEEseX0gi7GH9zTJZ0p9dtu87WRb/37mMPO2Ilx1s/t9vBHrFhbgweUwb+t7cIn5dxPhZg==} - dev: true + unist-util-is@4.1.0: {} - /unist-util-is@6.0.0: - resolution: {integrity: sha512-2qCTHimwdxLfz+YzdGfkqNlH0tLi9xjTnHddPmJwtIG9MGsdbutfTc4P+haPD7l7Cjxf/WZj+we5qfVPvvxfYw==} + unist-util-is@6.0.0: dependencies: '@types/unist': 3.0.0 - dev: true - /unist-util-position@3.1.0: - resolution: {integrity: sha512-w+PkwCbYSFw8vpgWD0v7zRCl1FpY3fjDSQ3/N/wNd9Ffa4gPi8+4keqt99N3XW6F99t/mUzp2xAhNmfKWp95QA==} - dev: true + unist-util-position@3.1.0: {} - /unist-util-position@5.0.0: - resolution: {integrity: sha512-fucsC7HjXvkB5R3kTCO7kUjRdrS0BJt3M/FPxmHMBOm8JQi2BsHAHFsy27E0EolP8rp0NzXsJ+jNPyDWvOJZPA==} + unist-util-position@5.0.0: dependencies: '@types/unist': 3.0.0 - dev: true - /unist-util-remove-position@2.0.1: - resolution: {integrity: sha512-fDZsLYIe2uT+oGFnuZmy73K6ZxOPG/Qcm+w7jbEjaFcJgbQ6cqjs/eSPzXhsmGpAsWPkqZM9pYjww5QTn3LHMA==} + unist-util-remove-position@2.0.1: dependencies: unist-util-visit: 2.0.3 - dev: true - /unist-util-remove@2.1.0: - resolution: {integrity: sha512-J8NYPyBm4baYLdCbjmf1bhPu45Cr1MWTm77qd9istEkzWpnN6O9tMsEbB2JhNnBCqGENRqEWomQ+He6au0B27Q==} + unist-util-remove@2.1.0: dependencies: unist-util-is: 4.1.0 - dev: true - /unist-util-stringify-position@2.0.3: - resolution: {integrity: sha512-3faScn5I+hy9VleOq/qNbAd6pAx7iH5jYBMS9I1HgQVijz/4mv5Bvw5iw1sC/90CODiKo81G/ps8AJrISn687g==} + unist-util-stringify-position@2.0.3: dependencies: '@types/unist': 2.0.6 - dev: true - /unist-util-stringify-position@4.0.0: - resolution: {integrity: sha512-0ASV06AAoKCDkS2+xw5RXJywruurpbC4JZSm7nr7MOt1ojAzvyyaO+UxZf18j8FCF6kmzCZKcAgN/yu2gm2XgQ==} + unist-util-stringify-position@4.0.0: dependencies: '@types/unist': 3.0.0 - dev: true - /unist-util-visit-parents@3.1.1: - resolution: {integrity: sha512-1KROIZWo6bcMrZEwiH2UrXDyalAa0uqzWCxCJj6lPOvTve2WkfgCytoDTPaMnodXh1WrXOq0haVYHj99ynJlsg==} + unist-util-visit-parents@3.1.1: dependencies: '@types/unist': 2.0.6 unist-util-is: 4.1.0 - dev: true - /unist-util-visit-parents@6.0.1: - resolution: {integrity: sha512-L/PqWzfTP9lzzEa6CKs0k2nARxTdZduw3zyh8d2NVBnsyvHjSX4TWse388YrrQKbvI8w20fGjGlhgT96WwKykw==} + unist-util-visit-parents@6.0.1: dependencies: '@types/unist': 3.0.0 unist-util-is: 6.0.0 - dev: true - /unist-util-visit@2.0.3: - resolution: {integrity: sha512-iJ4/RczbJMkD0712mGktuGpm/U4By4FfDonL7N/9tATGIF4imikjOuagyMY53tnZq3NP6BcmlrHhEKAfGWjh7Q==} + unist-util-visit@2.0.3: dependencies: '@types/unist': 2.0.6 unist-util-is: 4.1.0 unist-util-visit-parents: 3.1.1 - dev: true - /unist-util-visit@5.0.0: - resolution: {integrity: sha512-MR04uvD+07cwl/yhVuVWAtw+3GOR/knlL55Nd/wAdblk27GCVt3lqpTivy/tkJcZoNPzTwS1Y+KMojlLDhoTzg==} + unist-util-visit@5.0.0: dependencies: '@types/unist': 3.0.0 unist-util-is: 6.0.0 unist-util-visit-parents: 6.0.1 - dev: true - /universalify@0.1.2: - resolution: {integrity: sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==} - engines: {node: '>= 4.0.0'} - dev: true + universalify@0.1.2: {} - /universalify@0.2.0: - resolution: {integrity: sha512-CJ1QgKmNg3CwvAv/kOFmtnEN05f0D/cn9QntgNOQlQF9dgvVTHj3t+8JPdjqawCHk7V/KA+fbUqzZ9XWhcqPUg==} - engines: {node: '>= 4.0.0'} - dev: true + universalify@0.2.0: {} - /unpipe@1.0.0: - resolution: {integrity: sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==} - engines: {node: '>= 0.8'} - dev: false + unpipe@1.0.0: {} - /update-browserslist-db@1.0.10(browserslist@4.21.4): - resolution: {integrity: sha512-OztqDenkfFkbSG+tRxBeAnCVPckDBcvibKd35yDONx6OU8N7sqgwc7rCbkJ/WcYtVRZ4ba68d6byhC21GFh7sQ==} - hasBin: true - peerDependencies: - browserslist: '>= 4.21.0' + update-browserslist-db@1.0.10(browserslist@4.21.4): dependencies: browserslist: 4.21.4 escalade: 3.1.1 picocolors: 1.0.0 - dev: true - /update-browserslist-db@1.0.13(browserslist@4.23.0): - resolution: {integrity: sha512-xebP81SNcPuNpPP3uzeW1NYXxI3rxyJzF3pD6sH4jE7o/IX+WtSpwnVU+qIsDPyk0d3hmFQ7mjqc6AtV604hbg==} - hasBin: true - peerDependencies: - browserslist: '>= 4.21.0' + update-browserslist-db@1.0.13(browserslist@4.23.0): dependencies: browserslist: 4.23.0 escalade: 3.1.1 picocolors: 1.0.0 - dev: true - /uri-js@4.4.1: - resolution: {integrity: sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==} + uri-js@4.4.1: dependencies: punycode: 2.3.0 - /url-parse@1.5.10: - resolution: {integrity: sha512-WypcfiRhfeUP9vvF0j6rw0J3hrWrw6iZv3+22h6iRMJ/8z1Tj6XfLP4DsUix5MhMPnXpiHDoKyoZ/bdCkwBCiQ==} + url-parse@1.5.10: dependencies: querystringify: 2.2.0 requires-port: 1.0.0 - dev: true - /urlpattern-polyfill@10.0.0: - resolution: {integrity: sha512-H/A06tKD7sS1O1X2SshBVeA5FLycRpjqiBeqGKmBwBDBy28EnRjORxTNe269KSSr5un5qyWi1iL61wLxpd+ZOg==} - dev: true + urlpattern-polyfill@10.0.0: {} - /use-debounced-loader@0.1.1(react@18.2.0): - resolution: {integrity: sha512-FbY/ynor7wZV55v1EvvAvu8CvSoEKT1azS2zFb/aLlL0vySbqTM7x9fIcaOJN++E52mVINNDe2VmWWd+Q00S+A==} - engines: {node: '>=10'} - peerDependencies: - react: '>=16 || ^18.0.0' + use-debounced-loader@0.1.1(react@18.2.0): dependencies: react: 18.2.0 - dev: true - /use-sync-external-store@1.2.0(react@18.2.0): - resolution: {integrity: sha512-eEgnFxGQ1Ife9bzYs6VLi8/4X6CObHMw9Qr9tPY43iKwsPw8xE8+EFsf/2cFZ5S3esXgpWgtSCtLNS41F+sKPA==} - peerDependencies: - react: ^16.8.0 || ^17.0.0 || ^18.0.0 + use-sync-external-store@1.2.0(react@18.2.0): dependencies: react: 18.2.0 - dev: true - /util-deprecate@1.0.2: - resolution: {integrity: sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==} + util-deprecate@1.0.2: {} - /utility-types@3.10.0: - resolution: {integrity: sha512-O11mqxmi7wMKCo6HKFt5AhO4BwY3VV68YU07tgxfz8zJTIxr4BpsezN49Ffwy9j3ZpwwJp4fkRwjRzq3uWE6Rg==} - engines: {node: '>= 4'} - dev: true + utility-types@3.10.0: {} - /uuid@8.3.2: - resolution: {integrity: sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==} - hasBin: true - dev: false + uuid@8.3.2: {} - /uuid@9.0.1: - resolution: {integrity: sha512-b+1eJOlsR9K8HJpow9Ok3fiWOWSIcIzXodvv0rQjVoOVNpWMpxf1wZNpt4y9h10odCNrqnYp1OBzRktckBe3sA==} - hasBin: true - dev: false + uuid@9.0.1: {} - /v8-compile-cache-lib@3.0.1: - resolution: {integrity: sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==} - dev: true + v8-compile-cache-lib@3.0.1: {} - /v8-to-istanbul@9.2.0: - resolution: {integrity: sha512-/EH/sDgxU2eGxajKdwLCDmQ4FWq+kpi3uCmBGpw1xJtnAxEjlD8j8PEiGWpCIMIs3ciNAgH0d3TTJiUkYzyZjA==} - engines: {node: '>=10.12.0'} + v8-to-istanbul@9.2.0: dependencies: '@jridgewell/trace-mapping': 0.3.25 '@types/istanbul-lib-coverage': 2.0.4 convert-source-map: 2.0.0 - dev: true - /validate-npm-package-license@3.0.4: - resolution: {integrity: sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==} + validate-npm-package-license@3.0.4: dependencies: spdx-correct: 3.2.0 spdx-expression-parse: 3.0.1 - dev: true - /vary@1.1.2: - resolution: {integrity: sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==} - engines: {node: '>= 0.8'} + vary@1.1.2: {} - /vfile-location@3.2.0: - resolution: {integrity: sha512-aLEIZKv/oxuCDZ8lkJGhuhztf/BW4M+iHdCwglA/eWc+vtuRFJj8EtgceYFX4LRjOhCAAiNHsKGssC6onJ+jbA==} - dev: true + vfile-location@3.2.0: {} - /vfile-message@2.0.4: - resolution: {integrity: sha512-DjssxRGkMvifUOJre00juHoP9DPWuzjxKuMDrhNbk2TdaYYBNMStsNhEOt3idrtI12VQYM/1+iM0KOzXi4pxwQ==} + vfile-message@2.0.4: dependencies: '@types/unist': 2.0.6 unist-util-stringify-position: 2.0.3 - dev: true - /vfile-message@4.0.2: - resolution: {integrity: sha512-jRDZ1IMLttGj41KcZvlrYAaI3CfqpLpfpf+Mfig13viT6NKvRzWZ+lXz0Y5D60w6uJIBAOGq9mSHf0gktF0duw==} + vfile-message@4.0.2: dependencies: '@types/unist': 3.0.0 unist-util-stringify-position: 4.0.0 - dev: true - /vfile@4.2.1: - resolution: {integrity: sha512-O6AE4OskCG5S1emQ/4gl8zK586RqA3srz3nfK/Viy0UPToBc5Trp9BVFb1u0CjsKrAWwnpr4ifM/KBXPWwJbCA==} + vfile@4.2.1: dependencies: '@types/unist': 2.0.6 is-buffer: 2.0.5 unist-util-stringify-position: 2.0.3 vfile-message: 2.0.4 - dev: true - /vfile@6.0.1: - resolution: {integrity: sha512-1bYqc7pt6NIADBJ98UiG0Bn/CHIVOoZ/IyEkqIruLg0mE1BKzkOXY2D6CSqQIcKqgadppE5lrxgWXJmXd7zZJw==} + vfile@6.0.1: dependencies: '@types/unist': 3.0.0 unist-util-stringify-position: 4.0.0 vfile-message: 4.0.2 - dev: true - /vite-node@1.4.0(@types/node@20.10.4): - resolution: {integrity: sha512-VZDAseqjrHgNd4Kh8icYHWzTKSCZMhia7GyHfhtzLW33fZlG9SwsB6CEhgyVOWkJfJ2pFLrp/Gj1FSfAiqH9Lw==} - engines: {node: ^18.0.0 || >=20.0.0} - hasBin: true + vite-node@1.4.0(@types/node@20.10.4): dependencies: cac: 6.7.14 debug: 4.3.4 @@ -21377,12 +23895,8 @@ packages: - sugarss - supports-color - terser - 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 + vite-node@1.4.0(@types/node@20.11.20): dependencies: cac: 6.7.14 debug: 4.3.4 @@ -21398,56 +23912,25 @@ packages: - sugarss - supports-color - terser - dev: true - /vite-node@1.4.0(@types/node@20.12.7): - resolution: {integrity: sha512-VZDAseqjrHgNd4Kh8icYHWzTKSCZMhia7GyHfhtzLW33fZlG9SwsB6CEhgyVOWkJfJ2pFLrp/Gj1FSfAiqH9Lw==} - engines: {node: ^18.0.0 || >=20.0.0} - hasBin: true + vite-node@1.4.0(@types/node@20.12.7): dependencies: cac: 6.7.14 debug: 4.3.4 pathe: 1.1.2 - picocolors: 1.0.0 - vite: 5.2.9(@types/node@20.12.7) - transitivePeerDependencies: - - '@types/node' - - less - - lightningcss - - sass - - stylus - - sugarss - - supports-color - - terser - dev: true - - /vite@5.2.9(@types/node@20.10.4): - resolution: {integrity: sha512-uOQWfuZBlc6Y3W/DTuQ1Sr+oIXWvqljLvS881SVmAj00d5RdgShLcuXWxseWPd4HXwiYBFW/vXHfKFeqj9uQnw==} - 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 + picocolors: 1.0.0 + vite: 5.2.9(@types/node@20.12.7) + transitivePeerDependencies: + - '@types/node' + - less + - lightningcss + - sass + - stylus + - sugarss + - supports-color + - terser + + vite@5.2.9(@types/node@20.10.4): dependencies: '@types/node': 20.10.4 esbuild: 0.20.2 @@ -21455,35 +23938,8 @@ packages: rollup: 4.14.3 optionalDependencies: fsevents: 2.3.3 - dev: true - /vite@5.2.9(@types/node@20.11.20): - resolution: {integrity: sha512-uOQWfuZBlc6Y3W/DTuQ1Sr+oIXWvqljLvS881SVmAj00d5RdgShLcuXWxseWPd4HXwiYBFW/vXHfKFeqj9uQnw==} - 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 + vite@5.2.9(@types/node@20.11.20): dependencies: '@types/node': 20.11.20 esbuild: 0.20.2 @@ -21491,35 +23947,8 @@ packages: rollup: 4.14.3 optionalDependencies: fsevents: 2.3.3 - dev: true - /vite@5.2.9(@types/node@20.12.7): - resolution: {integrity: sha512-uOQWfuZBlc6Y3W/DTuQ1Sr+oIXWvqljLvS881SVmAj00d5RdgShLcuXWxseWPd4HXwiYBFW/vXHfKFeqj9uQnw==} - 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 + vite@5.2.9(@types/node@20.12.7): dependencies: '@types/node': 20.12.7 esbuild: 0.20.2 @@ -21527,32 +23956,8 @@ packages: rollup: 4.14.3 optionalDependencies: fsevents: 2.3.3 - dev: true - /vitest@1.4.0(@types/node@20.10.4): - 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 + vitest@1.4.0(@types/node@20.10.4): dependencies: '@types/node': 20.10.4 '@vitest/expect': 1.4.0 @@ -21583,32 +23988,8 @@ packages: - sugarss - supports-color - terser - 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 + vitest@1.4.0(@types/node@20.11.20): dependencies: '@types/node': 20.11.20 '@vitest/expect': 1.4.0 @@ -21639,32 +24020,8 @@ packages: - sugarss - supports-color - terser - dev: true - /vitest@1.4.0(@types/node@20.12.7): - 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 + vitest@1.4.0(@types/node@20.12.7): dependencies: '@types/node': 20.12.7 '@vitest/expect': 1.4.0 @@ -21695,24 +24052,14 @@ packages: - sugarss - supports-color - terser - dev: true - /void-elements@3.1.0: - resolution: {integrity: sha1-YU9/v42AHwu18GYfWy9XhXUOTwk=} - engines: {node: '>=0.10.0'} - dev: true + void-elements@3.1.0: {} - /w3c-xmlserializer@3.0.0: - resolution: {integrity: sha512-3WFqGEgSXIyGhOmAFtlicJNMjEps8b1MG31NCA0/vOF9+nKMUW1ckhi9cnNHmf88Rzw5V+dwIwsm2C7X8k9aQg==} - engines: {node: '>=12'} + w3c-xmlserializer@3.0.0: dependencies: xml-name-validator: 4.0.0 - dev: true - /wait-on@7.2.0: - resolution: {integrity: sha512-wCQcHkRazgjG5XoAq9jbTMLpNIjoSlZslrJ2+N9MxDsGEv1HnFoVjOCexL0ESva7Y9cu350j+DWADdk54s4AFQ==} - engines: {node: '>=12.0.0'} - hasBin: true + wait-on@7.2.0: dependencies: axios: 1.6.7 joi: 17.12.2 @@ -21721,92 +24068,60 @@ packages: rxjs: 7.8.1 transitivePeerDependencies: - debug - dev: true - /walker@1.0.8: - resolution: {integrity: sha512-ts/8E8l5b7kY0vlWLewOkDXMmPdLcVV4GmOQLyxuSswIJsweeFZtAsMF7k1Nszz+TYBQrlYRmzOnr398y1JemQ==} + walker@1.0.8: dependencies: makeerror: 1.0.12 - dev: true - /warning@4.0.3: - resolution: {integrity: sha512-rpJyN222KWIvHJ/F53XSZv0Zl/accqHR8et1kpaMTD/fLCRxtV8iX8czMzY7sVZupTI3zcUTg8eycS2kNF9l6w==} + warning@4.0.3: dependencies: loose-envify: 1.4.0 - dev: true - /wcwidth@1.0.1: - resolution: {integrity: sha512-XHPEwS0q6TaxcvG85+8EYkbiCux2XtWG2mkc47Ng2A77BQu9+DqIOJldST4HgPkuea7dvKSj5VgX3P1d4rW8Tg==} + wcwidth@1.0.1: dependencies: defaults: 1.0.4 - /weak-lru-cache@1.2.2: - resolution: {integrity: sha512-DEAoo25RfSYMuTGc9vPJzZcZullwIqRDSI9LOy+fkCJPi6hykCnfKaXTuPBDuXAUcqHXyOgFtHNp/kB2FjYHbw==} - dev: true + weak-lru-cache@1.2.2: {} - /web-namespaces@1.1.4: - resolution: {integrity: sha512-wYxSGajtmoP4WxfejAPIr4l0fVh+jeMXZb08wNc0tMg6xsfZXj3cECqIK0G7ZAqUq0PP8WlMDtaOGVBTAWztNw==} - dev: true + web-namespaces@1.1.4: {} - /webidl-conversions@3.0.1: - resolution: {integrity: sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==} - dev: false + webidl-conversions@3.0.1: {} - /webidl-conversions@4.0.2: - resolution: {integrity: sha512-YQ+BmxuTgd6UXZW3+ICGfyqRyHXVlD5GtQr5+qjiNW7bF0cqrzX500HVXPBOvgXb5YnzDd+h0zqyv61KUD7+Sg==} + webidl-conversions@4.0.2: {} - /webidl-conversions@7.0.0: - resolution: {integrity: sha512-VwddBukDzu71offAQR975unBIGqfKZpM+8ZX6ySk8nYhVoo5CYaZyzt3YBvYtRtO+aoGlqxPg/B87NGVZ/fu6g==} - engines: {node: '>=12'} - dev: true + webidl-conversions@7.0.0: {} - /whatwg-encoding@2.0.0: - resolution: {integrity: sha512-p41ogyeMUrw3jWclHWTQg1k05DSVXPLcVxRTYsXUk+ZooOCZLcoYgPZ/HL/D/N+uQPOtcp1me1WhBEaX02mhWg==} - engines: {node: '>=12'} + whatwg-encoding@2.0.0: dependencies: iconv-lite: 0.6.3 - dev: true - /whatwg-mimetype@3.0.0: - resolution: {integrity: sha512-nt+N2dzIutVRxARx1nghPKGv1xHikU7HKdfafKkLNLindmPU/ch3U31NOCGGA/dmPcmb1VlofO0vnKAcsm0o/Q==} - engines: {node: '>=12'} - dev: true + whatwg-mimetype@3.0.0: {} - /whatwg-url@11.0.0: - resolution: {integrity: sha512-RKT8HExMpoYx4igMiVMY83lN6UeITKJlBQ+vR/8ZJ8OCdSiN3RwCq+9gH0+Xzj0+5IrM6i4j/6LuvzbZIQgEcQ==} - engines: {node: '>=12'} + whatwg-url@11.0.0: dependencies: tr46: 3.0.0 webidl-conversions: 7.0.0 - dev: true - /whatwg-url@5.0.0: - resolution: {integrity: sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==} + whatwg-url@5.0.0: dependencies: tr46: 0.0.3 webidl-conversions: 3.0.1 - dev: false - /whatwg-url@7.1.0: - resolution: {integrity: sha512-WUu7Rg1DroM7oQvGWfOiAK21n74Gg+T4elXEQYkOhtyLeWiJFoOGLXPKI/9gzIie9CtwVLm8wtw6YJdKyxSjeg==} + whatwg-url@7.1.0: dependencies: lodash.sortby: 4.7.0 tr46: 1.0.1 webidl-conversions: 4.0.2 - /which-boxed-primitive@1.0.2: - resolution: {integrity: sha512-bwZdv0AKLpplFY2KZRX6TvyuN7ojjr7lwkg6ml0roIy9YeuSr7JS372qlNW18UQYzgYK9ziGcerWqZOmEn9VNg==} + which-boxed-primitive@1.0.2: dependencies: is-bigint: 1.0.4 is-boolean-object: 1.1.2 is-number-object: 1.0.7 is-string: 1.0.7 is-symbol: 1.0.4 - dev: true - /which-builtin-type@1.1.3: - resolution: {integrity: sha512-YmjsSMDBYsM1CaFiayOVT06+KJeXf0o5M/CAd4o1lTadFAtacTUM49zoYxr/oroopFDfhvN6iEcBxUyc3gvKmw==} - engines: {node: '>= 0.4'} + which-builtin-type@1.1.3: dependencies: function.prototype.name: 1.1.6 has-tostringtag: 1.0.2 @@ -21820,236 +24135,134 @@ packages: which-boxed-primitive: 1.0.2 which-collection: 1.0.2 which-typed-array: 1.1.15 - dev: true - /which-collection@1.0.2: - resolution: {integrity: sha512-K4jVyjnBdgvc86Y6BkaLZEN933SwYOuBFkdmBu9ZfkcAbdVbpITnDmjvZ/aQjRXQrv5EPkTnD1s39GiiqbngCw==} - engines: {node: '>= 0.4'} + which-collection@1.0.2: dependencies: is-map: 2.0.3 is-set: 2.0.3 is-weakmap: 2.0.2 is-weakset: 2.0.3 - dev: true - /which-module@2.0.0: - resolution: {integrity: sha512-B+enWhmw6cjfVC7kS8Pj9pCrKSc5txArRyaYGe088shv/FGWH+0Rjx/xPgtsWfsUtS27FkP697E4DDhgrgoc0Q==} + which-module@2.0.0: {} - /which-pm@2.0.0: - resolution: {integrity: sha512-Lhs9Pmyph0p5n5Z3mVnN0yWcbQYUAD7rbQUiMsQxOJ3T57k7RFe35SUwWMf7dsbDZks1uOmw4AecB/JMDj3v/w==} - engines: {node: '>=8.15'} + which-pm@2.0.0: dependencies: load-yaml-file: 0.2.0 path-exists: 4.0.0 - dev: true - /which-typed-array@1.1.15: - resolution: {integrity: sha512-oV0jmFtUky6CXfkqehVvBP/LSWJ2sy4vWMioiENyJLePrBO/yKyV9OyJySfAKosh+RYkIl5zJCNZ8/4JncrpdA==} - engines: {node: '>= 0.4'} + which-typed-array@1.1.15: dependencies: available-typed-arrays: 1.0.7 call-bind: 1.0.7 for-each: 0.3.3 gopd: 1.0.1 has-tostringtag: 1.0.2 - dev: true - /which@1.3.1: - resolution: {integrity: sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==} - hasBin: true + which@1.3.1: dependencies: isexe: 2.0.0 - dev: true - /which@2.0.2: - resolution: {integrity: sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==} - engines: {node: '>= 8'} - hasBin: true + which@2.0.2: dependencies: isexe: 2.0.0 - /why-is-node-running@2.2.2: - resolution: {integrity: sha512-6tSwToZxTOcotxHeA+qGCq1mVzKR3CwcJGmVcY+QE8SHy6TnpFnh8PAvPNHYr7EcuVeG0QSMxtYCuO1ta/G/oA==} - engines: {node: '>=8'} - hasBin: true + why-is-node-running@2.2.2: dependencies: siginfo: 2.0.0 stackback: 0.0.2 - dev: true - /word-wrap@1.2.3: - resolution: {integrity: sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ==} - engines: {node: '>=0.10.0'} - dev: true + word-wrap@1.2.3: {} - /wrap-ansi@6.2.0: - resolution: {integrity: sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==} - engines: {node: '>=8'} + wrap-ansi@6.2.0: dependencies: ansi-styles: 4.3.0 string-width: 4.2.3 strip-ansi: 6.0.1 - /wrap-ansi@7.0.0: - resolution: {integrity: sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==} - engines: {node: '>=10'} + wrap-ansi@7.0.0: dependencies: ansi-styles: 4.3.0 string-width: 4.2.3 strip-ansi: 6.0.1 - /wrap-ansi@8.0.1: - resolution: {integrity: sha512-QFF+ufAqhoYHvoHdajT/Po7KoXVBPXS2bgjIam5isfWJPfIOnQZ50JtUiVvCv/sjgacf3yRrt2ZKUZ/V4itN4g==} - engines: {node: '>=12'} + wrap-ansi@8.0.1: dependencies: ansi-styles: 6.2.1 string-width: 5.1.2 strip-ansi: 7.0.1 - dev: false - /wrap-ansi@8.1.0: - resolution: {integrity: sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==} - engines: {node: '>=12'} + wrap-ansi@8.1.0: dependencies: ansi-styles: 6.2.1 string-width: 5.1.2 strip-ansi: 7.1.0 - /wrappy@1.0.2: - resolution: {integrity: sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==} + wrappy@1.0.2: {} - /write-file-atomic@4.0.2: - resolution: {integrity: sha512-7KxauUdBmSdWnmpaGFg+ppNjKF8uNLry8LyzjauQDOVONfFLNKrKvQOxZ/VuTIcS/gge/YNahf5RIIQWTSarlg==} - engines: {node: ^12.13.0 || ^14.15.0 || >=16.0.0} + write-file-atomic@4.0.2: dependencies: imurmurhash: 0.1.4 signal-exit: 3.0.7 - dev: true - /write-file-atomic@5.0.1: - resolution: {integrity: sha512-+QU2zd6OTD8XWIJCbffaiQeH9U73qIqafo1x6V1snCWYGJf6cVE0cDR4D8xRzcEnfI21IFrUPzPGtcPf8AC+Rw==} - engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} + write-file-atomic@5.0.1: dependencies: imurmurhash: 0.1.4 signal-exit: 4.1.0 - dev: true - /ws@8.16.0: - resolution: {integrity: sha512-HS0c//TP7Ina87TfiPUz1rQzMhHrl/SG2guqRcTOIUYD2q8uhUdNHZYJUaQ8aTGPzCh+c6oawMKW35nFl1dxyQ==} - engines: {node: '>=10.0.0'} - peerDependencies: - bufferutil: ^4.0.1 - utf-8-validate: '>=5.0.2' - peerDependenciesMeta: - bufferutil: - optional: true - utf-8-validate: - optional: true - dev: true + ws@8.16.0: {} - /xml-crypto@3.0.1: - resolution: {integrity: sha512-7XrwB3ujd95KCO6+u9fidb8ajvRJvIfGNWD0XLJoTWlBKz+tFpUzEYxsN+Il/6/gHtEs1RgRh2RH+TzhcWBZUw==} - engines: {node: '>=0.4.0'} + xml-crypto@3.0.1: dependencies: '@xmldom/xmldom': 0.8.7 xpath: 0.0.32 - dev: false - /xml-escape@1.1.0: - resolution: {integrity: sha512-B/T4sDK8Z6aUh/qNr7mjKAwwncIljFuUP+DO/D5hloYFj+90O88z8Wf7oSucZTHxBAsC1/CTP4rtx/x1Uf72Mg==} - dev: false + xml-escape@1.1.0: {} - /xml-name-validator@4.0.0: - resolution: {integrity: sha512-ICP2e+jsHvAj2E2lIHxa5tjXRlKDJo4IdvPvCXbXQGdzSfmSpNVyIKMvoZHjDY9DP0zV17iI85o90vRFXNccRw==} - engines: {node: '>=12'} - dev: true + xml-name-validator@4.0.0: {} - /xml2js@0.5.0: - resolution: {integrity: sha512-drPFnkQJik/O+uPKpqSgr22mpuFHqKdbS835iAQrUC73L2F5WkboIRd63ai/2Yg6I1jzifPFKH2NTK+cfglkIA==} - engines: {node: '>=4.0.0'} + xml2js@0.5.0: dependencies: sax: 1.2.4 xmlbuilder: 11.0.1 - dev: false - /xml@1.0.1: - resolution: {integrity: sha512-huCv9IH9Tcf95zuYCsQraZtWnJvBtLVE0QHMOs8bWyZAFZNDcYjsPq1nEx8jKA9y+Beo9v+7OBPRisQTjinQMw==} - dev: false + xml@1.0.1: {} - /xmlbuilder@11.0.1: - resolution: {integrity: sha512-fDlsI/kFEx7gLvbecc0/ohLG50fugQp8ryHzMTuW9vSa1GJ0XYWKnhsUx7oie3G98+r56aTQIUB4kht42R3JvA==} - engines: {node: '>=4.0'} - dev: false + xmlbuilder@11.0.1: {} - /xmlchars@2.2.0: - resolution: {integrity: sha512-JZnDKK8B0RCDw84FNdDAIpZK+JuJw+s7Lz8nksI7SIuU3UXJJslUthsi+uWBUYOwPFwW7W7PRLRfUKpxjtjFCw==} - dev: true + xmlchars@2.2.0: {} - /xpath@0.0.32: - resolution: {integrity: sha512-rxMJhSIoiO8vXcWvSifKqhvV96GjiD5wYb8/QHdoRyQvraTpp4IEv944nhGausZZ3u7dhQXteZuZbaqfpB7uYw==} - engines: {node: '>=0.6.0'} - dev: false + xpath@0.0.32: {} - /xtend@4.0.2: - resolution: {integrity: sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==} - engines: {node: '>=0.4'} + xtend@4.0.2: {} - /xxhash-wasm@0.4.2: - resolution: {integrity: sha512-/eyHVRJQCirEkSZ1agRSCwriMhwlyUcFkXD5TPVSLP+IPzjsqMVzZwdoczLp1SoQU0R3dxz1RpIK+4YNQbCVOA==} - dev: true + xxhash-wasm@0.4.2: {} - /y18n@4.0.3: - resolution: {integrity: sha512-JKhqTOwSrqNA1NY5lSztJ1GrBiUodLMmIZuLiDaMRJ+itFd+ABVE8XBjOvIWL+rSqNDC74LCSFmlb/U4UZ4hJQ==} + y18n@4.0.3: {} - /y18n@5.0.8: - resolution: {integrity: sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==} - engines: {node: '>=10'} + y18n@5.0.8: {} - /yallist@2.1.2: - resolution: {integrity: sha512-ncTzHV7NvsQZkYe1DW7cbDLm0YpzHmZF5r/iyP3ZnQtMiJ+pjzisCiMNI+Sj+xQF5pXhSHxSB3uDbsBTzY/c2A==} - dev: true + yallist@2.1.2: {} - /yallist@3.1.1: - resolution: {integrity: sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==} - dev: true + yallist@3.1.1: {} - /yallist@4.0.0: - resolution: {integrity: sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==} + yallist@4.0.0: {} - /yallist@5.0.0: - resolution: {integrity: sha512-YgvUTfwqyc7UXVMrB+SImsVYSmTS8X/tSrtdNZMImM+n7+QTriRXyXim0mBrTXNeqzVF0KWGgHPeiyViFFrNDw==} - engines: {node: '>=18'} - dev: false + yallist@5.0.0: {} - /yaml@1.10.2: - resolution: {integrity: sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg==} - engines: {node: '>= 6'} - dev: true + yaml@1.10.2: {} - /yaml@2.3.3: - resolution: {integrity: sha512-zw0VAJxgeZ6+++/su5AFoqBbZbrEakwu+X0M5HmcwUiBL7AzcuPKjj5we4xfQLp78LkEMpD0cOnUhmgOVy3KdQ==} - engines: {node: '>= 14'} - dev: true + yaml@2.3.3: {} - /yargs-parser@18.1.3: - resolution: {integrity: sha512-o50j0JeToy/4K6OZcaQmW6lyXXKhq7csREXcDwk2omFPJEwUNOVtJKvmDr9EI1fAJZUyZcRF7kxGBWmRXudrCQ==} - engines: {node: '>=6'} + yargs-parser@18.1.3: dependencies: camelcase: 5.3.1 decamelize: 1.2.0 - /yargs-parser@20.2.9: - resolution: {integrity: sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w==} - engines: {node: '>=10'} - dev: true + yargs-parser@20.2.9: {} - /yargs-parser@21.1.1: - resolution: {integrity: sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==} - engines: {node: '>=12'} + yargs-parser@21.1.1: {} - /yargs@15.4.1: - resolution: {integrity: sha512-aePbxDmcYW++PaqBsJ+HYUFwCdv4LVvdnhBy78E57PIor8/OVvhMrADFFEDh8DHDFRv/O9i3lPhsENjO7QX0+A==} - engines: {node: '>=8'} + yargs@15.4.1: dependencies: cliui: 6.0.0 decamelize: 1.2.0 @@ -22063,9 +24276,7 @@ packages: y18n: 4.0.3 yargs-parser: 18.1.3 - /yargs@17.6.0: - resolution: {integrity: sha512-8H/wTDqlSwoSnScvV2N/JHfLWOKuh5MVla9hqLjK3nsfyy6Y4kDSYSvkU5YCUEPOSnRXfIyx3Sq+B/IWudTo4g==} - engines: {node: '>=12'} + yargs@17.6.0: dependencies: cliui: 8.0.1 escalade: 3.1.1 @@ -22074,11 +24285,8 @@ packages: string-width: 4.2.3 y18n: 5.0.8 yargs-parser: 21.1.1 - dev: false - /yargs@17.7.2: - resolution: {integrity: sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==} - engines: {node: '>=12'} + yargs@17.7.2: dependencies: cliui: 8.0.1 escalade: 3.1.1 @@ -22087,50 +24295,27 @@ packages: string-width: 4.2.3 y18n: 5.0.8 yargs-parser: 21.1.1 - dev: true - /yauzl@2.10.0: - resolution: {integrity: sha512-p4a9I6X6nu6IhoGmBqAcbJy1mlC4j27vEPZX9F4L4/vZT3Lyq1VkFHw/V/PUcB9Buo+DG3iHkT0x3Qya58zc3g==} + yauzl@2.10.0: dependencies: buffer-crc32: 0.2.13 fd-slicer: 1.1.0 - dev: true - /ylru@1.2.1: - resolution: {integrity: sha512-faQrqNMzcPCHGVC2aaOINk13K+aaBDUPjGWl0teOXywElLjyVAB6Oe2jj62jHYtwsU49jXhScYbvPENK+6zAvQ==} - engines: {node: '>= 4.0.0'} + ylru@1.2.1: {} - /yn@3.1.1: - resolution: {integrity: sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==} - engines: {node: '>=6'} - dev: true + yn@3.1.1: {} - /yocto-queue@0.1.0: - resolution: {integrity: sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==} - engines: {node: '>=10'} + yocto-queue@0.1.0: {} - /yocto-queue@1.0.0: - resolution: {integrity: sha512-9bnSc/HEW2uRy67wc+T8UwauLuPJVn28jb+GtJY16iiKWyvmYJRXVT4UamsAEGQfPohgr2q4Tq0sQbQlxTfi1g==} - engines: {node: '>=12.20'} + yocto-queue@1.0.0: {} - /zod-to-ts@1.2.0(typescript@5.3.3)(zod@3.22.4): - resolution: {integrity: sha512-x30XE43V+InwGpvTySRNz9kB7qFU8DlyEy7BsSTCHPH1R0QasMmHWZDCzYm6bVXtj/9NNJAZF3jW8rzFvH5OFA==} - peerDependencies: - typescript: ^4.9.4 || ^5.0.2 - zod: ^3 + zod-to-ts@1.2.0(typescript@5.3.3)(zod@3.22.4): dependencies: typescript: 5.3.3 zod: 3.22.4 - dev: true - /zod@3.22.4: - resolution: {integrity: sha512-iC+8Io04lddc+mVqQ9AZ7OQ2MrUKGN+oIQyq1vemgt46jwCwLfhq7/pwnBnNXXXZb8VTVLKwp9EDkx+ryxIWmg==} - requiresBuild: true + zod@3.22.4: {} - /zwitch@1.0.5: - resolution: {integrity: sha512-V50KMwwzqJV0NpZIZFwfOD5/lyny3WlSzRiXgA0G7VUnRlqttta1L6UQIHzd6EuBY/cHGfwTIck7w1yH6Q5zUw==} - dev: true + zwitch@1.0.5: {} - /zwitch@2.0.2: - resolution: {integrity: sha512-JZxotl7SxAJH0j7dN4pxsTV6ZLXoLdGME+PsjkL/DaBrVryK9kTGq06GfKrwcSOqypP+fdXGoCHE36b99fWVoA==} - dev: true + zwitch@2.0.2: {} From 3227f61fad97e0e494aa75095942860534c7747e Mon Sep 17 00:00:00 2001 From: Xiao Yijun Date: Thu, 9 May 2024 18:52:38 +0800 Subject: [PATCH 357/687] feat(console): support assign organization resource scopes for 3rd-party app (#5812) --- .../console/src/components/FormCard/index.tsx | 2 +- .../constants.ts | 27 --- .../index.tsx | 114 ----------- .../constants.ts | 40 ++++ .../index.tsx | 160 ++++++++++++++++ .../ApplicationScopesAssignmentModal/type.ts | 23 ++- .../use-application-scopes-assignment.ts | 43 ++++- .../use-organization-scopes-assignment.ts | 0 .../use-resource-scopes-assignment.ts | 27 ++- .../use-user-scopes-assignment.ts | 0 .../index.tsx | 0 .../PermissionsCard/index.module.scss | 20 ++ .../Permissions/PermissionsCard/index.tsx | 179 ++++++++++++++++++ .../use-scopes-table.tsx | 71 +++++-- .../Permissions/index.module.scss | 21 +- .../Permissions/index.tsx | 138 ++------------ .../admin-console/application-details.ts | 21 +- .../admin-console/application-details.ts | 14 +- .../admin-console/application-details.ts | 21 +- .../admin-console/application-details.ts | 21 +- .../admin-console/application-details.ts | 21 +- .../admin-console/application-details.ts | 21 +- .../admin-console/application-details.ts | 21 +- .../admin-console/application-details.ts | 21 +- .../admin-console/application-details.ts | 21 +- .../admin-console/application-details.ts | 21 +- .../admin-console/application-details.ts | 21 +- .../admin-console/application-details.ts | 21 +- .../admin-console/application-details.ts | 21 +- .../admin-console/application-details.ts | 21 +- .../admin-console/application-details.ts | 21 +- 31 files changed, 826 insertions(+), 347 deletions(-) delete mode 100644 packages/console/src/pages/ApplicationDetails/ApplicationDetailsContent/Permissions/ApplicationScopesAssignmentModal/constants.ts delete mode 100644 packages/console/src/pages/ApplicationDetails/ApplicationDetailsContent/Permissions/ApplicationScopesAssignmentModal/index.tsx create mode 100644 packages/console/src/pages/ApplicationDetails/ApplicationDetailsContent/Permissions/PermissionsCard/ApplicationScopesAssignmentModal/constants.ts create mode 100644 packages/console/src/pages/ApplicationDetails/ApplicationDetailsContent/Permissions/PermissionsCard/ApplicationScopesAssignmentModal/index.tsx rename packages/console/src/pages/ApplicationDetails/ApplicationDetailsContent/Permissions/{ => PermissionsCard}/ApplicationScopesAssignmentModal/type.ts (65%) rename packages/console/src/pages/ApplicationDetails/ApplicationDetailsContent/Permissions/{ => PermissionsCard}/ApplicationScopesAssignmentModal/use-application-scopes-assignment.ts (71%) rename packages/console/src/pages/ApplicationDetails/ApplicationDetailsContent/Permissions/{ => PermissionsCard}/ApplicationScopesAssignmentModal/use-organization-scopes-assignment.ts (100%) rename packages/console/src/pages/ApplicationDetails/ApplicationDetailsContent/Permissions/{ => PermissionsCard}/ApplicationScopesAssignmentModal/use-resource-scopes-assignment.ts (72%) rename packages/console/src/pages/ApplicationDetails/ApplicationDetailsContent/Permissions/{ => PermissionsCard}/ApplicationScopesAssignmentModal/use-user-scopes-assignment.ts (100%) rename packages/console/src/pages/ApplicationDetails/ApplicationDetailsContent/Permissions/{ => PermissionsCard}/ApplicationScopesManagementModal/index.tsx (100%) create mode 100644 packages/console/src/pages/ApplicationDetails/ApplicationDetailsContent/Permissions/PermissionsCard/index.module.scss create mode 100644 packages/console/src/pages/ApplicationDetails/ApplicationDetailsContent/Permissions/PermissionsCard/index.tsx rename packages/console/src/pages/ApplicationDetails/ApplicationDetailsContent/Permissions/{ => PermissionsCard}/use-scopes-table.tsx (71%) diff --git a/packages/console/src/components/FormCard/index.tsx b/packages/console/src/components/FormCard/index.tsx index 484b4897f06..565a3615a49 100644 --- a/packages/console/src/components/FormCard/index.tsx +++ b/packages/console/src/components/FormCard/index.tsx @@ -8,7 +8,7 @@ import type { Props as TextLinkProps } from '@/ds-components/TextLink'; import FormCardLayout from './FormCardLayout'; import * as styles from './index.module.scss'; -type Props = { +export type Props = { readonly title: AdminConsoleKey; readonly tag?: ReactNode; readonly description?: AdminConsoleKey; diff --git a/packages/console/src/pages/ApplicationDetails/ApplicationDetailsContent/Permissions/ApplicationScopesAssignmentModal/constants.ts b/packages/console/src/pages/ApplicationDetails/ApplicationDetailsContent/Permissions/ApplicationScopesAssignmentModal/constants.ts deleted file mode 100644 index b9cc89f6f5f..00000000000 --- a/packages/console/src/pages/ApplicationDetails/ApplicationDetailsContent/Permissions/ApplicationScopesAssignmentModal/constants.ts +++ /dev/null @@ -1,27 +0,0 @@ -import { type AdminConsoleKey } from '@logto/phrases'; -import { ApplicationUserConsentScopeType } from '@logto/schemas'; - -export const permissionTabs = Object.freeze({ - [ApplicationUserConsentScopeType.UserScopes]: { - title: 'application_details.permissions.user_profile', - key: ApplicationUserConsentScopeType.UserScopes, - }, - [ApplicationUserConsentScopeType.ResourceScopes]: { - title: 'application_details.permissions.api_resource', - key: ApplicationUserConsentScopeType.ResourceScopes, - }, - [ApplicationUserConsentScopeType.OrganizationResourceScopes]: { - // TODO @xiaoyijun: update the title - title: 'application_details.permissions.api_resource', - key: ApplicationUserConsentScopeType.OrganizationResourceScopes, - }, - [ApplicationUserConsentScopeType.OrganizationScopes]: { - title: 'application_details.permissions.organization', - key: ApplicationUserConsentScopeType.OrganizationScopes, - }, -}) satisfies { - [key in ApplicationUserConsentScopeType]: { - title: AdminConsoleKey; - key: key; - }; -}; diff --git a/packages/console/src/pages/ApplicationDetails/ApplicationDetailsContent/Permissions/ApplicationScopesAssignmentModal/index.tsx b/packages/console/src/pages/ApplicationDetails/ApplicationDetailsContent/Permissions/ApplicationScopesAssignmentModal/index.tsx deleted file mode 100644 index 4e87abfda18..00000000000 --- a/packages/console/src/pages/ApplicationDetails/ApplicationDetailsContent/Permissions/ApplicationScopesAssignmentModal/index.tsx +++ /dev/null @@ -1,114 +0,0 @@ -import { type AdminConsoleKey } from '@logto/phrases'; -import { ApplicationUserConsentScopeType } from '@logto/schemas'; -import { useCallback, useMemo } from 'react'; -import { useTranslation } from 'react-i18next'; - -import ConfirmModal from '@/ds-components/ConfirmModal'; -import DataTransferBox from '@/ds-components/DataTransferBox'; -import TabNav, { TabNavItem } from '@/ds-components/TabNav'; -import TabWrapper from '@/ds-components/TabWrapper'; - -import { permissionTabs } from './constants'; -import useApplicationScopesAssignment from './use-application-scopes-assignment'; - -const modalText = Object.freeze({ - title: 'application_details.permissions.table_name', - subtitle: 'application_details.permissions.permissions_assignment_description', - saveBtn: 'general.save', -}) satisfies Record; - -type Props = { - readonly isOpen: boolean; - readonly onClose: () => void; - readonly applicationId: string; -}; - -function ApplicationScopesAssignmentModal({ isOpen, onClose, applicationId }: Props) { - const { t } = useTranslation(undefined, { keyPrefix: 'admin_console' }); - - const { activeTab, setActiveTab, scopesAssignment, clearSelectedData, onSubmit, isLoading } = - useApplicationScopesAssignment(applicationId); - - const onCloseHandler = useCallback(() => { - onClose(); - clearSelectedData(); - setActiveTab(ApplicationUserConsentScopeType.UserScopes); - }, [clearSelectedData, onClose, setActiveTab]); - - const onSubmitHandler = useCallback(async () => { - await onSubmit(); - onCloseHandler(); - }, [onCloseHandler, onSubmit]); - - // If any of the tabs has selected scopes, the modal is dirty - const isDirty = Object.values(scopesAssignment).some( - ({ selectedData }) => selectedData.length > 0 - ); - - const tabs = useMemo( - () => - Object.values(permissionTabs) - /** - * Hide the organization resource scopes tab since the feature is not ready. - * We don't need the `isDevFeaturesEnabled` flag since the feature will change the UI. - * Todo @xiaoyijun Implement the new organization resource scopes feature. LOG-8823 - */ - .filter(({ key }) => key !== ApplicationUserConsentScopeType.OrganizationResourceScopes) - .map(({ title, key }) => { - const selectedDataCount = scopesAssignment[key].selectedData.length; - - return ( - { - setActiveTab(key); - }} - > - {`${t(title)}${selectedDataCount ? ` (${selectedDataCount})` : ''}`} - - ); - }), - [activeTab, scopesAssignment, setActiveTab, t] - ); - - return ( - - {tabs} - - - - - - - - - - - ); -} - -export default ApplicationScopesAssignmentModal; diff --git a/packages/console/src/pages/ApplicationDetails/ApplicationDetailsContent/Permissions/PermissionsCard/ApplicationScopesAssignmentModal/constants.ts b/packages/console/src/pages/ApplicationDetails/ApplicationDetailsContent/Permissions/PermissionsCard/ApplicationScopesAssignmentModal/constants.ts new file mode 100644 index 00000000000..3924688ecdc --- /dev/null +++ b/packages/console/src/pages/ApplicationDetails/ApplicationDetailsContent/Permissions/PermissionsCard/ApplicationScopesAssignmentModal/constants.ts @@ -0,0 +1,40 @@ +import { ApplicationUserConsentScopeType } from '@logto/schemas'; + +import { type PermissionTabType } from './type'; + +export const allLevelPermissionTabs: PermissionTabType = Object.freeze({ + [ApplicationUserConsentScopeType.UserScopes]: { + title: 'application_details.permissions.user_profile', + key: ApplicationUserConsentScopeType.UserScopes, + }, + [ApplicationUserConsentScopeType.ResourceScopes]: { + title: 'application_details.permissions.api_permissions', + key: ApplicationUserConsentScopeType.ResourceScopes, + }, + [ApplicationUserConsentScopeType.OrganizationScopes]: { + title: 'application_details.permissions.organization', + key: ApplicationUserConsentScopeType.OrganizationScopes, + }, +}); + +export const userLevelPermissionsTabs: PermissionTabType = Object.freeze({ + [ApplicationUserConsentScopeType.UserScopes]: { + title: 'application_details.permissions.user_profile', + key: ApplicationUserConsentScopeType.UserScopes, + }, + [ApplicationUserConsentScopeType.ResourceScopes]: { + title: 'application_details.permissions.api_permissions', + key: ApplicationUserConsentScopeType.ResourceScopes, + }, +}); + +export const organizationLevelPermissionsTab: PermissionTabType = Object.freeze({ + [ApplicationUserConsentScopeType.OrganizationScopes]: { + title: 'application_details.permissions.organization', + key: ApplicationUserConsentScopeType.OrganizationScopes, + }, + [ApplicationUserConsentScopeType.OrganizationResourceScopes]: { + title: 'application_details.permissions.api_permissions', + key: ApplicationUserConsentScopeType.OrganizationResourceScopes, + }, +}); diff --git a/packages/console/src/pages/ApplicationDetails/ApplicationDetailsContent/Permissions/PermissionsCard/ApplicationScopesAssignmentModal/index.tsx b/packages/console/src/pages/ApplicationDetails/ApplicationDetailsContent/Permissions/PermissionsCard/ApplicationScopesAssignmentModal/index.tsx new file mode 100644 index 00000000000..22e3cd71c4b --- /dev/null +++ b/packages/console/src/pages/ApplicationDetails/ApplicationDetailsContent/Permissions/PermissionsCard/ApplicationScopesAssignmentModal/index.tsx @@ -0,0 +1,160 @@ +import { type AdminConsoleKey } from '@logto/phrases'; +import { ApplicationUserConsentScopeType } from '@logto/schemas'; +import { useCallback, useMemo } from 'react'; +import { useTranslation } from 'react-i18next'; + +import ConfirmModal from '@/ds-components/ConfirmModal'; +import DataTransferBox from '@/ds-components/DataTransferBox'; +import TabNav, { TabNavItem } from '@/ds-components/TabNav'; +import TabWrapper from '@/ds-components/TabWrapper'; + +import { + allLevelPermissionTabs, + organizationLevelPermissionsTab, + userLevelPermissionsTabs, +} from './constants'; +import { ScopeLevel } from './type'; +import useApplicationScopesAssignment from './use-application-scopes-assignment'; + +type Props = { + readonly isOpen: boolean; + readonly onClose: () => void; + readonly applicationId: string; + readonly scopeLevel: ScopeLevel; +}; + +function ApplicationScopesAssignmentModal({ isOpen, onClose, applicationId, scopeLevel }: Props) { + const { t } = useTranslation(undefined, { keyPrefix: 'admin_console' }); + + const { activeTab, setActiveTab, scopesAssignment, clearSelectedData, onSubmit, isLoading } = + useApplicationScopesAssignment(applicationId, scopeLevel); + + const onCloseHandler = useCallback(() => { + onClose(); + clearSelectedData(); + setActiveTab( + scopeLevel === ScopeLevel.Organization + ? ApplicationUserConsentScopeType.OrganizationResourceScopes + : ApplicationUserConsentScopeType.UserScopes + ); + }, [clearSelectedData, onClose, scopeLevel, setActiveTab]); + + const onSubmitHandler = useCallback(async () => { + await onSubmit(); + onCloseHandler(); + }, [onCloseHandler, onSubmit]); + + // If any of the tabs has selected scopes, the modal is dirty + const isDirty = useMemo( + () => Object.values(scopesAssignment).some(({ selectedData }) => selectedData.length > 0), + [scopesAssignment] + ); + + const tabs = useMemo(() => { + const getPermissionTabs = () => { + if (scopeLevel === ScopeLevel.All) { + return allLevelPermissionTabs; + } + + return scopeLevel === ScopeLevel.User + ? userLevelPermissionsTabs + : organizationLevelPermissionsTab; + }; + + return Object.values(getPermissionTabs()).map(({ title, key }) => { + const selectedDataCount = scopesAssignment[key].selectedData.length; + + return ( + { + setActiveTab(key); + }} + > + {`${String(t(title))}${selectedDataCount ? ` (${selectedDataCount})` : ''}`} + + ); + }); + }, [activeTab, scopeLevel, scopesAssignment, setActiveTab, t]); + + const modalText = useMemo<{ + title: AdminConsoleKey; + subtitle: AdminConsoleKey; + saveButton: AdminConsoleKey; + }>(() => { + if (scopeLevel === ScopeLevel.All) { + return { + title: 'application_details.permissions.table_name', + subtitle: 'application_details.permissions.permissions_assignment_description', + saveButton: 'general.save', + }; + } + + const scopeLevelPhrase = scopeLevel === ScopeLevel.User ? 'user' : 'organization'; + + return { + title: `application_details.permissions.grant_${scopeLevelPhrase}_level_permissions`, + subtitle: `application_details.permissions.${scopeLevelPhrase}_description`, + saveButton: 'general.save', + }; + }, [scopeLevel]); + + return ( + + {tabs} + {(scopeLevel === ScopeLevel.All || scopeLevel === ScopeLevel.User) && ( + <> + + + + + + + + )} + {(scopeLevel === ScopeLevel.All || scopeLevel === ScopeLevel.Organization) && ( + + + + )} + {scopeLevel === ScopeLevel.Organization && ( + + + + )} + + ); +} + +export default ApplicationScopesAssignmentModal; diff --git a/packages/console/src/pages/ApplicationDetails/ApplicationDetailsContent/Permissions/ApplicationScopesAssignmentModal/type.ts b/packages/console/src/pages/ApplicationDetails/ApplicationDetailsContent/Permissions/PermissionsCard/ApplicationScopesAssignmentModal/type.ts similarity index 65% rename from packages/console/src/pages/ApplicationDetails/ApplicationDetailsContent/Permissions/ApplicationScopesAssignmentModal/type.ts rename to packages/console/src/pages/ApplicationDetails/ApplicationDetailsContent/Permissions/PermissionsCard/ApplicationScopesAssignmentModal/type.ts index 532cfe52f5c..8f033fcc0cd 100644 --- a/packages/console/src/pages/ApplicationDetails/ApplicationDetailsContent/Permissions/ApplicationScopesAssignmentModal/type.ts +++ b/packages/console/src/pages/ApplicationDetails/ApplicationDetailsContent/Permissions/PermissionsCard/ApplicationScopesAssignmentModal/type.ts @@ -1,4 +1,6 @@ +import { type AdminConsoleKey } from '@logto/phrases'; import { + type JsonObject, type ApplicationUserConsentScopesResponse, type ApplicationUserConsentScopeType, } from '@logto/schemas'; @@ -24,6 +26,25 @@ type CamelCase = T extends `${infer A}-${infer B}` ? `${A}${Capitalize = ( - assignedScopes?: ApplicationUserConsentScopesResponse[CamelCase] + assignedScopes?: ApplicationUserConsentScopesResponse[CamelCase], + options?: U ) => ScopeAssignmentHookReturnType; + +export enum ScopeLevel { + User = 'user', + Organization = 'organization', + /** + * Only used when the new organization resource scope feature is not ready. + * Todo @xiaoyijun remove this when the new organization resource scope feature is ready. + */ + All = 'all', +} + +export type PermissionTabType = Partial<{ + [Key in ApplicationUserConsentScopeType]: { + title: AdminConsoleKey; + key: Key; + }; +}>; diff --git a/packages/console/src/pages/ApplicationDetails/ApplicationDetailsContent/Permissions/ApplicationScopesAssignmentModal/use-application-scopes-assignment.ts b/packages/console/src/pages/ApplicationDetails/ApplicationDetailsContent/Permissions/PermissionsCard/ApplicationScopesAssignmentModal/use-application-scopes-assignment.ts similarity index 71% rename from packages/console/src/pages/ApplicationDetails/ApplicationDetailsContent/Permissions/ApplicationScopesAssignmentModal/use-application-scopes-assignment.ts rename to packages/console/src/pages/ApplicationDetails/ApplicationDetailsContent/Permissions/PermissionsCard/ApplicationScopesAssignmentModal/use-application-scopes-assignment.ts index 6f32c9dface..bae43407ee1 100644 --- a/packages/console/src/pages/ApplicationDetails/ApplicationDetailsContent/Permissions/ApplicationScopesAssignmentModal/use-application-scopes-assignment.ts +++ b/packages/console/src/pages/ApplicationDetails/ApplicationDetailsContent/Permissions/PermissionsCard/ApplicationScopesAssignmentModal/use-application-scopes-assignment.ts @@ -8,13 +8,16 @@ import useSWR from 'swr'; import useApi, { type RequestError } from '@/hooks/use-api'; +import { ScopeLevel } from './type'; import useOrganizationScopesAssignment from './use-organization-scopes-assignment'; import useResourceScopesAssignment from './use-resource-scopes-assignment'; import useUserScopesAssignment from './use-user-scopes-assignment'; -const useApplicationScopesAssignment = (applicationId: string) => { +const useApplicationScopesAssignment = (applicationId: string, scopeLevel: ScopeLevel) => { const [activeTab, setActiveTab] = useState( - ApplicationUserConsentScopeType.UserScopes + scopeLevel === ScopeLevel.Organization + ? ApplicationUserConsentScopeType.OrganizationScopes + : ApplicationUserConsentScopeType.UserScopes ); const [isLoading, setIsLoading] = useState(false); @@ -27,18 +30,31 @@ const useApplicationScopesAssignment = (applicationId: string) => { const userScopesAssignment = useUserScopesAssignment(data?.userScopes); const organizationScopesAssignment = useOrganizationScopesAssignment(data?.organizationScopes); const resourceScopesAssignment = useResourceScopesAssignment(data?.resourceScopes); + const organizationResourceScopesAssignment = useResourceScopesAssignment( + data?.organizationResourceScopes, + { isForOrganization: true } + ); const clearSelectedData = useCallback(() => { userScopesAssignment.setSelectedData([]); - organizationScopesAssignment.setSelectedData([]); resourceScopesAssignment.setSelectedData([]); - }, [organizationScopesAssignment, resourceScopesAssignment, userScopesAssignment]); + organizationScopesAssignment.setSelectedData([]); + organizationResourceScopesAssignment.setSelectedData([]); + }, [ + organizationResourceScopesAssignment, + organizationScopesAssignment, + resourceScopesAssignment, + userScopesAssignment, + ]); const onSubmit = useCallback(async () => { setIsLoading(true); const newUserScopes = userScopesAssignment.selectedData.map(({ id }) => id); const newOrganizationScopes = organizationScopesAssignment.selectedData.map(({ id }) => id); const newResourceScopes = resourceScopesAssignment.selectedData.map(({ id }) => id); + const newOrganizationResourceScopes = organizationResourceScopesAssignment.selectedData.map( + ({ id }) => id + ); await api .post(`api/applications/${applicationId}/user-consent-scopes`, { @@ -50,6 +66,11 @@ const useApplicationScopesAssignment = (applicationId: string) => { } ), ...conditional(newResourceScopes.length > 0 && { resourceScopes: newResourceScopes }), + ...conditional( + newOrganizationResourceScopes.length > 0 && { + organizationResourceScopes: newOrganizationResourceScopes, + } + ), }, }) .finally(() => { @@ -61,6 +82,7 @@ const useApplicationScopesAssignment = (applicationId: string) => { api, applicationId, mutate, + organizationResourceScopesAssignment.selectedData, organizationScopesAssignment.selectedData, resourceScopesAssignment.selectedData, userScopesAssignment.selectedData, @@ -70,12 +92,17 @@ const useApplicationScopesAssignment = (applicationId: string) => { const scopesAssignment = useMemo( () => ({ [ApplicationUserConsentScopeType.UserScopes]: userScopesAssignment, - [ApplicationUserConsentScopeType.OrganizationScopes]: organizationScopesAssignment, [ApplicationUserConsentScopeType.ResourceScopes]: resourceScopesAssignment, - // TODO @xiaoyijun: Replace with correct scopes - [ApplicationUserConsentScopeType.OrganizationResourceScopes]: resourceScopesAssignment, + [ApplicationUserConsentScopeType.OrganizationScopes]: organizationScopesAssignment, + [ApplicationUserConsentScopeType.OrganizationResourceScopes]: + organizationResourceScopesAssignment, }), - [organizationScopesAssignment, resourceScopesAssignment, userScopesAssignment] + [ + userScopesAssignment, + resourceScopesAssignment, + organizationScopesAssignment, + organizationResourceScopesAssignment, + ] ); return { diff --git a/packages/console/src/pages/ApplicationDetails/ApplicationDetailsContent/Permissions/ApplicationScopesAssignmentModal/use-organization-scopes-assignment.ts b/packages/console/src/pages/ApplicationDetails/ApplicationDetailsContent/Permissions/PermissionsCard/ApplicationScopesAssignmentModal/use-organization-scopes-assignment.ts similarity index 100% rename from packages/console/src/pages/ApplicationDetails/ApplicationDetailsContent/Permissions/ApplicationScopesAssignmentModal/use-organization-scopes-assignment.ts rename to packages/console/src/pages/ApplicationDetails/ApplicationDetailsContent/Permissions/PermissionsCard/ApplicationScopesAssignmentModal/use-organization-scopes-assignment.ts diff --git a/packages/console/src/pages/ApplicationDetails/ApplicationDetailsContent/Permissions/ApplicationScopesAssignmentModal/use-resource-scopes-assignment.ts b/packages/console/src/pages/ApplicationDetails/ApplicationDetailsContent/Permissions/PermissionsCard/ApplicationScopesAssignmentModal/use-resource-scopes-assignment.ts similarity index 72% rename from packages/console/src/pages/ApplicationDetails/ApplicationDetailsContent/Permissions/ApplicationScopesAssignmentModal/use-resource-scopes-assignment.ts rename to packages/console/src/pages/ApplicationDetails/ApplicationDetailsContent/Permissions/PermissionsCard/ApplicationScopesAssignmentModal/use-resource-scopes-assignment.ts index 508d6f520d5..9c158d09654 100644 --- a/packages/console/src/pages/ApplicationDetails/ApplicationDetailsContent/Permissions/ApplicationScopesAssignmentModal/use-resource-scopes-assignment.ts +++ b/packages/console/src/pages/ApplicationDetails/ApplicationDetailsContent/Permissions/PermissionsCard/ApplicationScopesAssignmentModal/use-resource-scopes-assignment.ts @@ -8,21 +8,30 @@ import { useState, useMemo } from 'react'; import useSWR from 'swr'; import { type RequestError } from '@/hooks/use-api'; +import { buildUrl } from '@/utils/url'; import { type ScopeAssignmentHook } from './type'; type HookType = ScopeAssignmentHook< - ApplicationUserConsentScopeType.ResourceScopes, - ApplicationUserConsentScopesResponse['resourceScopes'][number]['scopes'][number] + | ApplicationUserConsentScopeType.ResourceScopes + | ApplicationUserConsentScopeType.OrganizationResourceScopes, + ApplicationUserConsentScopesResponse['resourceScopes'][number]['scopes'][number], + { + /** Whether the assignment is for an organization */ + isForOrganization?: boolean; + } >; type SelectedDataType = ReturnType['selectedData'][number]; -const useResourceScopesAssignment: HookType = (assignedResourceScopes) => { +const useResourceScopesAssignment: HookType = (assignedResourceScopes, options) => { const [selectedData, setSelectedData] = useState([]); + const { isForOrganization } = options ?? {}; const { data: allResources } = useSWR( - 'api/resources?includeScopes=true' + buildUrl('api/resources', { + includeScopes: String(true), + }) ); const availableDataGroups = useMemo(() => { @@ -58,11 +67,17 @@ const useResourceScopesAssignment: HookType = (assignedResourceScopes) => { }, [allResources, assignedResourceScopes]); return { - scopeType: ApplicationUserConsentScopeType.ResourceScopes, + scopeType: isForOrganization + ? ApplicationUserConsentScopeType.OrganizationResourceScopes + : ApplicationUserConsentScopeType.ResourceScopes, selectedData, setSelectedData, availableDataGroups, - title: 'application_details.permissions.api_resource_permissions_assignment_form_title', + title: `application_details.permissions.${ + isForOrganization + ? 'add_permissions_for_organization' + : 'api_resource_permissions_assignment_form_title' + }`, }; }; diff --git a/packages/console/src/pages/ApplicationDetails/ApplicationDetailsContent/Permissions/ApplicationScopesAssignmentModal/use-user-scopes-assignment.ts b/packages/console/src/pages/ApplicationDetails/ApplicationDetailsContent/Permissions/PermissionsCard/ApplicationScopesAssignmentModal/use-user-scopes-assignment.ts similarity index 100% rename from packages/console/src/pages/ApplicationDetails/ApplicationDetailsContent/Permissions/ApplicationScopesAssignmentModal/use-user-scopes-assignment.ts rename to packages/console/src/pages/ApplicationDetails/ApplicationDetailsContent/Permissions/PermissionsCard/ApplicationScopesAssignmentModal/use-user-scopes-assignment.ts diff --git a/packages/console/src/pages/ApplicationDetails/ApplicationDetailsContent/Permissions/ApplicationScopesManagementModal/index.tsx b/packages/console/src/pages/ApplicationDetails/ApplicationDetailsContent/Permissions/PermissionsCard/ApplicationScopesManagementModal/index.tsx similarity index 100% rename from packages/console/src/pages/ApplicationDetails/ApplicationDetailsContent/Permissions/ApplicationScopesManagementModal/index.tsx rename to packages/console/src/pages/ApplicationDetails/ApplicationDetailsContent/Permissions/PermissionsCard/ApplicationScopesManagementModal/index.tsx diff --git a/packages/console/src/pages/ApplicationDetails/ApplicationDetailsContent/Permissions/PermissionsCard/index.module.scss b/packages/console/src/pages/ApplicationDetails/ApplicationDetailsContent/Permissions/PermissionsCard/index.module.scss new file mode 100644 index 00000000000..606d2eb9ddf --- /dev/null +++ b/packages/console/src/pages/ApplicationDetails/ApplicationDetailsContent/Permissions/PermissionsCard/index.module.scss @@ -0,0 +1,20 @@ +@use '@/scss/underscore' as _; + +// Override the Table component styles +.permissionsModal [class*='tableContainer'] [class*='bodyTable'] tr.sectionTitleRow { + height: _.unit(9); + + td { + font: var(--font-label-2); + color: var(--color-text-secondary); + background-color: var(--color-layer-light); + padding-top: _.unit(2); + padding-bottom: _.unit(2); + } +} + +.label { + display: flex; + gap: _.unit(1); + align-items: center; +} diff --git a/packages/console/src/pages/ApplicationDetails/ApplicationDetailsContent/Permissions/PermissionsCard/index.tsx b/packages/console/src/pages/ApplicationDetails/ApplicationDetailsContent/Permissions/PermissionsCard/index.tsx new file mode 100644 index 00000000000..a8ee174b4c7 --- /dev/null +++ b/packages/console/src/pages/ApplicationDetails/ApplicationDetailsContent/Permissions/PermissionsCard/index.tsx @@ -0,0 +1,179 @@ +import { type AdminConsoleKey } from '@logto/phrases'; +import { + ApplicationUserConsentScopeType, + type ApplicationUserConsentScopesResponse, +} from '@logto/schemas'; +import { conditional } from '@silverhand/essentials'; +import { useMemo, useState } from 'react'; +import { useTranslation } from 'react-i18next'; +import useSWR from 'swr'; + +import ActionsButton from '@/components/ActionsButton'; +import Breakable from '@/components/Breakable'; +import FormCard, { type Props as FormCardProps } from '@/components/FormCard'; +import TemplateTable from '@/components/TemplateTable'; +import { logtoThirdPartyAppPermissionsLink } from '@/consts'; +import Tag from '@/ds-components/Tag'; +import { type RequestError } from '@/hooks/use-api'; +import useDocumentationUrl from '@/hooks/use-documentation-url'; + +import ApplicationScopesAssignmentModal from './ApplicationScopesAssignmentModal'; +import { ScopeLevel } from './ApplicationScopesAssignmentModal/type'; +import ApplicationScopesManagementModal, { + type EditableScopeData, +} from './ApplicationScopesManagementModal'; +import * as styles from './index.module.scss'; +import useScopesTable from './use-scopes-table'; + +type Props = { + readonly applicationId: string; + readonly scopeLevel: ScopeLevel; +}; + +function PermissionsCard({ applicationId, scopeLevel }: Props) { + const { t } = useTranslation(undefined, { keyPrefix: 'admin_console' }); + const { getDocumentationUrl } = useDocumentationUrl(); + + const { data, error, mutate, isLoading } = useSWR< + ApplicationUserConsentScopesResponse, + RequestError + >(`api/applications/${applicationId}/user-consent-scopes`); + + const { parseRowGroup, deleteScope, editScope } = useScopesTable(); + + const [editScopeModalData, setEditScopeModalData] = useState(); + const [isAssignScopesModalOpen, setIsAssignScopesModalOpen] = useState(false); + + const rowGroups = useMemo(() => { + const { userLevelRowGroups, organizationLevelGroups } = parseRowGroup(data); + + if (scopeLevel === ScopeLevel.All) { + return [...userLevelRowGroups, ...organizationLevelGroups]; + } + + return scopeLevel === ScopeLevel.User ? userLevelRowGroups : organizationLevelGroups; + }, [data, parseRowGroup, scopeLevel]); + + const displayTextProps = useMemo<{ + formCard: Omit; + tableName: AdminConsoleKey; + }>(() => { + if (scopeLevel === ScopeLevel.All) { + return { + formCard: { + title: 'application_details.permissions.name', + description: 'application_details.permissions.description', + learnMoreLink: { + href: getDocumentationUrl(logtoThirdPartyAppPermissionsLink), + targetBlank: 'noopener', + }, + }, + tableName: 'application_details.permissions.table_name', + }; + } + + const scopeLevelPhrase = scopeLevel === ScopeLevel.User ? 'user' : 'organization'; + + return { + formCard: { + title: `application_details.permissions.${scopeLevelPhrase}_title`, + description: `application_details.permissions.${scopeLevelPhrase}_description`, + learnMoreLink: conditional( + scopeLevel === ScopeLevel.User && { + href: getDocumentationUrl(logtoThirdPartyAppPermissionsLink), + targetBlank: 'noopener', + } + ), + }, + tableName: `application_details.permissions.grant_${scopeLevelPhrase}_level_permissions`, + }; + }, [getDocumentationUrl, scopeLevel]); + + return ( + + ( + + {name} + + ), + }, + { + title: `${t('general.description')} (${t( + 'application_details.permissions.field_description' + )})`, + dataIndex: 'description', + colSpan: 5, + render: ({ description }) => {description ?? '-'}, + }, + { + title: null, + dataIndex: 'delete', + render: (data) => ( + { + setEditScopeModalData(data); + } + } + onDelete={async () => { + await deleteScope(data, applicationId); + void mutate(); + }} + /> + ), + }, + ]} + onAdd={() => { + setIsAssignScopesModalOpen(true); + }} + /> + {/* Render the permissions assignment modal only if the data is fetched properly */} + {data && ( + { + setIsAssignScopesModalOpen(false); + }} + /> + )} + {data && ( + { + setEditScopeModalData(undefined); + }} + onSubmit={async (scope) => { + await editScope(scope); + void mutate(); + setEditScopeModalData(undefined); + }} + /> + )} + + ); +} + +export default PermissionsCard; diff --git a/packages/console/src/pages/ApplicationDetails/ApplicationDetailsContent/Permissions/use-scopes-table.tsx b/packages/console/src/pages/ApplicationDetails/ApplicationDetailsContent/Permissions/PermissionsCard/use-scopes-table.tsx similarity index 71% rename from packages/console/src/pages/ApplicationDetails/ApplicationDetailsContent/Permissions/use-scopes-table.tsx rename to packages/console/src/pages/ApplicationDetails/ApplicationDetailsContent/Permissions/PermissionsCard/use-scopes-table.tsx index f4f6093b6e3..845661bee2c 100644 --- a/packages/console/src/pages/ApplicationDetails/ApplicationDetailsContent/Permissions/use-scopes-table.tsx +++ b/packages/console/src/pages/ApplicationDetails/ApplicationDetailsContent/Permissions/PermissionsCard/use-scopes-table.tsx @@ -4,10 +4,12 @@ import { type ApplicationUserConsentScopesResponse, ApplicationUserConsentScopeType, } from '@logto/schemas'; +import { condArray } from '@silverhand/essentials'; import { useCallback, type ReactNode } from 'react'; import { useTranslation } from 'react-i18next'; import Tip from '@/assets/icons/tip.svg'; +import { isDevFeaturesEnabled } from '@/consts/env'; import IconButton from '@/ds-components/IconButton'; import { ToggleTip } from '@/ds-components/Tip'; import useApi from '@/hooks/use-api'; @@ -26,7 +28,9 @@ type OrganizationScopeTableRowDataType = { } & ApplicationUserConsentScopesResponse['organizationScopes'][number]; type ResourceScopeTableRowDataType = { - type: ApplicationUserConsentScopeType.ResourceScopes; + type: + | ApplicationUserConsentScopeType.ResourceScopes + | ApplicationUserConsentScopeType.OrganizationResourceScopes; // Resource ID is required for resource scope patch request resourceId: string; resourceName: string; @@ -54,12 +58,20 @@ const useScopesTable = () => { const api = useApi(); const parseRowGroup = useCallback( - (data?: ApplicationUserConsentScopesResponse): ScopesTableRowGroupType[] => { + ( + data?: ApplicationUserConsentScopesResponse + ): { + userLevelRowGroups: ScopesTableRowGroupType[]; + organizationLevelGroups: ScopesTableRowGroupType[]; + } => { if (!data) { - return []; + return { + userLevelRowGroups: [], + organizationLevelGroups: [], + }; } - const { organizationScopes, userScopes, resourceScopes } = data; + const { userScopes, resourceScopes, organizationScopes, organizationResourceScopes } = data; const userScopesGroup: ScopesTableRowGroupType = { key: ApplicationUserConsentScopeType.UserScopes, @@ -85,6 +97,20 @@ const useScopesTable = () => { })), }; + const resourceScopesGroups = resourceScopes.map( + ({ resource, scopes }) => ({ + key: resource.indicator, + label: resource.name, + labelRowClassName: styles.sectionTitleRow, + data: scopes.map((scope) => ({ + type: ApplicationUserConsentScopeType.ResourceScopes, + ...scope, + resourceId: resource.id, + resourceName: resource.name, + })), + }) + ); + const organizationScopesGroup: ScopesTableRowGroupType = { key: ApplicationUserConsentScopeType.OrganizationScopes, label: t('application_details.permissions.organization_permissions'), @@ -95,27 +121,38 @@ const useScopesTable = () => { })), }; - const resourceScopesGroups = resourceScopes.map( - ({ resource, scopes }) => ({ + const organizationResourceScopesGroup = + organizationResourceScopes.map(({ resource, scopes }) => ({ key: resource.indicator, label: resource.name, labelRowClassName: styles.sectionTitleRow, data: scopes.map((scope) => ({ - type: ApplicationUserConsentScopeType.ResourceScopes, + type: ApplicationUserConsentScopeType.OrganizationResourceScopes, ...scope, resourceId: resource.id, resourceName: resource.name, })), - }) - ); - - return [ - // Hide the user scopes group if there is no user scopes - ...(userScopesGroup.data.length > 0 ? [userScopesGroup] : []), - ...resourceScopesGroups, - // Hide the organization scopes group if there is no organization scopes - ...(organizationScopesGroup.data.length > 0 ? [organizationScopesGroup] : []), - ]; + })); + + return { + userLevelRowGroups: [ + // Hide the user scopes group if there is no user scopes + ...(userScopesGroup.data.length > 0 ? [userScopesGroup] : []), + ...resourceScopesGroups, + ], + organizationLevelGroups: [ + // Hide the organization scopes group if there is no organization scopes + ...(organizationScopesGroup.data.length > 0 ? [organizationScopesGroup] : []), + ...condArray( + /** + * Hide the organization resource scopes group if the organization resource scopes feature is not ready + */ + isDevFeaturesEnabled && + organizationResourceScopesGroup.length > 0 && + organizationResourceScopesGroup + ), + ], + }; }, [experienceT, t] ); diff --git a/packages/console/src/pages/ApplicationDetails/ApplicationDetailsContent/Permissions/index.module.scss b/packages/console/src/pages/ApplicationDetails/ApplicationDetailsContent/Permissions/index.module.scss index 95ca3bed04f..ff6690197fb 100644 --- a/packages/console/src/pages/ApplicationDetails/ApplicationDetailsContent/Permissions/index.module.scss +++ b/packages/console/src/pages/ApplicationDetails/ApplicationDetailsContent/Permissions/index.module.scss @@ -1,21 +1,8 @@ @use '@/scss/underscore' as _; - -// Override the Table component styles -.permissionsModal [class*='tableContainer'] [class*='bodyTable'] tr.sectionTitleRow { - height: _.unit(9); - - td { - font: var(--font-label-2); - color: var(--color-text-secondary); - background-color: var(--color-layer-light); - padding-top: _.unit(2); - padding-bottom: _.unit(2); - } -} - -.label { +.container { display: flex; - gap: _.unit(1); - align-items: center; + flex-direction: column; + gap: _.unit(4); + padding-bottom: _.unit(6); } diff --git a/packages/console/src/pages/ApplicationDetails/ApplicationDetailsContent/Permissions/index.tsx b/packages/console/src/pages/ApplicationDetails/ApplicationDetailsContent/Permissions/index.tsx index 6836dacaace..7c3a711833d 100644 --- a/packages/console/src/pages/ApplicationDetails/ApplicationDetailsContent/Permissions/index.tsx +++ b/packages/console/src/pages/ApplicationDetails/ApplicationDetailsContent/Permissions/index.tsx @@ -1,140 +1,26 @@ -import { - type Application, - type ApplicationUserConsentScopesResponse, - ApplicationUserConsentScopeType, -} from '@logto/schemas'; -import { useMemo, useState } from 'react'; -import { useTranslation } from 'react-i18next'; -import useSWR from 'swr'; +import { type Application } from '@logto/schemas'; -import ActionsButton from '@/components/ActionsButton'; -import Breakable from '@/components/Breakable'; -import FormCard from '@/components/FormCard'; -import TemplateTable from '@/components/TemplateTable'; -import { logtoThirdPartyAppPermissionsLink } from '@/consts'; -import Tag from '@/ds-components/Tag'; -import { type RequestError } from '@/hooks/use-api'; -import useDocumentationUrl from '@/hooks/use-documentation-url'; +import { isDevFeaturesEnabled } from '@/consts/env'; -import ApplicationScopesAssignmentModal from './ApplicationScopesAssignmentModal'; -import ApplicationScopesManagementModal, { - type EditableScopeData, -} from './ApplicationScopesManagementModal'; +import PermissionsCard from './PermissionsCard'; +import { ScopeLevel } from './PermissionsCard/ApplicationScopesAssignmentModal/type'; import * as styles from './index.module.scss'; -import useScopesTable from './use-scopes-table'; type Props = { readonly application: Application; }; function Permissions({ application }: Props) { - const { t } = useTranslation(undefined, { keyPrefix: 'admin_console' }); - const { getDocumentationUrl } = useDocumentationUrl(); - - const [isAssignScopesModalOpen, setIsAssignScopesModalOpen] = useState(false); - const [editScopeModalData, setEditScopeModalData] = useState(); - - const { parseRowGroup, deleteScope, editScope } = useScopesTable(); - - const { data, error, mutate, isLoading } = useSWR< - ApplicationUserConsentScopesResponse, - RequestError - >(`api/applications/${application.id}/user-consent-scopes`); - - const rowGroups = useMemo(() => parseRowGroup(data), [data, parseRowGroup]); + const displayScopeLevels = isDevFeaturesEnabled + ? [ScopeLevel.User, ScopeLevel.Organization] + : [ScopeLevel.All]; return ( - <> - - ( - - {name} - - ), - }, - { - title: `${t('general.description')} (${t( - 'application_details.permissions.field_description' - )})`, - dataIndex: 'description', - colSpan: 5, - render: ({ description }) => {description ?? '-'}, - }, - { - title: null, - dataIndex: 'delete', - render: (data) => ( - { - setEditScopeModalData(data); - } - } - onDelete={async () => { - await deleteScope(data, application.id); - void mutate(); - }} - /> - ), - }, - ]} - onAdd={() => { - setIsAssignScopesModalOpen(true); - }} - /> - - {/* Render the permissions assignment modal only if the data is fetched properly */} - {data && ( - { - setIsAssignScopesModalOpen(false); - }} - /> - )} - {data && ( - { - setEditScopeModalData(undefined); - }} - onSubmit={async (scope) => { - await editScope(scope); - void mutate(); - setEditScopeModalData(undefined); - }} - /> - )} - +
+ {displayScopeLevels.map((scopeLevel) => ( + + ))} +
); } diff --git a/packages/phrases/src/locales/de/translation/admin-console/application-details.ts b/packages/phrases/src/locales/de/translation/admin-console/application-details.ts index 975b4ed8848..41f0f588aa0 100644 --- a/packages/phrases/src/locales/de/translation/admin-console/application-details.ts +++ b/packages/phrases/src/locales/de/translation/admin-console/application-details.ts @@ -156,9 +156,9 @@ const application_details = { /** UNTRANSLATED */ user_profile: 'User data', /** UNTRANSLATED */ - api_resource: 'API resource', + api_permissions: 'API permissions', /** UNTRANSLATED */ - organization: 'Organization', + organization: 'Organization permissions', /** UNTRANSLATED */ user_permissions_assignment_form_title: 'Add the user profile permissions', /** UNTRANSLATED */ @@ -171,6 +171,23 @@ const application_details = { /** UNTRANSLATED */ permission_description_tips: 'When Logto is used as an Identity Provider (IdP) for authentication in third-party apps, and users are asked for authorization, this description appears on the consent screen.', + /** UNTRANSLATED */ + user_title: 'User', + /** UNTRANSLATED */ + user_description: + 'Select the permissions requested by the third-party app for accessing specific user data.', + /** UNTRANSLATED */ + grant_user_level_permissions: 'Grant permissions of user data', + /** UNTRANSLATED */ + organization_title: 'Organization', + /** UNTRANSLATED */ + organization_description: + 'Select the permissions requested by the third-party app for accessing specific organization data.', + /** UNTRANSLATED */ + grant_organization_level_permissions: 'Grant permissions of organization data', + /** UNTRANSLATED */ + add_permissions_for_organization: + 'Add the API resource permissions used in the "Organization template"', }, roles: { name_column: 'Rolle', diff --git a/packages/phrases/src/locales/en/translation/admin-console/application-details.ts b/packages/phrases/src/locales/en/translation/admin-console/application-details.ts index de113eca775..19a64caaf05 100644 --- a/packages/phrases/src/locales/en/translation/admin-console/application-details.ts +++ b/packages/phrases/src/locales/en/translation/admin-console/application-details.ts @@ -111,8 +111,8 @@ const application_details = { permissions_assignment_description: 'Select the permissions the third-party application requests for user authorization to access specific data types.', user_profile: 'User data', - api_resource: 'API resource', - organization: 'Organization', + api_permissions: 'API permissions', + organization: 'Organization permissions', user_permissions_assignment_form_title: 'Add the user profile permissions', organization_permissions_assignment_form_title: 'Add the organization permissions', api_resource_permissions_assignment_form_title: 'Add the API resource permissions', @@ -120,6 +120,16 @@ const application_details = { 'You can modify the description of the personal user data permissions via "Sign-in Experience > Content > Manage Language"', permission_description_tips: 'When Logto is used as an Identity Provider (IdP) for authentication in third-party apps, and users are asked for authorization, this description appears on the consent screen.', + user_title: 'User', + user_description: + 'Select the permissions requested by the third-party app for accessing specific user data.', + grant_user_level_permissions: 'Grant permissions of user data', + organization_title: 'Organization', + organization_description: + 'Select the permissions requested by the third-party app for accessing specific organization data.', + grant_organization_level_permissions: 'Grant permissions of organization data', + add_permissions_for_organization: + 'Add the API resource permissions used in the "Organization template"', }, roles: { name_column: 'Role', diff --git a/packages/phrases/src/locales/es/translation/admin-console/application-details.ts b/packages/phrases/src/locales/es/translation/admin-console/application-details.ts index 3163190d8b1..db99d5c90dd 100644 --- a/packages/phrases/src/locales/es/translation/admin-console/application-details.ts +++ b/packages/phrases/src/locales/es/translation/admin-console/application-details.ts @@ -156,9 +156,9 @@ const application_details = { /** UNTRANSLATED */ user_profile: 'User data', /** UNTRANSLATED */ - api_resource: 'API resource', + api_permissions: 'API permissions', /** UNTRANSLATED */ - organization: 'Organization', + organization: 'Organization permissions', /** UNTRANSLATED */ user_permissions_assignment_form_title: 'Add the user profile permissions', /** UNTRANSLATED */ @@ -171,6 +171,23 @@ const application_details = { /** UNTRANSLATED */ permission_description_tips: 'When Logto is used as an Identity Provider (IdP) for authentication in third-party apps, and users are asked for authorization, this description appears on the consent screen.', + /** UNTRANSLATED */ + user_title: 'User', + /** UNTRANSLATED */ + user_description: + 'Select the permissions requested by the third-party app for accessing specific user data.', + /** UNTRANSLATED */ + grant_user_level_permissions: 'Grant permissions of user data', + /** UNTRANSLATED */ + organization_title: 'Organization', + /** UNTRANSLATED */ + organization_description: + 'Select the permissions requested by the third-party app for accessing specific organization data.', + /** UNTRANSLATED */ + grant_organization_level_permissions: 'Grant permissions of organization data', + /** UNTRANSLATED */ + add_permissions_for_organization: + 'Add the API resource permissions used in the "Organization template"', }, roles: { name_column: 'Rol', diff --git a/packages/phrases/src/locales/fr/translation/admin-console/application-details.ts b/packages/phrases/src/locales/fr/translation/admin-console/application-details.ts index c27f0d4d9a9..a2d5fa38235 100644 --- a/packages/phrases/src/locales/fr/translation/admin-console/application-details.ts +++ b/packages/phrases/src/locales/fr/translation/admin-console/application-details.ts @@ -156,9 +156,9 @@ const application_details = { /** UNTRANSLATED */ user_profile: 'User data', /** UNTRANSLATED */ - api_resource: 'API resource', + api_permissions: 'API permissions', /** UNTRANSLATED */ - organization: 'Organization', + organization: 'Organization permissions', /** UNTRANSLATED */ user_permissions_assignment_form_title: 'Add the user profile permissions', /** UNTRANSLATED */ @@ -171,6 +171,23 @@ const application_details = { /** UNTRANSLATED */ permission_description_tips: 'When Logto is used as an Identity Provider (IdP) for authentication in third-party apps, and users are asked for authorization, this description appears on the consent screen.', + /** UNTRANSLATED */ + user_title: 'User', + /** UNTRANSLATED */ + user_description: + 'Select the permissions requested by the third-party app for accessing specific user data.', + /** UNTRANSLATED */ + grant_user_level_permissions: 'Grant permissions of user data', + /** UNTRANSLATED */ + organization_title: 'Organization', + /** UNTRANSLATED */ + organization_description: + 'Select the permissions requested by the third-party app for accessing specific organization data.', + /** UNTRANSLATED */ + grant_organization_level_permissions: 'Grant permissions of organization data', + /** UNTRANSLATED */ + add_permissions_for_organization: + 'Add the API resource permissions used in the "Organization template"', }, roles: { name_column: 'Rôle', diff --git a/packages/phrases/src/locales/it/translation/admin-console/application-details.ts b/packages/phrases/src/locales/it/translation/admin-console/application-details.ts index 1800e5b85d4..db63e9c99e9 100644 --- a/packages/phrases/src/locales/it/translation/admin-console/application-details.ts +++ b/packages/phrases/src/locales/it/translation/admin-console/application-details.ts @@ -156,9 +156,9 @@ const application_details = { /** UNTRANSLATED */ user_profile: 'User data', /** UNTRANSLATED */ - api_resource: 'API resource', + api_permissions: 'API permissions', /** UNTRANSLATED */ - organization: 'Organization', + organization: 'Organization permissions', /** UNTRANSLATED */ user_permissions_assignment_form_title: 'Add the user profile permissions', /** UNTRANSLATED */ @@ -171,6 +171,23 @@ const application_details = { /** UNTRANSLATED */ permission_description_tips: 'When Logto is used as an Identity Provider (IdP) for authentication in third-party apps, and users are asked for authorization, this description appears on the consent screen.', + /** UNTRANSLATED */ + user_title: 'User', + /** UNTRANSLATED */ + user_description: + 'Select the permissions requested by the third-party app for accessing specific user data.', + /** UNTRANSLATED */ + grant_user_level_permissions: 'Grant permissions of user data', + /** UNTRANSLATED */ + organization_title: 'Organization', + /** UNTRANSLATED */ + organization_description: + 'Select the permissions requested by the third-party app for accessing specific organization data.', + /** UNTRANSLATED */ + grant_organization_level_permissions: 'Grant permissions of organization data', + /** UNTRANSLATED */ + add_permissions_for_organization: + 'Add the API resource permissions used in the "Organization template"', }, roles: { name_column: 'Ruolo', diff --git a/packages/phrases/src/locales/ja/translation/admin-console/application-details.ts b/packages/phrases/src/locales/ja/translation/admin-console/application-details.ts index fa99ad2691a..fea90741b13 100644 --- a/packages/phrases/src/locales/ja/translation/admin-console/application-details.ts +++ b/packages/phrases/src/locales/ja/translation/admin-console/application-details.ts @@ -156,9 +156,9 @@ const application_details = { /** UNTRANSLATED */ user_profile: 'User data', /** UNTRANSLATED */ - api_resource: 'API resource', + api_permissions: 'API permissions', /** UNTRANSLATED */ - organization: 'Organization', + organization: 'Organization permissions', /** UNTRANSLATED */ user_permissions_assignment_form_title: 'Add the user profile permissions', /** UNTRANSLATED */ @@ -171,6 +171,23 @@ const application_details = { /** UNTRANSLATED */ permission_description_tips: 'When Logto is used as an Identity Provider (IdP) for authentication in third-party apps, and users are asked for authorization, this description appears on the consent screen.', + /** UNTRANSLATED */ + user_title: 'User', + /** UNTRANSLATED */ + user_description: + 'Select the permissions requested by the third-party app for accessing specific user data.', + /** UNTRANSLATED */ + grant_user_level_permissions: 'Grant permissions of user data', + /** UNTRANSLATED */ + organization_title: 'Organization', + /** UNTRANSLATED */ + organization_description: + 'Select the permissions requested by the third-party app for accessing specific organization data.', + /** UNTRANSLATED */ + grant_organization_level_permissions: 'Grant permissions of organization data', + /** UNTRANSLATED */ + add_permissions_for_organization: + 'Add the API resource permissions used in the "Organization template"', }, roles: { name_column: '役割', diff --git a/packages/phrases/src/locales/ko/translation/admin-console/application-details.ts b/packages/phrases/src/locales/ko/translation/admin-console/application-details.ts index afdab6b1fd5..e2b739474d7 100644 --- a/packages/phrases/src/locales/ko/translation/admin-console/application-details.ts +++ b/packages/phrases/src/locales/ko/translation/admin-console/application-details.ts @@ -156,9 +156,9 @@ const application_details = { /** UNTRANSLATED */ user_profile: 'User data', /** UNTRANSLATED */ - api_resource: 'API resource', + api_permissions: 'API permissions', /** UNTRANSLATED */ - organization: 'Organization', + organization: 'Organization permissions', /** UNTRANSLATED */ user_permissions_assignment_form_title: 'Add the user profile permissions', /** UNTRANSLATED */ @@ -171,6 +171,23 @@ const application_details = { /** UNTRANSLATED */ permission_description_tips: 'When Logto is used as an Identity Provider (IdP) for authentication in third-party apps, and users are asked for authorization, this description appears on the consent screen.', + /** UNTRANSLATED */ + user_title: 'User', + /** UNTRANSLATED */ + user_description: + 'Select the permissions requested by the third-party app for accessing specific user data.', + /** UNTRANSLATED */ + grant_user_level_permissions: 'Grant permissions of user data', + /** UNTRANSLATED */ + organization_title: 'Organization', + /** UNTRANSLATED */ + organization_description: + 'Select the permissions requested by the third-party app for accessing specific organization data.', + /** UNTRANSLATED */ + grant_organization_level_permissions: 'Grant permissions of organization data', + /** UNTRANSLATED */ + add_permissions_for_organization: + 'Add the API resource permissions used in the "Organization template"', }, roles: { name_column: '역할', diff --git a/packages/phrases/src/locales/pl-pl/translation/admin-console/application-details.ts b/packages/phrases/src/locales/pl-pl/translation/admin-console/application-details.ts index 5109d54eb7c..806d17a3d98 100644 --- a/packages/phrases/src/locales/pl-pl/translation/admin-console/application-details.ts +++ b/packages/phrases/src/locales/pl-pl/translation/admin-console/application-details.ts @@ -156,9 +156,9 @@ const application_details = { /** UNTRANSLATED */ user_profile: 'User data', /** UNTRANSLATED */ - api_resource: 'API resource', + api_permissions: 'API permissions', /** UNTRANSLATED */ - organization: 'Organization', + organization: 'Organization permissions', /** UNTRANSLATED */ user_permissions_assignment_form_title: 'Add the user profile permissions', /** UNTRANSLATED */ @@ -171,6 +171,23 @@ const application_details = { /** UNTRANSLATED */ permission_description_tips: 'When Logto is used as an Identity Provider (IdP) for authentication in third-party apps, and users are asked for authorization, this description appears on the consent screen.', + /** UNTRANSLATED */ + user_title: 'User', + /** UNTRANSLATED */ + user_description: + 'Select the permissions requested by the third-party app for accessing specific user data.', + /** UNTRANSLATED */ + grant_user_level_permissions: 'Grant permissions of user data', + /** UNTRANSLATED */ + organization_title: 'Organization', + /** UNTRANSLATED */ + organization_description: + 'Select the permissions requested by the third-party app for accessing specific organization data.', + /** UNTRANSLATED */ + grant_organization_level_permissions: 'Grant permissions of organization data', + /** UNTRANSLATED */ + add_permissions_for_organization: + 'Add the API resource permissions used in the "Organization template"', }, roles: { name_column: 'Role', diff --git a/packages/phrases/src/locales/pt-br/translation/admin-console/application-details.ts b/packages/phrases/src/locales/pt-br/translation/admin-console/application-details.ts index 880a8c495e5..40a18966f26 100644 --- a/packages/phrases/src/locales/pt-br/translation/admin-console/application-details.ts +++ b/packages/phrases/src/locales/pt-br/translation/admin-console/application-details.ts @@ -156,9 +156,9 @@ const application_details = { /** UNTRANSLATED */ user_profile: 'User data', /** UNTRANSLATED */ - api_resource: 'API resource', + api_permissions: 'API permissions', /** UNTRANSLATED */ - organization: 'Organization', + organization: 'Organization permissions', /** UNTRANSLATED */ user_permissions_assignment_form_title: 'Add the user profile permissions', /** UNTRANSLATED */ @@ -171,6 +171,23 @@ const application_details = { /** UNTRANSLATED */ permission_description_tips: 'When Logto is used as an Identity Provider (IdP) for authentication in third-party apps, and users are asked for authorization, this description appears on the consent screen.', + /** UNTRANSLATED */ + user_title: 'User', + /** UNTRANSLATED */ + user_description: + 'Select the permissions requested by the third-party app for accessing specific user data.', + /** UNTRANSLATED */ + grant_user_level_permissions: 'Grant permissions of user data', + /** UNTRANSLATED */ + organization_title: 'Organization', + /** UNTRANSLATED */ + organization_description: + 'Select the permissions requested by the third-party app for accessing specific organization data.', + /** UNTRANSLATED */ + grant_organization_level_permissions: 'Grant permissions of organization data', + /** UNTRANSLATED */ + add_permissions_for_organization: + 'Add the API resource permissions used in the "Organization template"', }, roles: { name_column: 'Função', diff --git a/packages/phrases/src/locales/pt-pt/translation/admin-console/application-details.ts b/packages/phrases/src/locales/pt-pt/translation/admin-console/application-details.ts index a494b65ab30..324618e8926 100644 --- a/packages/phrases/src/locales/pt-pt/translation/admin-console/application-details.ts +++ b/packages/phrases/src/locales/pt-pt/translation/admin-console/application-details.ts @@ -156,9 +156,9 @@ const application_details = { /** UNTRANSLATED */ user_profile: 'User data', /** UNTRANSLATED */ - api_resource: 'API resource', + api_permissions: 'API permissions', /** UNTRANSLATED */ - organization: 'Organization', + organization: 'Organization permissions', /** UNTRANSLATED */ user_permissions_assignment_form_title: 'Add the user profile permissions', /** UNTRANSLATED */ @@ -171,6 +171,23 @@ const application_details = { /** UNTRANSLATED */ permission_description_tips: 'When Logto is used as an Identity Provider (IdP) for authentication in third-party apps, and users are asked for authorization, this description appears on the consent screen.', + /** UNTRANSLATED */ + user_title: 'User', + /** UNTRANSLATED */ + user_description: + 'Select the permissions requested by the third-party app for accessing specific user data.', + /** UNTRANSLATED */ + grant_user_level_permissions: 'Grant permissions of user data', + /** UNTRANSLATED */ + organization_title: 'Organization', + /** UNTRANSLATED */ + organization_description: + 'Select the permissions requested by the third-party app for accessing specific organization data.', + /** UNTRANSLATED */ + grant_organization_level_permissions: 'Grant permissions of organization data', + /** UNTRANSLATED */ + add_permissions_for_organization: + 'Add the API resource permissions used in the "Organization template"', }, roles: { name_column: 'Nome da função', diff --git a/packages/phrases/src/locales/ru/translation/admin-console/application-details.ts b/packages/phrases/src/locales/ru/translation/admin-console/application-details.ts index 2d17797ddaf..9c5d69eef7e 100644 --- a/packages/phrases/src/locales/ru/translation/admin-console/application-details.ts +++ b/packages/phrases/src/locales/ru/translation/admin-console/application-details.ts @@ -156,9 +156,9 @@ const application_details = { /** UNTRANSLATED */ user_profile: 'User data', /** UNTRANSLATED */ - api_resource: 'API resource', + api_permissions: 'API permissions', /** UNTRANSLATED */ - organization: 'Organization', + organization: 'Organization permissions', /** UNTRANSLATED */ user_permissions_assignment_form_title: 'Add the user profile permissions', /** UNTRANSLATED */ @@ -171,6 +171,23 @@ const application_details = { /** UNTRANSLATED */ permission_description_tips: 'When Logto is used as an Identity Provider (IdP) for authentication in third-party apps, and users are asked for authorization, this description appears on the consent screen.', + /** UNTRANSLATED */ + user_title: 'User', + /** UNTRANSLATED */ + user_description: + 'Select the permissions requested by the third-party app for accessing specific user data.', + /** UNTRANSLATED */ + grant_user_level_permissions: 'Grant permissions of user data', + /** UNTRANSLATED */ + organization_title: 'Organization', + /** UNTRANSLATED */ + organization_description: + 'Select the permissions requested by the third-party app for accessing specific organization data.', + /** UNTRANSLATED */ + grant_organization_level_permissions: 'Grant permissions of organization data', + /** UNTRANSLATED */ + add_permissions_for_organization: + 'Add the API resource permissions used in the "Organization template"', }, roles: { name_column: 'Роль', diff --git a/packages/phrases/src/locales/tr-tr/translation/admin-console/application-details.ts b/packages/phrases/src/locales/tr-tr/translation/admin-console/application-details.ts index 3207b3b62bf..8d0a8897647 100644 --- a/packages/phrases/src/locales/tr-tr/translation/admin-console/application-details.ts +++ b/packages/phrases/src/locales/tr-tr/translation/admin-console/application-details.ts @@ -156,9 +156,9 @@ const application_details = { /** UNTRANSLATED */ user_profile: 'User data', /** UNTRANSLATED */ - api_resource: 'API resource', + api_permissions: 'API permissions', /** UNTRANSLATED */ - organization: 'Organization', + organization: 'Organization permissions', /** UNTRANSLATED */ user_permissions_assignment_form_title: 'Add the user profile permissions', /** UNTRANSLATED */ @@ -171,6 +171,23 @@ const application_details = { /** UNTRANSLATED */ permission_description_tips: 'When Logto is used as an Identity Provider (IdP) for authentication in third-party apps, and users are asked for authorization, this description appears on the consent screen.', + /** UNTRANSLATED */ + user_title: 'User', + /** UNTRANSLATED */ + user_description: + 'Select the permissions requested by the third-party app for accessing specific user data.', + /** UNTRANSLATED */ + grant_user_level_permissions: 'Grant permissions of user data', + /** UNTRANSLATED */ + organization_title: 'Organization', + /** UNTRANSLATED */ + organization_description: + 'Select the permissions requested by the third-party app for accessing specific organization data.', + /** UNTRANSLATED */ + grant_organization_level_permissions: 'Grant permissions of organization data', + /** UNTRANSLATED */ + add_permissions_for_organization: + 'Add the API resource permissions used in the "Organization template"', }, roles: { name_column: 'Rol', diff --git a/packages/phrases/src/locales/zh-cn/translation/admin-console/application-details.ts b/packages/phrases/src/locales/zh-cn/translation/admin-console/application-details.ts index 7a7e91aebe8..eb488536a4f 100644 --- a/packages/phrases/src/locales/zh-cn/translation/admin-console/application-details.ts +++ b/packages/phrases/src/locales/zh-cn/translation/admin-console/application-details.ts @@ -154,9 +154,9 @@ const application_details = { /** UNTRANSLATED */ user_profile: 'User data', /** UNTRANSLATED */ - api_resource: 'API resource', + api_permissions: 'API permissions', /** UNTRANSLATED */ - organization: 'Organization', + organization: 'Organization permissions', /** UNTRANSLATED */ user_permissions_assignment_form_title: 'Add the user profile permissions', /** UNTRANSLATED */ @@ -169,6 +169,23 @@ const application_details = { /** UNTRANSLATED */ permission_description_tips: 'When Logto is used as an Identity Provider (IdP) for authentication in third-party apps, and users are asked for authorization, this description appears on the consent screen.', + /** UNTRANSLATED */ + user_title: 'User', + /** UNTRANSLATED */ + user_description: + 'Select the permissions requested by the third-party app for accessing specific user data.', + /** UNTRANSLATED */ + grant_user_level_permissions: 'Grant permissions of user data', + /** UNTRANSLATED */ + organization_title: 'Organization', + /** UNTRANSLATED */ + organization_description: + 'Select the permissions requested by the third-party app for accessing specific organization data.', + /** UNTRANSLATED */ + grant_organization_level_permissions: 'Grant permissions of organization data', + /** UNTRANSLATED */ + add_permissions_for_organization: + 'Add the API resource permissions used in the "Organization template"', }, roles: { name_column: '角色', diff --git a/packages/phrases/src/locales/zh-hk/translation/admin-console/application-details.ts b/packages/phrases/src/locales/zh-hk/translation/admin-console/application-details.ts index fc5d83eda49..28167217081 100644 --- a/packages/phrases/src/locales/zh-hk/translation/admin-console/application-details.ts +++ b/packages/phrases/src/locales/zh-hk/translation/admin-console/application-details.ts @@ -154,9 +154,9 @@ const application_details = { /** UNTRANSLATED */ user_profile: 'User data', /** UNTRANSLATED */ - api_resource: 'API resource', + api_permissions: 'API permissions', /** UNTRANSLATED */ - organization: 'Organization', + organization: 'Organization permissions', /** UNTRANSLATED */ user_permissions_assignment_form_title: 'Add the user profile permissions', /** UNTRANSLATED */ @@ -169,6 +169,23 @@ const application_details = { /** UNTRANSLATED */ permission_description_tips: 'When Logto is used as an Identity Provider (IdP) for authentication in third-party apps, and users are asked for authorization, this description appears on the consent screen.', + /** UNTRANSLATED */ + user_title: 'User', + /** UNTRANSLATED */ + user_description: + 'Select the permissions requested by the third-party app for accessing specific user data.', + /** UNTRANSLATED */ + grant_user_level_permissions: 'Grant permissions of user data', + /** UNTRANSLATED */ + organization_title: 'Organization', + /** UNTRANSLATED */ + organization_description: + 'Select the permissions requested by the third-party app for accessing specific organization data.', + /** UNTRANSLATED */ + grant_organization_level_permissions: 'Grant permissions of organization data', + /** UNTRANSLATED */ + add_permissions_for_organization: + 'Add the API resource permissions used in the "Organization template"', }, roles: { name_column: '角色', diff --git a/packages/phrases/src/locales/zh-tw/translation/admin-console/application-details.ts b/packages/phrases/src/locales/zh-tw/translation/admin-console/application-details.ts index a6adcb7c228..d8b31bc3a34 100644 --- a/packages/phrases/src/locales/zh-tw/translation/admin-console/application-details.ts +++ b/packages/phrases/src/locales/zh-tw/translation/admin-console/application-details.ts @@ -155,9 +155,9 @@ const application_details = { /** UNTRANSLATED */ user_profile: 'User data', /** UNTRANSLATED */ - api_resource: 'API resource', + api_permissions: 'API permissions', /** UNTRANSLATED */ - organization: 'Organization', + organization: 'Organization permissions', /** UNTRANSLATED */ user_permissions_assignment_form_title: 'Add the user profile permissions', /** UNTRANSLATED */ @@ -170,6 +170,23 @@ const application_details = { /** UNTRANSLATED */ permission_description_tips: 'When Logto is used as an Identity Provider (IdP) for authentication in third-party apps, and users are asked for authorization, this description appears on the consent screen.', + /** UNTRANSLATED */ + user_title: 'User', + /** UNTRANSLATED */ + user_description: + 'Select the permissions requested by the third-party app for accessing specific user data.', + /** UNTRANSLATED */ + grant_user_level_permissions: 'Grant permissions of user data', + /** UNTRANSLATED */ + organization_title: 'Organization', + /** UNTRANSLATED */ + organization_description: + 'Select the permissions requested by the third-party app for accessing specific organization data.', + /** UNTRANSLATED */ + grant_organization_level_permissions: 'Grant permissions of organization data', + /** UNTRANSLATED */ + add_permissions_for_organization: + 'Add the API resource permissions used in the "Organization template"', }, roles: { name_column: '角色', From ff65cfb75b83058c7549ef21013e28afb2ea1bbb Mon Sep 17 00:00:00 2001 From: Charles Zhao Date: Thu, 9 May 2024 19:16:26 +0800 Subject: [PATCH 358/687] fix(console): make profile a tenant independent page (#5687) * fix(console): make profile a tenant independent page * refactor(console): profile routes * chore(core): refactor later --- packages/console/src/cloud/AppRoutes.tsx | 13 +- .../Topbar/UserInfo/index.module.scss | 5 + .../src/components/Topbar/UserInfo/index.tsx | 15 ++- .../console/src/components/Topbar/index.tsx | 10 +- .../src/containers/ConsoleContent/index.tsx | 3 +- .../src/containers/ConsoleRoutes/index.tsx | 6 +- .../console/src/contexts/TenantsProvider.tsx | 1 + .../Uploader/FileUploader/index.tsx | 17 ++- .../Uploader/ImageUploaderField/index.tsx | 2 +- .../src/hooks/use-console-routes/index.tsx | 2 - .../use-console-routes/routes/profile.tsx | 17 +-- .../src/hooks/use-user-assets-service.ts | 25 +++- .../BasicUserInfoUpdateModal/index.tsx | 8 +- .../src/pages/Profile/index.module.scss | 49 +++++--- packages/console/src/pages/Profile/index.tsx | 114 ++++++++++-------- packages/core/src/routes-me/init.ts | 2 + packages/core/src/routes-me/user-assets.ts | 105 ++++++++++++++++ 17 files changed, 297 insertions(+), 97 deletions(-) create mode 100644 packages/core/src/routes-me/user-assets.ts diff --git a/packages/console/src/cloud/AppRoutes.tsx b/packages/console/src/cloud/AppRoutes.tsx index 3230e90cc91..d97f388c13c 100644 --- a/packages/console/src/cloud/AppRoutes.tsx +++ b/packages/console/src/cloud/AppRoutes.tsx @@ -1,11 +1,11 @@ import { Route, Routes } from 'react-router-dom'; -import { isCloud } from '@/consts/env'; import ProtectedRoutes from '@/containers/ProtectedRoutes'; import { GlobalAnonymousRoute, GlobalRoute } from '@/contexts/TenantsProvider'; import AcceptInvitation from '@/pages/AcceptInvitation'; import Callback from '@/pages/Callback'; import CheckoutSuccessCallback from '@/pages/CheckoutSuccessCallback'; +import Profile from '@/pages/Profile'; import * as styles from './AppRoutes.module.scss'; import Main from './pages/Main'; @@ -19,12 +19,11 @@ function AppRoutes() { } /> } /> }> - {isCloud && ( - } - /> - )} + } + /> + } /> } /> } /> diff --git a/packages/console/src/components/Topbar/UserInfo/index.module.scss b/packages/console/src/components/Topbar/UserInfo/index.module.scss index 489df1751f5..2d2582a0149 100644 --- a/packages/console/src/components/Topbar/UserInfo/index.module.scss +++ b/packages/console/src/components/Topbar/UserInfo/index.module.scss @@ -48,6 +48,11 @@ } .icon { + display: flex; + align-items: center; + justify-content: center; + width: 20px; + height: 20px; color: var(--color-text-secondary); } diff --git a/packages/console/src/components/Topbar/UserInfo/index.tsx b/packages/console/src/components/Topbar/UserInfo/index.tsx index 7dd2a1c25a6..67dd709a2a9 100644 --- a/packages/console/src/components/Topbar/UserInfo/index.tsx +++ b/packages/console/src/components/Topbar/UserInfo/index.tsx @@ -5,12 +5,14 @@ import classNames from 'classnames'; import { useRef, useState } from 'react'; import { useTranslation } from 'react-i18next'; +import ExternalLinkIcon from '@/assets/icons/external-link.svg'; import Globe from '@/assets/icons/globe.svg'; import Palette from '@/assets/icons/palette.svg'; import Profile from '@/assets/icons/profile.svg'; import SignOut from '@/assets/icons/sign-out.svg'; import UserAvatar from '@/components/UserAvatar'; import UserInfoCard from '@/components/UserInfoCard'; +import { isCloud } from '@/consts/env'; import Divider from '@/ds-components/Divider'; import Dropdown, { DropdownItem } from '@/ds-components/Dropdown'; import Spacer from '@/ds-components/Spacer'; @@ -28,7 +30,7 @@ import * as styles from './index.module.scss'; function UserInfo() { const { signOut } = useLogto(); - const { navigate } = useTenantPathname(); + const { getUrl } = useTenantPathname(); const { t } = useTranslation(undefined, { keyPrefix: 'admin_console' }); const { user, isLoading: isLoadingUser } = useCurrentUser(); const anchorRef = useRef(null); @@ -77,10 +79,19 @@ function UserInfo() { className={classNames(styles.dropdownItem, isLoading && styles.loading)} icon={} onClick={() => { - navigate('/profile'); + // In OSS version, there will be a `/console` context path in the URL. + const profileRouteWithConsoleContext = getUrl('/profile'); + + // Open the profile page in a new tab. In Logto Cloud, the profile page is not nested in the tenant independent, + // whereas in OSS version, it is under the `/console` context path. + window.open(isCloud ? '/profile' : profileRouteWithConsoleContext, '_blank'); }} > {t('menu.profile')} + +
+ +
- {isCloud && } - {!isCloud && ( + {isCloud && !hideTenantSelector && } + {!isCloud && !hideTitle && ( <>
{t('title')}
diff --git a/packages/console/src/containers/ConsoleContent/index.tsx b/packages/console/src/containers/ConsoleContent/index.tsx index 651982374c6..f1ae1cd5003 100644 --- a/packages/console/src/containers/ConsoleContent/index.tsx +++ b/packages/console/src/containers/ConsoleContent/index.tsx @@ -14,9 +14,10 @@ function ConsoleContent() { const { scrollableContent } = useOutletContext(); const routeObjects = useConsoleRoutes(); const routes = useRoutes(routeObjects); + usePlausiblePageview(routeObjects); + // Use this hook here to make sure console listens to user tenant scope changes. useTenantScopeListener(); - usePlausiblePageview(routeObjects); return (
diff --git a/packages/console/src/containers/ConsoleRoutes/index.tsx b/packages/console/src/containers/ConsoleRoutes/index.tsx index 9dbb4d7df0c..45c0da00a05 100644 --- a/packages/console/src/containers/ConsoleRoutes/index.tsx +++ b/packages/console/src/containers/ConsoleRoutes/index.tsx @@ -8,11 +8,12 @@ import AppContent, { RedirectToFirstItem } from '@/containers/AppContent'; import ConsoleContent from '@/containers/ConsoleContent'; import ProtectedRoutes from '@/containers/ProtectedRoutes'; import TenantAccess from '@/containers/TenantAccess'; -import { GlobalRoute } from '@/contexts/TenantsProvider'; +import { GlobalAnonymousRoute, GlobalRoute } from '@/contexts/TenantsProvider'; import Toast from '@/ds-components/Toast'; import useSwrOptions from '@/hooks/use-swr-options'; import Callback from '@/pages/Callback'; import CheckoutSuccessCallback from '@/pages/CheckoutSuccessCallback'; +import Profile from '@/pages/Profile'; import HandleSocialCallback from '@/pages/Profile/containers/HandleSocialCallback'; import Welcome from '@/pages/Welcome'; import { dropLeadingSlash } from '@/utils/url'; @@ -39,6 +40,9 @@ export function ConsoleRoutes() { * console path to trigger the console routes. */} {!isCloud && } />} + {!isCloud && ( + } /> + )} }> } /> } /> diff --git a/packages/console/src/contexts/TenantsProvider.tsx b/packages/console/src/contexts/TenantsProvider.tsx index 641e473ef6a..eca1189c936 100644 --- a/packages/console/src/contexts/TenantsProvider.tsx +++ b/packages/console/src/contexts/TenantsProvider.tsx @@ -21,6 +21,7 @@ import { isCloud } from '@/consts/env'; export enum GlobalAnonymousRoute { Callback = '/callback', SocialDemoCallback = '/social-demo-callback', + Profile = '/profile', } /** diff --git a/packages/console/src/ds-components/Uploader/FileUploader/index.tsx b/packages/console/src/ds-components/Uploader/FileUploader/index.tsx index bab632a0e5f..edafb2d325d 100644 --- a/packages/console/src/ds-components/Uploader/FileUploader/index.tsx +++ b/packages/console/src/ds-components/Uploader/FileUploader/index.tsx @@ -1,6 +1,7 @@ import type { AllowedUploadMimeType, UserAssets } from '@logto/schemas'; import { maxUploadFileSize } from '@logto/schemas'; import classNames from 'classnames'; +import { type KyInstance } from 'ky'; import { useCallback, useEffect, useState } from 'react'; import { type FileRejection, useDropzone } from 'react-dropzone'; import { useTranslation } from 'react-i18next'; @@ -20,6 +21,15 @@ export type Props = { readonly onCompleted: (fileUrl: string) => void; readonly onUploadErrorChange: (errorMessage?: string) => void; readonly className?: string; + /** + * Specify which API instance to use for the upload request. For example, you can use admin tenant API instead. + * Defaults to the return value of `useApi()`. + */ + readonly apiInstance?: KyInstance; + /** + * Specify the URL to upload the file to. Defaults to `api/user-assets`. + */ + readonly uploadUrl?: string; }; function FileUploader({ @@ -29,6 +39,8 @@ function FileUploader({ onCompleted, onUploadErrorChange, className, + apiInstance, + uploadUrl = 'api/user-assets', }: Props) { const { t } = useTranslation(undefined, { keyPrefix: 'admin_console' }); const [isUploading, setIsUploading] = useState(false); @@ -91,7 +103,8 @@ function FileUploader({ try { setIsUploading(true); - const { url } = await api.post('api/user-assets', { body: formData }).json(); + const uploadApi = apiInstance ?? api; + const { url } = await uploadApi.post(uploadUrl, { body: formData }).json(); onCompleted(url); } catch { @@ -100,7 +113,7 @@ function FileUploader({ setIsUploading(false); } }, - [allowedMimeTypes, api, maxSize, onCompleted, t] + [api, apiInstance, allowedMimeTypes, maxSize, onCompleted, t, uploadUrl] ); const { getRootProps, getInputProps, isDragActive } = useDropzone({ diff --git a/packages/console/src/ds-components/Uploader/ImageUploaderField/index.tsx b/packages/console/src/ds-components/Uploader/ImageUploaderField/index.tsx index 02d079289f7..faaccc9ce62 100644 --- a/packages/console/src/ds-components/Uploader/ImageUploaderField/index.tsx +++ b/packages/console/src/ds-components/Uploader/ImageUploaderField/index.tsx @@ -9,7 +9,7 @@ import type { Props as ImageUploaderProps } from '../ImageUploader'; import * as styles from './index.module.scss'; -type Props = Pick & { +type Props = Omit & { readonly onChange: (value: string) => void; readonly allowedMimeTypes?: UserAssetsServiceStatus['allowUploadMimeTypes']; }; diff --git a/packages/console/src/hooks/use-console-routes/index.tsx b/packages/console/src/hooks/use-console-routes/index.tsx index 9739b14c4b2..92277b99fb7 100644 --- a/packages/console/src/hooks/use-console-routes/index.tsx +++ b/packages/console/src/hooks/use-console-routes/index.tsx @@ -23,7 +23,6 @@ import { customizeJwt } from './routes/customize-jwt'; import { enterpriseSso } from './routes/enterprise-sso'; import { organizationTemplate } from './routes/organization-template'; import { organizations } from './routes/organizations'; -import { profile } from './routes/profile'; import { roles } from './routes/roles'; import { signInExperience } from './routes/sign-in-experience'; import { useTenantSettings } from './routes/tenant-settings'; @@ -62,7 +61,6 @@ export const useConsoleRoutes = () => { { path: steps.organizationInfo, element: }, ], }, - profile, { path: 'signing-keys', element: }, isCloud && tenantSettings, isCloud && customizeJwt diff --git a/packages/console/src/hooks/use-console-routes/routes/profile.tsx b/packages/console/src/hooks/use-console-routes/routes/profile.tsx index a1644479ecc..f4bb0268f08 100644 --- a/packages/console/src/hooks/use-console-routes/routes/profile.tsx +++ b/packages/console/src/hooks/use-console-routes/routes/profile.tsx @@ -1,18 +1,13 @@ import { type RouteObject } from 'react-router-dom'; -import Profile from '@/pages/Profile'; import ChangePasswordModal from '@/pages/Profile/containers/ChangePasswordModal'; import LinkEmailModal from '@/pages/Profile/containers/LinkEmailModal'; import VerificationCodeModal from '@/pages/Profile/containers/VerificationCodeModal'; import VerifyPasswordModal from '@/pages/Profile/containers/VerifyPasswordModal'; -export const profile: RouteObject = { - path: 'profile', - children: [ - { index: true, element: }, - { path: 'verify-password', element: }, - { path: 'change-password', element: }, - { path: 'link-email', element: }, - { path: 'verification-code', element: }, - ], -}; +export const profile: RouteObject[] = [ + { path: 'verify-password', element: }, + { path: 'change-password', element: }, + { path: 'link-email', element: }, + { path: 'verification-code', element: }, +]; diff --git a/packages/console/src/hooks/use-user-assets-service.ts b/packages/console/src/hooks/use-user-assets-service.ts index e781ff149d8..ff4a39bad48 100644 --- a/packages/console/src/hooks/use-user-assets-service.ts +++ b/packages/console/src/hooks/use-user-assets-service.ts @@ -1,11 +1,30 @@ -import type { UserAssetsServiceStatus } from '@logto/schemas'; +import { type UserAssetsServiceStatus } from '@logto/schemas'; +import { useLocation } from 'react-router-dom'; import useSWRImmutable from 'swr/immutable'; -import type { RequestError } from './use-api'; +import { adminTenantEndpoint, meApi } from '@/consts'; +import { isCloud } from '@/consts/env'; +import { GlobalAnonymousRoute } from '@/contexts/TenantsProvider'; + +import useApi, { useStaticApi, type RequestError } from './use-api'; +import useSwrFetcher from './use-swr-fetcher'; const useUserAssetsService = () => { + const adminApi = useStaticApi({ + prefixUrl: adminTenantEndpoint, + resourceIndicator: meApi.indicator, + }); + const api = useApi(); + const { pathname } = useLocation(); + const isProfilePage = + pathname === GlobalAnonymousRoute.Profile || + pathname.startsWith(GlobalAnonymousRoute.Profile + '/'); + const shouldUseAdminApi = isCloud && isProfilePage; + + const fetcher = useSwrFetcher(shouldUseAdminApi ? adminApi : api); const { data, error } = useSWRImmutable( - 'api/user-assets/service-status' + `${shouldUseAdminApi ? 'me' : 'api'}/user-assets/service-status`, + fetcher ); return { diff --git a/packages/console/src/pages/Profile/containers/BasicUserInfoUpdateModal/index.tsx b/packages/console/src/pages/Profile/containers/BasicUserInfoUpdateModal/index.tsx index 4f0e5b157c0..74b93ffb424 100644 --- a/packages/console/src/pages/Profile/containers/BasicUserInfoUpdateModal/index.tsx +++ b/packages/console/src/pages/Profile/containers/BasicUserInfoUpdateModal/index.tsx @@ -130,7 +130,13 @@ function BasicUserInfoUpdateModal({ field, value: initialValue, isOpen, onClose name="avatar" control={control} render={({ field: { onChange, value, name } }) => ( - + )} /> ) : ( diff --git a/packages/console/src/pages/Profile/index.module.scss b/packages/console/src/pages/Profile/index.module.scss index 5a963e324d7..26226a6afcd 100644 --- a/packages/console/src/pages/Profile/index.module.scss +++ b/packages/console/src/pages/Profile/index.module.scss @@ -1,24 +1,43 @@ @use '@/scss/underscore' as _; -.content { - margin-top: _.unit(4); - padding-bottom: _.unit(6); +.pageContainer { + position: absolute; + inset: 0; + display: flex; + flex-direction: column; + height: 100%; + + .scrollable { + width: 100%; + } + + .wrapper { + @include _.main-content-width; + width: 100%; + padding: _.unit(3) _.unit(6) 0; + } - > div + div { + .content { + width: 100%; margin-top: _.unit(4); + padding-bottom: _.unit(6); + + > div + div { + margin-top: _.unit(4); + } } -} -.deleteAccount { - flex: 1; - display: flex; - align-items: center; - border: 1px solid var(--color-divider); - border-radius: 8px; - padding: _.unit(4); + .deleteAccount { + flex: 1; + display: flex; + align-items: center; + border: 1px solid var(--color-divider); + border-radius: 8px; + padding: _.unit(4); - .description { - font: var(--font-body-2); - margin-right: _.unit(2); + .description { + font: var(--font-body-2); + margin-right: _.unit(2); + } } } diff --git a/packages/console/src/pages/Profile/index.tsx b/packages/console/src/pages/Profile/index.tsx index afc6d451d6d..8d3a68116d1 100644 --- a/packages/console/src/pages/Profile/index.tsx +++ b/packages/console/src/pages/Profile/index.tsx @@ -1,17 +1,22 @@ import type { ConnectorResponse } from '@logto/schemas'; import { useState } from 'react'; import { useTranslation } from 'react-i18next'; +import { useRoutes } from 'react-router-dom'; import useSWRImmutable from 'swr/immutable'; import FormCard from '@/components/FormCard'; import PageMeta from '@/components/PageMeta'; +import Topbar from '@/components/Topbar'; import { adminTenantEndpoint, meApi } from '@/consts'; import { isCloud } from '@/consts/env'; import Button from '@/ds-components/Button'; import CardTitle from '@/ds-components/CardTitle'; +import OverlayScrollbar from '@/ds-components/OverlayScrollbar'; import type { RequestError } from '@/hooks/use-api'; import { useStaticApi } from '@/hooks/use-api'; +import { profile } from '@/hooks/use-console-routes/routes/profile'; import useCurrentUser from '@/hooks/use-current-user'; +import { usePlausiblePageview } from '@/hooks/use-plausible-pageview'; import useSwrFetcher from '@/hooks/use-swr-fetcher'; import useTenantPathname from '@/hooks/use-tenant-pathname'; import useUserAssetsService from '@/hooks/use-user-assets-service'; @@ -28,6 +33,9 @@ import * as styles from './index.module.scss'; function Profile() { const { t } = useTranslation(undefined, { keyPrefix: 'admin_console' }); const { navigate } = useTenantPathname(); + const childrenRoutes = useRoutes(profile); + usePlausiblePageview(profile); + const api = useStaticApi({ prefixUrl: adminTenantEndpoint, resourceIndicator: meApi.indicator }); const fetcher = useSwrFetcher(api); const { data: connectors, error: fetchConnectorsError } = useSWRImmutable< @@ -42,58 +50,68 @@ function Profile() { const showLoadingSkeleton = isLoadingUser || isLoadingConnectors || isUserAssetServiceLoading; return ( -
- -
- -
- {showLoadingSkeleton && } - {user && !showLoadingSkeleton && ( -
- - {isCloud && } - - (value ? ******** : ), - action: { - name: 'profile.change', - handler: () => { - navigate(user.hasPassword ? 'verify-password' : 'change-password', { - state: { email: user.primaryEmail, action: 'changePassword' }, - }); +
+ + +
+ +
+ +
+ {showLoadingSkeleton && } + {user && !showLoadingSkeleton && ( +
+ + {isCloud && ( + + )} + + (value ? ******** : ), + action: { + name: 'profile.change', + handler: () => { + navigate(user.hasPassword ? 'verify-password' : 'change-password', { + state: { email: user.primaryEmail, action: 'changePassword' }, + }); + }, + }, }, - }, - }, - ]} - /> - - {isCloud && ( - -
-
{t('profile.delete_account.description')}
-
- { - setShowDeleteAccountModal(false); - }} - /> -
+ + {isCloud && ( + +
+
+ {t('profile.delete_account.description')} +
+
+ { + setShowDeleteAccountModal(false); + }} + /> +
+ )} +
)}
- )} +
+ {childrenRoutes}
); } diff --git a/packages/core/src/routes-me/init.ts b/packages/core/src/routes-me/init.ts index bff084f08df..a689b69727a 100644 --- a/packages/core/src/routes-me/init.ts +++ b/packages/core/src/routes-me/init.ts @@ -11,6 +11,7 @@ import type TenantContext from '#src/tenants/TenantContext.js'; import assertThat from '#src/utils/assert-that.js'; import socialRoutes from './social.js'; +import userAssetsRoutes from './user-assets.js'; import userRoutes from './user.js'; import verificationCodeRoutes from './verification-code.js'; @@ -36,6 +37,7 @@ export default function initMeApis(tenant: TenantContext): Koa { userRoutes(meRouter, tenant); socialRoutes(meRouter, tenant); verificationCodeRoutes(meRouter, tenant); + userAssetsRoutes(meRouter, tenant); const meApp = new Koa(); meApp.use(koaCors(EnvSet.values.cloudUrlSet)); diff --git a/packages/core/src/routes-me/user-assets.ts b/packages/core/src/routes-me/user-assets.ts new file mode 100644 index 00000000000..c0139f51bc6 --- /dev/null +++ b/packages/core/src/routes-me/user-assets.ts @@ -0,0 +1,105 @@ +import { readFile } from 'node:fs/promises'; + +import { consoleLog } from '@logto/cli/lib/utils.js'; +import { + userAssetsServiceStatusGuard, + allowUploadMimeTypes, + maxUploadFileSize, + type UserAssets, + userAssetsGuard, + adminTenantId, +} from '@logto/schemas'; +import { generateStandardId } from '@logto/shared'; +import { format } from 'date-fns'; +import { object } from 'zod'; + +import RequestError from '#src/errors/RequestError/index.js'; +import koaGuard from '#src/middleware/koa-guard.js'; +import type { RouterInitArgs } from '#src/routes/types.js'; +import SystemContext from '#src/tenants/SystemContext.js'; +import assertThat from '#src/utils/assert-that.js'; +import { uploadFileGuard } from '#src/utils/storage/consts.js'; +import { buildUploadFile } from '#src/utils/storage/index.js'; + +import type { AuthedMeRouter } from './types.js'; + +/** + * Duplicated from `/user-assets` management API and used specifically for admin tenant. + * E.g. Profile avatar upload. + * + * @todo: Refactor to reuse as much code as possible. @Charles + */ +export default function userAssetsRoutes(...[router]: RouterInitArgs) { + router.get( + '/user-assets/service-status', + koaGuard({ + response: userAssetsServiceStatusGuard, + }), + async (ctx, next) => { + const { storageProviderConfig } = SystemContext.shared; + const status = storageProviderConfig + ? { + status: 'ready', + allowUploadMimeTypes, + maxUploadFileSize, + } + : { + status: 'not_configured', + }; + + ctx.body = status; + + return next(); + } + ); + + router.post( + '/user-assets', + koaGuard({ + files: object({ + file: uploadFileGuard, + }), + response: userAssetsGuard, + }), + async (ctx, next) => { + const { file } = ctx.guard.files; + + assertThat(file.size <= maxUploadFileSize, 'guard.file_size_exceeded'); + assertThat( + allowUploadMimeTypes.map(String).includes(file.mimetype), + 'guard.mime_type_not_allowed' + ); + + const { storageProviderConfig } = SystemContext.shared; + assertThat(storageProviderConfig, 'storage.not_configured'); + + const userId = ctx.auth.id; + const uploadFile = buildUploadFile(storageProviderConfig); + const objectKey = `${adminTenantId}/${userId}/${format( + new Date(), + 'yyyy/MM/dd' + )}/${generateStandardId(8)}/${file.originalFilename}`; + + try { + const { url } = await uploadFile(await readFile(file.filepath), objectKey, { + contentType: file.mimetype, + publicUrl: storageProviderConfig.publicUrl, + }); + + const result: UserAssets = { + url, + }; + + ctx.body = result; + } catch (error: unknown) { + consoleLog.error(error); + throw new RequestError({ + code: 'storage.upload_error', + status: 500, + }); + } + + return next(); + } + ); +} From 50f336c7d35e27066931916ad2dc16d98b5cb768 Mon Sep 17 00:00:00 2001 From: Xiao Yijun Date: Fri, 10 May 2024 10:08:56 +0800 Subject: [PATCH 359/687] fix(console): focus on org socpes tab on app scopes modal reopened (#5839) --- .../PermissionsCard/ApplicationScopesAssignmentModal/index.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/console/src/pages/ApplicationDetails/ApplicationDetailsContent/Permissions/PermissionsCard/ApplicationScopesAssignmentModal/index.tsx b/packages/console/src/pages/ApplicationDetails/ApplicationDetailsContent/Permissions/PermissionsCard/ApplicationScopesAssignmentModal/index.tsx index 22e3cd71c4b..6d01bc65608 100644 --- a/packages/console/src/pages/ApplicationDetails/ApplicationDetailsContent/Permissions/PermissionsCard/ApplicationScopesAssignmentModal/index.tsx +++ b/packages/console/src/pages/ApplicationDetails/ApplicationDetailsContent/Permissions/PermissionsCard/ApplicationScopesAssignmentModal/index.tsx @@ -34,7 +34,7 @@ function ApplicationScopesAssignmentModal({ isOpen, onClose, applicationId, scop clearSelectedData(); setActiveTab( scopeLevel === ScopeLevel.Organization - ? ApplicationUserConsentScopeType.OrganizationResourceScopes + ? ApplicationUserConsentScopeType.OrganizationScopes : ApplicationUserConsentScopeType.UserScopes ); }, [clearSelectedData, onClose, scopeLevel, setActiveTab]); From feae37b9b187fe0e617cddc09e7313fc1723f12f Mon Sep 17 00:00:00 2001 From: Charles Zhao Date: Fri, 10 May 2024 10:53:22 +0800 Subject: [PATCH 360/687] fix(console): fix the link social feature on logto cloud (#5838) --- .../pages/Profile/components/LinkAccountSection/index.tsx | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/packages/console/src/pages/Profile/components/LinkAccountSection/index.tsx b/packages/console/src/pages/Profile/components/LinkAccountSection/index.tsx index ba5e2d065d5..8a00dd71554 100644 --- a/packages/console/src/pages/Profile/components/LinkAccountSection/index.tsx +++ b/packages/console/src/pages/Profile/components/LinkAccountSection/index.tsx @@ -34,7 +34,7 @@ type Props = { function LinkAccountSection({ user, connectors, onUpdate }: Props) { const { t } = useTranslation(undefined, { keyPrefix: 'admin_console' }); - const { navigate, getUrl } = useTenantPathname(); + const { navigate } = useTenantPathname(); const theme = useTheme(); const { show: showConfirm } = useConfirmModal(); const api = useStaticApi({ prefixUrl: adminTenantEndpoint, resourceIndicator: meApi.indicator }); @@ -96,7 +96,10 @@ function LinkAccountSection({ user, connectors, onUpdate }: Props) { name: 'profile.link', handler: async () => { const authUri = await getSocialAuthorizationUri(id); - const callback = getUrl('handle-social').href; + // Profile page has been moved to the root path instead of being nested inside a tenant context. + // Therefore, we don't need to use `getUrl` to prepend the tenant segment in the callback URL. + // Also, link social is Cloud only, so no need to conditionally prepend the `ossConsolePath`, either. + const callback = new URL('/handle-social', window.location.href).href; const queries = new URLSearchParams({ redirectTo: authUri, @@ -125,7 +128,6 @@ function LinkAccountSection({ user, connectors, onUpdate }: Props) { t, onUpdate, getSocialAuthorizationUri, - getUrl, ]); return ( From 266af8c3d7e5b0a6b9549d86dbc436ce1afecf03 Mon Sep 17 00:00:00 2001 From: Xiao Yijun Date: Fri, 10 May 2024 11:00:26 +0800 Subject: [PATCH 361/687] fix(experience): hide scope list if no user scopes and resource scopes (#5840) --- .../src/pages/Consent/ScopesListCard/index.tsx | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/packages/experience/src/pages/Consent/ScopesListCard/index.tsx b/packages/experience/src/pages/Consent/ScopesListCard/index.tsx index 87b1bdb66cb..37929f119f6 100644 --- a/packages/experience/src/pages/Consent/ScopesListCard/index.tsx +++ b/packages/experience/src/pages/Consent/ScopesListCard/index.tsx @@ -45,15 +45,12 @@ const ScopesListCard = ({ [t, userScopes] ); - const showTerms = Boolean(termsUrl ?? privacyUrl); + // Todo @xiaoyijun remove dev feature flag and authorization agreement from this component + const showTerms = !isDevFeaturesEnabled && Boolean(termsUrl ?? privacyUrl); // If there is no user scopes and resource scopes, we don't need to show the scopes list. // This is a fallback for the corner case that all the scopes are already granted. - if ( - !isDevFeaturesEnabled && // Todo @xiaoyijun remove dev feature flag - !userScopesData?.length && - !resourceScopes?.length - ) { + if (!userScopesData?.length && !resourceScopes?.length) { return showTerms ? (
Date: Fri, 10 May 2024 15:10:51 +0800 Subject: [PATCH 362/687] refactor(console): refactor some console global routes (#5841) --- packages/console/src/cloud/AppRoutes.tsx | 4 +++- packages/console/src/containers/ConsoleRoutes/index.tsx | 7 ++++--- packages/console/src/contexts/TenantsProvider.tsx | 2 +- 3 files changed, 8 insertions(+), 5 deletions(-) diff --git a/packages/console/src/cloud/AppRoutes.tsx b/packages/console/src/cloud/AppRoutes.tsx index d97f388c13c..32394669d75 100644 --- a/packages/console/src/cloud/AppRoutes.tsx +++ b/packages/console/src/cloud/AppRoutes.tsx @@ -6,6 +6,7 @@ import AcceptInvitation from '@/pages/AcceptInvitation'; import Callback from '@/pages/Callback'; import CheckoutSuccessCallback from '@/pages/CheckoutSuccessCallback'; import Profile from '@/pages/Profile'; +import HandleSocialCallback from '@/pages/Profile/containers/HandleSocialCallback'; import * as styles from './AppRoutes.module.scss'; import Main from './pages/Main'; @@ -20,10 +21,11 @@ function AppRoutes() { } /> }> } /> } /> + } /> } /> } /> diff --git a/packages/console/src/containers/ConsoleRoutes/index.tsx b/packages/console/src/containers/ConsoleRoutes/index.tsx index 45c0da00a05..b6efae43ea4 100644 --- a/packages/console/src/containers/ConsoleRoutes/index.tsx +++ b/packages/console/src/containers/ConsoleRoutes/index.tsx @@ -40,13 +40,14 @@ export function ConsoleRoutes() { * console path to trigger the console routes. */} {!isCloud && } />} - {!isCloud && ( - } /> - )} }> } /> } /> }> + } + /> } /> }> {isCloud && ( diff --git a/packages/console/src/contexts/TenantsProvider.tsx b/packages/console/src/contexts/TenantsProvider.tsx index eca1189c936..71822d21902 100644 --- a/packages/console/src/contexts/TenantsProvider.tsx +++ b/packages/console/src/contexts/TenantsProvider.tsx @@ -21,6 +21,7 @@ import { isCloud } from '@/consts/env'; export enum GlobalAnonymousRoute { Callback = '/callback', SocialDemoCallback = '/social-demo-callback', + AcceptInvitation = '/accept', Profile = '/profile', } @@ -29,7 +30,6 @@ export enum GlobalAnonymousRoute { */ export enum GlobalRoute { CheckoutSuccessCallback = '/checkout-success-callback', - AcceptInvitation = '/accept', } const reservedRoutes: Readonly = Object.freeze([ From 3d4404f5df5e846aa8c44b47936921a4d8d82943 Mon Sep 17 00:00:00 2001 From: Charles Zhao Date: Fri, 10 May 2024 16:20:12 +0800 Subject: [PATCH 363/687] fix(console): move handle social route to global anonymous route enum (#5842) --- packages/console/src/cloud/AppRoutes.tsx | 2 +- packages/console/src/containers/ConsoleRoutes/index.tsx | 2 -- packages/console/src/contexts/TenantsProvider.tsx | 1 + 3 files changed, 2 insertions(+), 3 deletions(-) diff --git a/packages/console/src/cloud/AppRoutes.tsx b/packages/console/src/cloud/AppRoutes.tsx index 32394669d75..097b4008c48 100644 --- a/packages/console/src/cloud/AppRoutes.tsx +++ b/packages/console/src/cloud/AppRoutes.tsx @@ -25,7 +25,7 @@ function AppRoutes() { element={} /> } /> - } /> + } /> } /> } /> diff --git a/packages/console/src/containers/ConsoleRoutes/index.tsx b/packages/console/src/containers/ConsoleRoutes/index.tsx index b6efae43ea4..e1244164663 100644 --- a/packages/console/src/containers/ConsoleRoutes/index.tsx +++ b/packages/console/src/containers/ConsoleRoutes/index.tsx @@ -14,7 +14,6 @@ import useSwrOptions from '@/hooks/use-swr-options'; import Callback from '@/pages/Callback'; import CheckoutSuccessCallback from '@/pages/CheckoutSuccessCallback'; import Profile from '@/pages/Profile'; -import HandleSocialCallback from '@/pages/Profile/containers/HandleSocialCallback'; import Welcome from '@/pages/Welcome'; import { dropLeadingSlash } from '@/utils/url'; @@ -48,7 +47,6 @@ export function ConsoleRoutes() { path={dropLeadingSlash(GlobalAnonymousRoute.Profile) + '/*'} element={} /> - } /> }> {isCloud && ( Date: Sat, 11 May 2024 12:44:58 +0800 Subject: [PATCH 364/687] refactor(console, phrases): update resource scopes assignment form title (#5846) --- .../use-resource-scopes-assignment.ts | 6 +----- .../de/translation/admin-console/application-details.ts | 3 --- .../en/translation/admin-console/application-details.ts | 2 -- .../es/translation/admin-console/application-details.ts | 3 --- .../fr/translation/admin-console/application-details.ts | 3 --- .../it/translation/admin-console/application-details.ts | 3 --- .../ja/translation/admin-console/application-details.ts | 3 --- .../ko/translation/admin-console/application-details.ts | 3 --- .../pl-pl/translation/admin-console/application-details.ts | 3 --- .../pt-br/translation/admin-console/application-details.ts | 3 --- .../pt-pt/translation/admin-console/application-details.ts | 3 --- .../ru/translation/admin-console/application-details.ts | 3 --- .../tr-tr/translation/admin-console/application-details.ts | 3 --- .../zh-cn/translation/admin-console/application-details.ts | 3 --- .../zh-hk/translation/admin-console/application-details.ts | 3 --- .../zh-tw/translation/admin-console/application-details.ts | 3 --- 16 files changed, 1 insertion(+), 49 deletions(-) diff --git a/packages/console/src/pages/ApplicationDetails/ApplicationDetailsContent/Permissions/PermissionsCard/ApplicationScopesAssignmentModal/use-resource-scopes-assignment.ts b/packages/console/src/pages/ApplicationDetails/ApplicationDetailsContent/Permissions/PermissionsCard/ApplicationScopesAssignmentModal/use-resource-scopes-assignment.ts index 9c158d09654..7f05960b3d5 100644 --- a/packages/console/src/pages/ApplicationDetails/ApplicationDetailsContent/Permissions/PermissionsCard/ApplicationScopesAssignmentModal/use-resource-scopes-assignment.ts +++ b/packages/console/src/pages/ApplicationDetails/ApplicationDetailsContent/Permissions/PermissionsCard/ApplicationScopesAssignmentModal/use-resource-scopes-assignment.ts @@ -73,11 +73,7 @@ const useResourceScopesAssignment: HookType = (assignedResourceScopes, options) selectedData, setSelectedData, availableDataGroups, - title: `application_details.permissions.${ - isForOrganization - ? 'add_permissions_for_organization' - : 'api_resource_permissions_assignment_form_title' - }`, + title: `application_details.permissions.api_resource_permissions_assignment_form_title`, }; }; diff --git a/packages/phrases/src/locales/de/translation/admin-console/application-details.ts b/packages/phrases/src/locales/de/translation/admin-console/application-details.ts index 41f0f588aa0..3ee1d929000 100644 --- a/packages/phrases/src/locales/de/translation/admin-console/application-details.ts +++ b/packages/phrases/src/locales/de/translation/admin-console/application-details.ts @@ -185,9 +185,6 @@ const application_details = { 'Select the permissions requested by the third-party app for accessing specific organization data.', /** UNTRANSLATED */ grant_organization_level_permissions: 'Grant permissions of organization data', - /** UNTRANSLATED */ - add_permissions_for_organization: - 'Add the API resource permissions used in the "Organization template"', }, roles: { name_column: 'Rolle', diff --git a/packages/phrases/src/locales/en/translation/admin-console/application-details.ts b/packages/phrases/src/locales/en/translation/admin-console/application-details.ts index 19a64caaf05..c3fb74122a6 100644 --- a/packages/phrases/src/locales/en/translation/admin-console/application-details.ts +++ b/packages/phrases/src/locales/en/translation/admin-console/application-details.ts @@ -128,8 +128,6 @@ const application_details = { organization_description: 'Select the permissions requested by the third-party app for accessing specific organization data.', grant_organization_level_permissions: 'Grant permissions of organization data', - add_permissions_for_organization: - 'Add the API resource permissions used in the "Organization template"', }, roles: { name_column: 'Role', diff --git a/packages/phrases/src/locales/es/translation/admin-console/application-details.ts b/packages/phrases/src/locales/es/translation/admin-console/application-details.ts index db99d5c90dd..fdb165d4cf7 100644 --- a/packages/phrases/src/locales/es/translation/admin-console/application-details.ts +++ b/packages/phrases/src/locales/es/translation/admin-console/application-details.ts @@ -185,9 +185,6 @@ const application_details = { 'Select the permissions requested by the third-party app for accessing specific organization data.', /** UNTRANSLATED */ grant_organization_level_permissions: 'Grant permissions of organization data', - /** UNTRANSLATED */ - add_permissions_for_organization: - 'Add the API resource permissions used in the "Organization template"', }, roles: { name_column: 'Rol', diff --git a/packages/phrases/src/locales/fr/translation/admin-console/application-details.ts b/packages/phrases/src/locales/fr/translation/admin-console/application-details.ts index a2d5fa38235..0bd87067744 100644 --- a/packages/phrases/src/locales/fr/translation/admin-console/application-details.ts +++ b/packages/phrases/src/locales/fr/translation/admin-console/application-details.ts @@ -185,9 +185,6 @@ const application_details = { 'Select the permissions requested by the third-party app for accessing specific organization data.', /** UNTRANSLATED */ grant_organization_level_permissions: 'Grant permissions of organization data', - /** UNTRANSLATED */ - add_permissions_for_organization: - 'Add the API resource permissions used in the "Organization template"', }, roles: { name_column: 'Rôle', diff --git a/packages/phrases/src/locales/it/translation/admin-console/application-details.ts b/packages/phrases/src/locales/it/translation/admin-console/application-details.ts index db63e9c99e9..f8a2de7cabe 100644 --- a/packages/phrases/src/locales/it/translation/admin-console/application-details.ts +++ b/packages/phrases/src/locales/it/translation/admin-console/application-details.ts @@ -185,9 +185,6 @@ const application_details = { 'Select the permissions requested by the third-party app for accessing specific organization data.', /** UNTRANSLATED */ grant_organization_level_permissions: 'Grant permissions of organization data', - /** UNTRANSLATED */ - add_permissions_for_organization: - 'Add the API resource permissions used in the "Organization template"', }, roles: { name_column: 'Ruolo', diff --git a/packages/phrases/src/locales/ja/translation/admin-console/application-details.ts b/packages/phrases/src/locales/ja/translation/admin-console/application-details.ts index fea90741b13..7906c5c1552 100644 --- a/packages/phrases/src/locales/ja/translation/admin-console/application-details.ts +++ b/packages/phrases/src/locales/ja/translation/admin-console/application-details.ts @@ -185,9 +185,6 @@ const application_details = { 'Select the permissions requested by the third-party app for accessing specific organization data.', /** UNTRANSLATED */ grant_organization_level_permissions: 'Grant permissions of organization data', - /** UNTRANSLATED */ - add_permissions_for_organization: - 'Add the API resource permissions used in the "Organization template"', }, roles: { name_column: '役割', diff --git a/packages/phrases/src/locales/ko/translation/admin-console/application-details.ts b/packages/phrases/src/locales/ko/translation/admin-console/application-details.ts index e2b739474d7..9cf65d5e69c 100644 --- a/packages/phrases/src/locales/ko/translation/admin-console/application-details.ts +++ b/packages/phrases/src/locales/ko/translation/admin-console/application-details.ts @@ -185,9 +185,6 @@ const application_details = { 'Select the permissions requested by the third-party app for accessing specific organization data.', /** UNTRANSLATED */ grant_organization_level_permissions: 'Grant permissions of organization data', - /** UNTRANSLATED */ - add_permissions_for_organization: - 'Add the API resource permissions used in the "Organization template"', }, roles: { name_column: '역할', diff --git a/packages/phrases/src/locales/pl-pl/translation/admin-console/application-details.ts b/packages/phrases/src/locales/pl-pl/translation/admin-console/application-details.ts index 806d17a3d98..3031a8d4189 100644 --- a/packages/phrases/src/locales/pl-pl/translation/admin-console/application-details.ts +++ b/packages/phrases/src/locales/pl-pl/translation/admin-console/application-details.ts @@ -185,9 +185,6 @@ const application_details = { 'Select the permissions requested by the third-party app for accessing specific organization data.', /** UNTRANSLATED */ grant_organization_level_permissions: 'Grant permissions of organization data', - /** UNTRANSLATED */ - add_permissions_for_organization: - 'Add the API resource permissions used in the "Organization template"', }, roles: { name_column: 'Role', diff --git a/packages/phrases/src/locales/pt-br/translation/admin-console/application-details.ts b/packages/phrases/src/locales/pt-br/translation/admin-console/application-details.ts index 40a18966f26..bfa291fccd9 100644 --- a/packages/phrases/src/locales/pt-br/translation/admin-console/application-details.ts +++ b/packages/phrases/src/locales/pt-br/translation/admin-console/application-details.ts @@ -185,9 +185,6 @@ const application_details = { 'Select the permissions requested by the third-party app for accessing specific organization data.', /** UNTRANSLATED */ grant_organization_level_permissions: 'Grant permissions of organization data', - /** UNTRANSLATED */ - add_permissions_for_organization: - 'Add the API resource permissions used in the "Organization template"', }, roles: { name_column: 'Função', diff --git a/packages/phrases/src/locales/pt-pt/translation/admin-console/application-details.ts b/packages/phrases/src/locales/pt-pt/translation/admin-console/application-details.ts index 324618e8926..e9032e3c0f2 100644 --- a/packages/phrases/src/locales/pt-pt/translation/admin-console/application-details.ts +++ b/packages/phrases/src/locales/pt-pt/translation/admin-console/application-details.ts @@ -185,9 +185,6 @@ const application_details = { 'Select the permissions requested by the third-party app for accessing specific organization data.', /** UNTRANSLATED */ grant_organization_level_permissions: 'Grant permissions of organization data', - /** UNTRANSLATED */ - add_permissions_for_organization: - 'Add the API resource permissions used in the "Organization template"', }, roles: { name_column: 'Nome da função', diff --git a/packages/phrases/src/locales/ru/translation/admin-console/application-details.ts b/packages/phrases/src/locales/ru/translation/admin-console/application-details.ts index 9c5d69eef7e..956b20e922b 100644 --- a/packages/phrases/src/locales/ru/translation/admin-console/application-details.ts +++ b/packages/phrases/src/locales/ru/translation/admin-console/application-details.ts @@ -185,9 +185,6 @@ const application_details = { 'Select the permissions requested by the third-party app for accessing specific organization data.', /** UNTRANSLATED */ grant_organization_level_permissions: 'Grant permissions of organization data', - /** UNTRANSLATED */ - add_permissions_for_organization: - 'Add the API resource permissions used in the "Organization template"', }, roles: { name_column: 'Роль', diff --git a/packages/phrases/src/locales/tr-tr/translation/admin-console/application-details.ts b/packages/phrases/src/locales/tr-tr/translation/admin-console/application-details.ts index 8d0a8897647..c9b11c66fac 100644 --- a/packages/phrases/src/locales/tr-tr/translation/admin-console/application-details.ts +++ b/packages/phrases/src/locales/tr-tr/translation/admin-console/application-details.ts @@ -185,9 +185,6 @@ const application_details = { 'Select the permissions requested by the third-party app for accessing specific organization data.', /** UNTRANSLATED */ grant_organization_level_permissions: 'Grant permissions of organization data', - /** UNTRANSLATED */ - add_permissions_for_organization: - 'Add the API resource permissions used in the "Organization template"', }, roles: { name_column: 'Rol', diff --git a/packages/phrases/src/locales/zh-cn/translation/admin-console/application-details.ts b/packages/phrases/src/locales/zh-cn/translation/admin-console/application-details.ts index eb488536a4f..3af38781d38 100644 --- a/packages/phrases/src/locales/zh-cn/translation/admin-console/application-details.ts +++ b/packages/phrases/src/locales/zh-cn/translation/admin-console/application-details.ts @@ -183,9 +183,6 @@ const application_details = { 'Select the permissions requested by the third-party app for accessing specific organization data.', /** UNTRANSLATED */ grant_organization_level_permissions: 'Grant permissions of organization data', - /** UNTRANSLATED */ - add_permissions_for_organization: - 'Add the API resource permissions used in the "Organization template"', }, roles: { name_column: '角色', diff --git a/packages/phrases/src/locales/zh-hk/translation/admin-console/application-details.ts b/packages/phrases/src/locales/zh-hk/translation/admin-console/application-details.ts index 28167217081..6e5505d6f2e 100644 --- a/packages/phrases/src/locales/zh-hk/translation/admin-console/application-details.ts +++ b/packages/phrases/src/locales/zh-hk/translation/admin-console/application-details.ts @@ -183,9 +183,6 @@ const application_details = { 'Select the permissions requested by the third-party app for accessing specific organization data.', /** UNTRANSLATED */ grant_organization_level_permissions: 'Grant permissions of organization data', - /** UNTRANSLATED */ - add_permissions_for_organization: - 'Add the API resource permissions used in the "Organization template"', }, roles: { name_column: '角色', diff --git a/packages/phrases/src/locales/zh-tw/translation/admin-console/application-details.ts b/packages/phrases/src/locales/zh-tw/translation/admin-console/application-details.ts index d8b31bc3a34..ce8d30010ae 100644 --- a/packages/phrases/src/locales/zh-tw/translation/admin-console/application-details.ts +++ b/packages/phrases/src/locales/zh-tw/translation/admin-console/application-details.ts @@ -184,9 +184,6 @@ const application_details = { 'Select the permissions requested by the third-party app for accessing specific organization data.', /** UNTRANSLATED */ grant_organization_level_permissions: 'Grant permissions of organization data', - /** UNTRANSLATED */ - add_permissions_for_organization: - 'Add the API resource permissions used in the "Organization template"', }, roles: { name_column: '角色', From 5872172cbb21414d4a6764a7f48f50f03fd53a02 Mon Sep 17 00:00:00 2001 From: Darcy Ye Date: Sat, 11 May 2024 22:22:14 +0800 Subject: [PATCH 365/687] feat(core,console): enable custom JWT for OSS and can run script in local vm (#5794) --- .changeset/itchy-eels-remain.md | 8 + .../ConsoleContent/Sidebar/hook.tsx | 1 - .../src/hooks/use-console-routes/index.tsx | 2 +- packages/core/src/libraries/jwt-customizer.ts | 127 ++- packages/core/src/oidc/extra-token-claims.ts | 45 +- .../logto-config/jwt-customizer.test.ts | 16 +- .../src/routes/logto-config/jwt-customizer.ts | 32 +- .../logto-config/logto-config.openapi.json | 1 - packages/core/src/tenants/Libraries.ts | 4 +- packages/core/src/utils/custom-jwt/index.ts | 1 + .../src/utils/custom-jwt/local-vm-error.ts | 17 + .../src/__mocks__/jwt-customizer.ts | 37 +- .../integration-tests/src/api/logto-config.ts | 9 + .../api/application/application.roles.test.ts | 48 +- .../src/tests/api/logto-config.test.ts | 27 + .../tests/api/oidc/get-access-token.test.ts | 21 +- .../src/types/logto-config/jwt-customizer.ts | 25 +- packages/toolkit/core-kit/package.json | 6 +- .../core-kit/src/custom-jwt/error-handling.ts | 10 + .../toolkit/core-kit/src/custom-jwt/index.ts | 2 + .../src/custom-jwt/script-execution.ts | 41 + pnpm-lock.yaml | 842 ++++++++++-------- 22 files changed, 853 insertions(+), 469 deletions(-) create mode 100644 .changeset/itchy-eels-remain.md create mode 100644 packages/core/src/utils/custom-jwt/local-vm-error.ts create mode 100644 packages/toolkit/core-kit/src/custom-jwt/error-handling.ts create mode 100644 packages/toolkit/core-kit/src/custom-jwt/index.ts create mode 100644 packages/toolkit/core-kit/src/custom-jwt/script-execution.ts diff --git a/.changeset/itchy-eels-remain.md b/.changeset/itchy-eels-remain.md new file mode 100644 index 00000000000..7bd5047ae22 --- /dev/null +++ b/.changeset/itchy-eels-remain.md @@ -0,0 +1,8 @@ +--- +"@logto/console": minor +"@logto/core": minor +--- + +enable custom JWT feature for OSS version + +OSS version users can now use custom JWT feature to add custom claims to JWT access tokens payload (previously, this feature was only available to Logto Cloud). diff --git a/packages/console/src/containers/ConsoleContent/Sidebar/hook.tsx b/packages/console/src/containers/ConsoleContent/Sidebar/hook.tsx index 1d1cb002e15..2cc9cede834 100644 --- a/packages/console/src/containers/ConsoleContent/Sidebar/hook.tsx +++ b/packages/console/src/containers/ConsoleContent/Sidebar/hook.tsx @@ -130,7 +130,6 @@ export const useSidebarMenuItems = (): { { Icon: JwtClaims, title: 'customize_jwt', - isHidden: !isCloud, }, { Icon: Hook, diff --git a/packages/console/src/hooks/use-console-routes/index.tsx b/packages/console/src/hooks/use-console-routes/index.tsx index 92277b99fb7..597a9e57533 100644 --- a/packages/console/src/hooks/use-console-routes/index.tsx +++ b/packages/console/src/hooks/use-console-routes/index.tsx @@ -63,7 +63,7 @@ export const useConsoleRoutes = () => { }, { path: 'signing-keys', element: }, isCloud && tenantSettings, - isCloud && customizeJwt + customizeJwt ), [tenantSettings] ); diff --git a/packages/core/src/libraries/jwt-customizer.ts b/packages/core/src/libraries/jwt-customizer.ts index d8be39a7612..6ae1e538030 100644 --- a/packages/core/src/libraries/jwt-customizer.ts +++ b/packages/core/src/libraries/jwt-customizer.ts @@ -1,14 +1,19 @@ +import { runScriptFunctionInLocalVm, buildErrorResponse } from '@logto/core-kit/custom-jwt'; import { userInfoSelectFields, jwtCustomizerUserContextGuard, type LogtoJwtTokenKey, type JwtCustomizerType, type JwtCustomizerUserContext, + type CustomJwtFetcher, + LogtoJwtTokenKeyType, } from '@logto/schemas'; import { type ConsoleLog } from '@logto/shared'; import { deduplicate, pick, pickState, assert } from '@silverhand/essentials'; import deepmerge from 'deepmerge'; +import { z, ZodError } from 'zod'; +import { EnvSet } from '#src/env-set/index.js'; import RequestError from '#src/errors/RequestError/index.js'; import type { LogtoConfigLibrary } from '#src/libraries/logto-config.js'; import { type ScopeLibrary } from '#src/libraries/scope.js'; @@ -18,26 +23,49 @@ import { getJwtCustomizerScripts, type CustomJwtDeployRequestBody, } from '#src/utils/custom-jwt/index.js'; +import { LocalVmError } from '#src/utils/custom-jwt/index.js'; import { type CloudConnectionLibrary } from './cloud-connection.js'; -export const createJwtCustomizerLibrary = ( - queries: Queries, - logtoConfigs: LogtoConfigLibrary, - cloudConnection: CloudConnectionLibrary, - userLibrary: UserLibrary, - scopeLibrary: ScopeLibrary -) => { - const { - users: { findUserById }, - rolesScopes: { findRolesScopesByRoleIds }, - scopes: { findScopesByIds }, - userSsoIdentities, - organizations: { relations }, - } = queries; - const { findUserRoles } = userLibrary; - const { attachResourceToScopes } = scopeLibrary; - const { getJwtCustomizers } = logtoConfigs; +export class JwtCustomizerLibrary { + // Convert errors to WithTyped client response error to share the error handling logic. + static async runScriptInLocalVm(data: CustomJwtFetcher) { + try { + const payload = + data.tokenType === LogtoJwtTokenKeyType.AccessToken + ? pick(data, 'token', 'context', 'environmentVariables') + : pick(data, 'token', 'environmentVariables'); + const result = await runScriptFunctionInLocalVm(data.script, 'getCustomJwtClaims', payload); + + // If the `result` is not a record, we cannot merge it to the existing token payload. + return z.record(z.unknown()).parse(result); + } catch (error: unknown) { + // Assuming we only use zod for request body validation + if (error instanceof ZodError) { + const { errors } = error; + throw new LocalVmError( + { + message: 'Invalid input', + errors, + }, + 400 + ); + } + + throw new LocalVmError( + buildErrorResponse(error), + error instanceof SyntaxError || error instanceof TypeError ? 422 : 500 + ); + } + } + + constructor( + private readonly queries: Queries, + private readonly logtoConfigs: LogtoConfigLibrary, + private readonly cloudConnection: CloudConnectionLibrary, + private readonly userLibrary: UserLibrary, + private readonly scopeLibrary: ScopeLibrary + ) {} /** * We does not include org roles' scopes for the following reason: @@ -45,15 +73,20 @@ export const createJwtCustomizerLibrary = ( * these APIs from console setup while this library method is a backend used method. * 2. Logto developers can get the org roles' id from this user context and hence query the org roles' scopes via management API. */ - const getUserContext = async (userId: string): Promise => { - const user = await findUserById(userId); - const fullSsoIdentities = await userSsoIdentities.findUserSsoIdentitiesByUserId(userId); - const roles = await findUserRoles(userId); - const rolesScopes = await findRolesScopesByRoleIds(roles.map(({ id }) => id)); + async getUserContext(userId: string): Promise { + const user = await this.queries.users.findUserById(userId); + const fullSsoIdentities = await this.queries.userSsoIdentities.findUserSsoIdentitiesByUserId( + userId + ); + const roles = await this.userLibrary.findUserRoles(userId); + const rolesScopes = await this.queries.rolesScopes.findRolesScopesByRoleIds( + roles.map(({ id }) => id) + ); const scopeIds = rolesScopes.map(({ scopeId }) => scopeId); - const scopes = await findScopesByIds(scopeIds); - const scopesWithResources = await attachResourceToScopes(scopes); - const organizationsWithRoles = await relations.users.getOrganizationsByUserId(userId); + const scopes = await this.queries.scopes.findScopesByIds(scopeIds); + const scopesWithResources = await this.scopeLibrary.attachResourceToScopes(scopes); + const organizationsWithRoles = + await this.queries.organizations.relations.users.getOrganizationsByUserId(userId); const userContext = { ...pick(user, ...userInfoSelectFields), ssoIdentities: fullSsoIdentities.map(pickState('issuer', 'identityId', 'detail')), @@ -81,7 +114,7 @@ export const createJwtCustomizerLibrary = ( }; return jwtCustomizerUserContextGuard.parse(userContext); - }; + } /** * This method is used to deploy the give JWT customizer scripts to the cloud worker service. @@ -95,17 +128,24 @@ export const createJwtCustomizerLibrary = ( * @params payload.value - JWT customizer value * @params payload.useCase - The use case of JWT customizer script, can be either `test` or `production`. */ - const deployJwtCustomizerScript = async ( + async deployJwtCustomizerScript( consoleLog: ConsoleLog, payload: { key: T; value: JwtCustomizerType[T]; useCase: 'test' | 'production'; } - ) => { + ) { + if (!EnvSet.values.isCloud) { + consoleLog.warn( + 'Early terminate `deployJwtCustomizerScript` since we do not provide dedicated computing resource for OSS version.' + ); + return; + } + const [client, jwtCustomizers] = await Promise.all([ - cloudConnection.getClient(), - getJwtCustomizers(consoleLog), + this.cloudConnection.getClient(), + this.logtoConfigs.getJwtCustomizers(consoleLog), ]); const customizerScriptsFromDatabase = getJwtCustomizerScripts(jwtCustomizers); @@ -129,15 +169,19 @@ export const createJwtCustomizerLibrary = ( await client.put(`/api/services/custom-jwt/worker`, { body: deepmerge(customizerScriptsFromDatabase, newCustomizerScripts), }); - }; + } + + async undeployJwtCustomizerScript(consoleLog: ConsoleLog, key: T) { + if (!EnvSet.values.isCloud) { + consoleLog.warn( + 'Early terminate `undeployJwtCustomizerScript` since we do not deploy the script to dedicated computing resource for OSS version.' + ); + return; + } - const undeployJwtCustomizerScript = async ( - consoleLog: ConsoleLog, - key: T - ) => { const [client, jwtCustomizers] = await Promise.all([ - cloudConnection.getClient(), - getJwtCustomizers(consoleLog), + this.cloudConnection.getClient(), + this.logtoConfigs.getJwtCustomizers(consoleLog), ]); assert(jwtCustomizers[key], new RequestError({ code: 'entity.not_exists', key })); @@ -160,10 +204,5 @@ export const createJwtCustomizerLibrary = ( await client.put(`/api/services/custom-jwt/worker`, { body: deepmerge(customizerScriptsFromDatabase, newCustomizerScripts), }); - }; - return { - getUserContext, - deployJwtCustomizerScript, - undeployJwtCustomizerScript, - }; -}; + } +} diff --git a/packages/core/src/oidc/extra-token-claims.ts b/packages/core/src/oidc/extra-token-claims.ts index 5b9fbb42bb5..906e5134599 100644 --- a/packages/core/src/oidc/extra-token-claims.ts +++ b/packages/core/src/oidc/extra-token-claims.ts @@ -4,6 +4,7 @@ import { LogtoJwtTokenKeyType, LogResult, jwtCustomizer as jwtCustomizerLog, + type CustomJwtFetcher, } from '@logto/schemas'; import { generateStandardId } from '@logto/shared'; import { conditional, trySafe } from '@silverhand/essentials'; @@ -11,6 +12,7 @@ import { type KoaContextWithOIDC, type UnknownObject } from 'oidc-provider'; import { EnvSet } from '#src/env-set/index.js'; import { type CloudConnectionLibrary } from '#src/libraries/cloud-connection.js'; +import { JwtCustomizerLibrary } from '#src/libraries/jwt-customizer.js'; import { type LogtoConfigLibrary } from '#src/libraries/logto-config.js'; import { LogEntry } from '#src/middleware/koa-audit-log.js'; import type Libraries from '#src/tenants/Libraries.js'; @@ -66,12 +68,6 @@ export const getExtraTokenClaimsForJwtCustomization = async ( cloudConnection: CloudConnectionLibrary; } ): Promise => { - const { isCloud } = EnvSet.values; - // No cloud connection for OSS version, skip. - if (!isCloud) { - return; - } - // Narrow down the token type to `AccessToken` and `ClientCredentials`. if ( !(token instanceof ctx.oidc.provider.AccessToken) && @@ -110,14 +106,6 @@ export const getExtraTokenClaimsForJwtCustomization = async ( .map((field) => [field, Reflect.get(token, field)]) ); - const client = await cloudConnection.getClient(); - - const commonPayload = { - script, - environmentVariables, - token: readOnlyToken, - }; - // We pass context to the cloud API only when it is a user's access token. const logtoUserInfo = conditional( !isTokenClientCredentials && @@ -125,22 +113,29 @@ export const getExtraTokenClaimsForJwtCustomization = async ( (await libraries.jwtCustomizers.getUserContext(token.accountId)) ); - // `context` parameter is only eligible for user's access token for now. - return await client.post(`/api/services/custom-jwt`, { - body: isTokenClientCredentials - ? { - ...commonPayload, - tokenType: LogtoJwtTokenKeyType.ClientCredentials, - } + const payload: CustomJwtFetcher = { + script, + environmentVariables, + token: readOnlyToken, + ...(isTokenClientCredentials + ? { tokenType: LogtoJwtTokenKeyType.ClientCredentials } : { - ...commonPayload, tokenType: LogtoJwtTokenKeyType.AccessToken, // TODO (LOG-8555): the newly added `UserProfile` type includes undefined fields and can not be directly assigned to `Json` type. And the `undefined` fields should be removed by zod guard. + // `context` parameter is only eligible for user's access token for now. // eslint-disable-next-line no-restricted-syntax context: { user: logtoUserInfo as Record }, - }, - search: {}, - }); + }), + }; + + if (EnvSet.values.isCloud) { + const client = await cloudConnection.getClient(); + return await client.post(`/api/services/custom-jwt`, { + body: payload, + search: {}, + }); + } + return await JwtCustomizerLibrary.runScriptInLocalVm(payload); } catch (error: unknown) { const entry = new LogEntry( `${jwtCustomizerLog.prefix}.${ diff --git a/packages/core/src/routes/logto-config/jwt-customizer.test.ts b/packages/core/src/routes/logto-config/jwt-customizer.test.ts index 0c5e3428cab..b3138192980 100644 --- a/packages/core/src/routes/logto-config/jwt-customizer.test.ts +++ b/packages/core/src/routes/logto-config/jwt-customizer.test.ts @@ -157,10 +157,9 @@ describe('configs JWT customizer routes', () => { expect(response.status).toEqual(204); }); - it('POST /configs/jwt-customizer/test should return 200', async () => { - const cloudConnectionResponse = { success: true }; + it('POST /configs/jwt-customizer/test should not call cloud connection client post', async () => { jest.spyOn(tenantContext.cloudConnection, 'getClient').mockResolvedValue(mockCloudClient); - jest.spyOn(mockCloudClient, 'post').mockResolvedValue(cloudConnectionResponse); + const clientPostSpy = jest.spyOn(mockCloudClient, 'post'); const payload: JwtCustomizerTestRequestBody = { tokenType: LogtoJwtTokenKeyType.ClientCredentials, @@ -169,7 +168,7 @@ describe('configs JWT customizer routes', () => { token: {}, }; - const response = await routeRequester.post('/configs/jwt-customizer/test').send(payload); + await routeRequester.post('/configs/jwt-customizer/test').send(payload); expect(tenantContext.libraries.jwtCustomizers.deployJwtCustomizerScript).toHaveBeenCalledWith( expect.any(ConsoleLog), @@ -180,13 +179,8 @@ describe('configs JWT customizer routes', () => { } ); - expect(mockCloudClient.post).toHaveBeenCalledWith('/api/services/custom-jwt', { - body: payload, - search: { - isTest: 'true', - }, - }); + expect(clientPostSpy).toHaveBeenCalledTimes(0); - expect(response.status).toEqual(200); + // TODO: Add the test on nested class static method. }); }); diff --git a/packages/core/src/routes/logto-config/jwt-customizer.ts b/packages/core/src/routes/logto-config/jwt-customizer.ts index f69cadaa630..43ae020e530 100644 --- a/packages/core/src/routes/logto-config/jwt-customizer.ts +++ b/packages/core/src/routes/logto-config/jwt-customizer.ts @@ -13,6 +13,7 @@ import { ZodError, z } from 'zod'; import { EnvSet } from '#src/env-set/index.js'; import RequestError, { formatZodError } from '#src/errors/RequestError/index.js'; +import { JwtCustomizerLibrary } from '#src/libraries/jwt-customizer.js'; import koaGuard, { parse } from '#src/middleware/koa-guard.js'; import koaQuotaGuard from '#src/middleware/koa-quota-guard.js'; import { getConsoleLogFromContext } from '#src/utils/console.js'; @@ -41,7 +42,6 @@ export default function logtoConfigJwtCustomizerRoutes, statusCode: number) { + super( + new Response( + new Blob([JSON.stringify(errorBody)], { + type: 'application/json', + }), + { + status: statusCode, + } + ) + ); + } +} diff --git a/packages/integration-tests/src/__mocks__/jwt-customizer.ts b/packages/integration-tests/src/__mocks__/jwt-customizer.ts index 398c2785460..72f9831ae8a 100644 --- a/packages/integration-tests/src/__mocks__/jwt-customizer.ts +++ b/packages/integration-tests/src/__mocks__/jwt-customizer.ts @@ -1,11 +1,38 @@ +import type { AccessTokenPayload, ClientCredentialsPayload } from '@logto/schemas'; + +const standardTokenPayloadData = { + jti: 'f1d3d2d1-1f2d-3d4e-5d6f-7d8a9d0e1d2', + aud: 'http://localhost:3000/api/test', + scope: 'read write', + clientId: 'my_app', +}; + +export const accessTokenSample: AccessTokenPayload = { + ...standardTokenPayloadData, + accountId: 'uid_123', + grantId: 'grant_123', + gty: 'authorization_code', + kind: 'AccessToken', +}; + +export const clientCredentialsTokenSample: ClientCredentialsPayload = { + ...standardTokenPayloadData, + kind: 'ClientCredentials', +}; + export const clientCredentialsJwtCustomizerPayload = { script: '', - environmentVariables: {}, + environmentVariables: { + foo: 'bar', + API_KEY: '12345', + }, contextSample: {}, + tokenSample: clientCredentialsTokenSample, }; export const accessTokenJwtCustomizerPayload = { ...clientCredentialsJwtCustomizerPayload, + tokenSample: accessTokenSample, contextSample: { user: { id: '123', @@ -26,3 +53,11 @@ export const accessTokenJwtCustomizerPayload = { }, }, }; + +export const accessTokenSampleScript = `const getCustomJwtClaims = async ({ token, context, environmentVariables }) => { + return { user_id: context?.user?.id ?? 'unknown' }; +}`; + +export const clientCredentialsSampleScript = `const getCustomJwtClaims = async ({ token, context, environmentVariables }) => { + return { ...environmentVariables }; +}`; diff --git a/packages/integration-tests/src/api/logto-config.ts b/packages/integration-tests/src/api/logto-config.ts index 78ce7c7ec58..37804b5b3fe 100644 --- a/packages/integration-tests/src/api/logto-config.ts +++ b/packages/integration-tests/src/api/logto-config.ts @@ -6,6 +6,8 @@ import { type AccessTokenJwtCustomizer, type ClientCredentialsJwtCustomizer, type JwtCustomizerConfigs, + type JwtCustomizerTestRequestBody, + type Json, } from '@logto/schemas'; import { authedAdminApi } from './api.js'; @@ -60,3 +62,10 @@ export const updateJwtCustomizer = async ( authedAdminApi .patch(`configs/jwt-customizer/${keyTypePath}`, { json: value }) .json(); + +export const testJwtCustomizer = async (payload: JwtCustomizerTestRequestBody) => + authedAdminApi + .post(`configs/jwt-customizer/test`, { + json: payload, + }) + .json(); diff --git a/packages/integration-tests/src/tests/api/application/application.roles.test.ts b/packages/integration-tests/src/tests/api/application/application.roles.test.ts index 6fe86b4620b..0e012e47b12 100644 --- a/packages/integration-tests/src/tests/api/application/application.roles.test.ts +++ b/packages/integration-tests/src/tests/api/application/application.roles.test.ts @@ -1,7 +1,12 @@ import { ApplicationType, RoleType } from '@logto/schemas'; -import { generateStandardId } from '@logto/shared'; +import { generateStandardId, formUrlEncodedHeaders } from '@logto/shared'; import { HTTPError } from 'ky'; +import { + clientCredentialsJwtCustomizerPayload, + clientCredentialsSampleScript, +} from '#src/__mocks__/jwt-customizer.js'; +import { oidcApi } from '#src/api/api.js'; import { createApplication, getApplicationRoles, @@ -9,9 +14,14 @@ import { deleteRoleFromApplication, putRolesToApplication, getApplications, + createResource, + upsertJwtCustomizer, + deleteJwtCustomizer, } from '#src/api/index.js'; import { createRole, assignApplicationsToRole } from '#src/api/role.js'; +import { createScope } from '#src/api/scope.js'; import { expectRejects } from '#src/helpers/index.js'; +import { getAccessTokenPayload } from '#src/utils.js'; describe('admin console application management (roles)', () => { it('should get empty list successfully', async () => { @@ -146,4 +156,40 @@ describe('admin console application management (roles)', () => { expect(applications.find(({ name }) => name === 'test-m2m-app-002')).toBeFalsy(); expect(applications.find(({ name }) => name === 'test-spa-app-002')).toBeTruthy(); }); + + it('test m2m application client credentials grant type with custom JWT', async () => { + await upsertJwtCustomizer('client-credentials', { + ...clientCredentialsJwtCustomizerPayload, + script: clientCredentialsSampleScript, + }); + + const m2mApp = await createApplication(generateStandardId(), ApplicationType.MachineToMachine); + const resource = await createResource(); + const createdScope = await createScope(resource.id); + const createdScope2 = await createScope(resource.id); + const role = await createRole({ + type: RoleType.MachineToMachine, + scopeIds: [createdScope.id, createdScope2.id], + }); + await assignApplicationsToRole([m2mApp.id], role.id); + + const { access_token: accessToken } = await oidcApi + .post('token', { + headers: formUrlEncodedHeaders, + body: new URLSearchParams({ + client_id: m2mApp.id, + client_secret: m2mApp.secret, + grant_type: 'client_credentials', + resource: resource.indicator, + scope: [createdScope.name, createdScope2.name].join(' '), + }), + }) + .json<{ access_token: string }>(); + + const payload = getAccessTokenPayload(accessToken); + expect(payload).toHaveProperty('foo', 'bar'); + expect(payload).toHaveProperty('API_KEY', '12345'); + + await deleteJwtCustomizer('client-credentials'); + }); }); diff --git a/packages/integration-tests/src/tests/api/logto-config.test.ts b/packages/integration-tests/src/tests/api/logto-config.test.ts index 3cb093077de..04b16662be9 100644 --- a/packages/integration-tests/src/tests/api/logto-config.test.ts +++ b/packages/integration-tests/src/tests/api/logto-config.test.ts @@ -3,11 +3,14 @@ import { type AdminConsoleData, LogtoOidcConfigKeyType, LogtoJwtTokenKey, + LogtoJwtTokenKeyType, } from '@logto/schemas'; import { accessTokenJwtCustomizerPayload, clientCredentialsJwtCustomizerPayload, + accessTokenSampleScript, + clientCredentialsSampleScript, } from '#src/__mocks__/jwt-customizer.js'; import { deleteOidcKey, @@ -20,6 +23,7 @@ import { getJwtCustomizer, getJwtCustomizers, deleteJwtCustomizer, + testJwtCustomizer, } from '#src/api/index.js'; import { expectRejects } from '#src/helpers/index.js'; @@ -241,4 +245,27 @@ describe('admin console sign-in experience', () => { await deleteJwtCustomizer('client-credentials'); await expect(getJwtCustomizers()).resolves.toEqual([]); }); + + it('should successfully test an access token JWT customizer', async () => { + const testResult = await testJwtCustomizer({ + tokenType: LogtoJwtTokenKeyType.AccessToken, + token: accessTokenJwtCustomizerPayload.tokenSample, + context: accessTokenJwtCustomizerPayload.contextSample, + script: accessTokenSampleScript, + environmentVariables: accessTokenJwtCustomizerPayload.environmentVariables, + }); + expect(testResult).toMatchObject({ + user_id: accessTokenJwtCustomizerPayload.contextSample.user.id, + }); + }); + + it('should successfully test a client credentials JWT customizer', async () => { + const testResult = await testJwtCustomizer({ + tokenType: LogtoJwtTokenKeyType.ClientCredentials, + token: clientCredentialsJwtCustomizerPayload.tokenSample, + script: clientCredentialsSampleScript, + environmentVariables: clientCredentialsJwtCustomizerPayload.environmentVariables, + }); + expect(testResult).toMatchObject(clientCredentialsJwtCustomizerPayload.environmentVariables); + }); }); diff --git a/packages/integration-tests/src/tests/api/oidc/get-access-token.test.ts b/packages/integration-tests/src/tests/api/oidc/get-access-token.test.ts index 63da8bb4f22..5857de7caab 100644 --- a/packages/integration-tests/src/tests/api/oidc/get-access-token.test.ts +++ b/packages/integration-tests/src/tests/api/oidc/get-access-token.test.ts @@ -5,7 +5,18 @@ import { InteractionEvent, type Resource, RoleType } from '@logto/schemas'; import { assert } from '@silverhand/essentials'; import { createRemoteJWKSet, jwtVerify } from 'jose'; -import { createResource, deleteResource, deleteUser, putInteraction } from '#src/api/index.js'; +import { + accessTokenJwtCustomizerPayload, + accessTokenSampleScript, +} from '#src/__mocks__/jwt-customizer.js'; +import { + createResource, + deleteJwtCustomizer, + deleteResource, + deleteUser, + putInteraction, + upsertJwtCustomizer, +} from '#src/api/index.js'; import { assignUsersToRole, createRole, deleteRole } from '#src/api/role.js'; import { createScope, deleteScope } from '#src/api/scope.js'; import MockClient, { defaultConfig } from '#src/client/index.js'; @@ -91,6 +102,11 @@ describe('get access token', () => { }); it('can sign in and getAccessToken with guest user', async () => { + await upsertJwtCustomizer('access-token', { + ...accessTokenJwtCustomizerPayload, + script: accessTokenSampleScript, + }); + const client = new MockClient({ resources: [testApiResourceInfo.indicator], scopes: testApiScopeNames, @@ -108,6 +124,9 @@ describe('get access token', () => { 'scope', testApiScopeNames.join(' ') ); + expect(getAccessTokenPayload(accessToken)).toHaveProperty('user_id', guestUserId); + + await deleteJwtCustomizer('access-token'); }); it('sign in and verify jwt', async () => { diff --git a/packages/schemas/src/types/logto-config/jwt-customizer.ts b/packages/schemas/src/types/logto-config/jwt-customizer.ts index 6c64073d979..ef6714aa892 100644 --- a/packages/schemas/src/types/logto-config/jwt-customizer.ts +++ b/packages/schemas/src/types/logto-config/jwt-customizer.ts @@ -1,12 +1,24 @@ +import { jsonObjectGuard } from '@logto/connector-kit'; import { z } from 'zod'; import { Organizations, Roles, UserSsoIdentities } from '../../db-entries/index.js'; -import { jsonObjectGuard, mfaFactorsGuard } from '../../foundations/index.js'; +import { mfaFactorsGuard } from '../../foundations/index.js'; import { scopeResponseGuard } from '../scope.js'; import { userInfoGuard } from '../user.js'; import { accessTokenPayloadGuard, clientCredentialsPayloadGuard } from './oidc-provider.js'; +export const jwtCustomizerGuard = z.object({ + script: z.string(), + environmentVariables: z.record(z.string()).optional(), + contextSample: jsonObjectGuard.optional(), +}); + +export enum LogtoJwtTokenKeyType { + AccessToken = 'access-token', + ClientCredentials = 'client-credentials', +} + export const jwtCustomizerUserContextGuard = userInfoGuard.extend({ ssoIdentities: UserSsoIdentities.guard .pick({ issuer: true, identityId: true, detail: true }) @@ -32,12 +44,6 @@ export const jwtCustomizerUserContextGuard = userInfoGuard.extend({ export type JwtCustomizerUserContext = z.infer; -export const jwtCustomizerGuard = z.object({ - script: z.string(), - environmentVariables: z.record(z.string()).optional(), - contextSample: jsonObjectGuard.optional(), -}); - export const accessTokenJwtCustomizerGuard = jwtCustomizerGuard .extend({ // Use partial token guard since users customization may not rely on all fields. @@ -57,11 +63,6 @@ export const clientCredentialsJwtCustomizerGuard = jwtCustomizerGuard export type ClientCredentialsJwtCustomizer = z.infer; -export enum LogtoJwtTokenKeyType { - AccessToken = 'access-token', - ClientCredentials = 'client-credentials', -} - /** * This guard is for the core JWT customizer testing API request body guard. * Unlike the DB guard diff --git a/packages/toolkit/core-kit/package.json b/packages/toolkit/core-kit/package.json index 91b6f3251e7..034e3b0792e 100644 --- a/packages/toolkit/core-kit/package.json +++ b/packages/toolkit/core-kit/package.json @@ -17,7 +17,11 @@ "import": "./lib/index.js" }, "./declaration": "./declaration/index.ts", - "./scss/*": "./scss/*.scss" + "./scss/*": "./scss/*.scss", + "./custom-jwt": { + "node": "./lib/custom-jwt/index.js", + "types": "./lib/custom-jwt/index.d.ts" + } }, "types": "./lib/index.d.ts", "files": [ diff --git a/packages/toolkit/core-kit/src/custom-jwt/error-handling.ts b/packages/toolkit/core-kit/src/custom-jwt/error-handling.ts new file mode 100644 index 00000000000..ae013172b93 --- /dev/null +++ b/packages/toolkit/core-kit/src/custom-jwt/error-handling.ts @@ -0,0 +1,10 @@ +import { types } from 'node:util'; + +export const buildErrorResponse = (error: unknown) => + /** + * Use `isNativeError` to check if the error is an instance of `Error`. + * If the error comes from `node:vm` module, then it will not be an instance of `Error` but can be captured by `isNativeError`. + */ + types.isNativeError(error) + ? { message: error.message, stack: error.stack } + : { message: String(error) }; diff --git a/packages/toolkit/core-kit/src/custom-jwt/index.ts b/packages/toolkit/core-kit/src/custom-jwt/index.ts new file mode 100644 index 00000000000..5d732ce66cf --- /dev/null +++ b/packages/toolkit/core-kit/src/custom-jwt/index.ts @@ -0,0 +1,2 @@ +export * from './script-execution.js'; +export * from './error-handling.js'; diff --git a/packages/toolkit/core-kit/src/custom-jwt/script-execution.ts b/packages/toolkit/core-kit/src/custom-jwt/script-execution.ts new file mode 100644 index 00000000000..32ee65f4ce6 --- /dev/null +++ b/packages/toolkit/core-kit/src/custom-jwt/script-execution.ts @@ -0,0 +1,41 @@ +import { runInNewContext } from 'node:vm'; + +/** + * This function is used to execute a named function in a customized code script in a local + * virtual machine with the given payload as input. + * + * @param script Custom code snippet. + * @param functionName The name of the function to be executed. + * @param payload The input payload for the function. + * @returns The result of the function execution. + */ +export const runScriptFunctionInLocalVm = async ( + script: string, + functionName: string, + payload: unknown +) => { + const globalContext = Object.freeze({ + fetch: async (...args: Parameters) => fetch(...args), + }); + const customFunction: unknown = runInNewContext(script + `;${functionName};`, globalContext); + + if (typeof customFunction !== 'function') { + throw new TypeError(`The script does not have a function named \`${functionName}\``); + } + + /** + * We can not use top-level await in `vm`, use the following implementation instead. + * + * Ref: + * 1. https://github.com/nodejs/node/issues/40898 + * 2. https://github.com/n-riesco/ijavascript/issues/173#issuecomment-693924098 + */ + const result: unknown = await runInNewContext( + '(async () => customFunction(payload))();', + Object.freeze({ customFunction, payload }), + // Limit the execution time to 3 seconds, throws error if the script takes too long to execute. + { timeout: 3000 } + ); + + return result; +}; diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 4fc91804bb5..caa106faa04 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -63,7 +63,7 @@ importers: version: 20.10.4 '@vitest/coverage-v8': specifier: ^1.4.0 - version: 1.4.0(vitest@1.4.0) + version: 1.4.0(vitest@1.4.0(@types/node@20.10.4)(jsdom@20.0.2)(sass@1.56.1)) eslint: specifier: ^8.56.0 version: 8.57.0 @@ -78,7 +78,7 @@ importers: version: 5.3.3 vitest: specifier: ^1.4.0 - version: 1.4.0(@types/node@20.10.4) + version: 1.4.0(@types/node@20.10.4)(jsdom@20.0.2)(sass@1.56.1) packages/cli: dependencies: @@ -190,7 +190,7 @@ importers: version: 17.0.13 '@vitest/coverage-v8': specifier: ^1.4.0 - version: 1.4.0(vitest@1.4.0) + version: 1.4.0(vitest@1.4.0(@types/node@20.10.4)(jsdom@20.0.2)(sass@1.56.1)) '@withtyped/server': specifier: ^0.13.6 version: 0.13.6(zod@3.22.4) @@ -208,7 +208,7 @@ importers: version: 17.0.0 vitest: specifier: ^1.4.0 - version: 1.4.0(@types/node@20.10.4) + version: 1.4.0(@types/node@20.10.4)(jsdom@20.0.2)(sass@1.56.1) packages/connectors/connector-alipay-native: dependencies: @@ -245,7 +245,7 @@ importers: version: 15.2.3(rollup@4.12.0) '@rollup/plugin-typescript': specifier: ^11.1.6 - version: 11.1.6(rollup@4.12.0)(typescript@5.3.3) + version: 11.1.6(rollup@4.12.0)(tslib@2.6.2)(typescript@5.3.3) '@shopify/jest-koa-mocks': specifier: ^5.0.0 version: 5.0.0 @@ -263,7 +263,7 @@ importers: version: 6.0.2 '@vitest/coverage-v8': specifier: ^1.4.0 - version: 1.4.0(vitest@1.4.0) + version: 1.4.0(vitest@1.4.0(@types/node@20.11.20)(jsdom@20.0.2)(sass@1.56.1)) eslint: specifier: ^8.56.0 version: 8.57.0 @@ -290,7 +290,7 @@ importers: version: 5.3.3 vitest: specifier: ^1.4.0 - version: 1.4.0(@types/node@20.11.20) + version: 1.4.0(@types/node@20.11.20)(jsdom@20.0.2)(sass@1.56.1) packages/connectors/connector-alipay-web: dependencies: @@ -327,7 +327,7 @@ importers: version: 15.2.3(rollup@4.12.0) '@rollup/plugin-typescript': specifier: ^11.1.6 - version: 11.1.6(rollup@4.12.0)(typescript@5.3.3) + version: 11.1.6(rollup@4.12.0)(tslib@2.6.2)(typescript@5.3.3) '@shopify/jest-koa-mocks': specifier: ^5.0.0 version: 5.0.0 @@ -345,7 +345,7 @@ importers: version: 6.0.2 '@vitest/coverage-v8': specifier: ^1.4.0 - version: 1.4.0(vitest@1.4.0) + version: 1.4.0(vitest@1.4.0(@types/node@20.11.20)(jsdom@20.0.2)(sass@1.56.1)) eslint: specifier: ^8.56.0 version: 8.57.0 @@ -372,7 +372,7 @@ importers: version: 5.3.3 vitest: specifier: ^1.4.0 - version: 1.4.0(@types/node@20.11.20) + version: 1.4.0(@types/node@20.11.20)(jsdom@20.0.2)(sass@1.56.1) packages/connectors/connector-aliyun-dm: dependencies: @@ -403,7 +403,7 @@ importers: version: 15.2.3(rollup@4.12.0) '@rollup/plugin-typescript': specifier: ^11.1.6 - version: 11.1.6(rollup@4.12.0)(typescript@5.3.3) + version: 11.1.6(rollup@4.12.0)(tslib@2.6.2)(typescript@5.3.3) '@silverhand/eslint-config': specifier: 6.0.1 version: 6.0.1(eslint@8.57.0)(prettier@3.0.0)(typescript@5.3.3) @@ -418,7 +418,7 @@ importers: version: 6.0.2 '@vitest/coverage-v8': specifier: ^1.4.0 - version: 1.4.0(vitest@1.4.0) + version: 1.4.0(vitest@1.4.0(@types/node@20.11.20)(jsdom@20.0.2)(sass@1.56.1)) eslint: specifier: ^8.56.0 version: 8.57.0 @@ -445,7 +445,7 @@ importers: version: 5.3.3 vitest: specifier: ^1.4.0 - version: 1.4.0(@types/node@20.11.20) + version: 1.4.0(@types/node@20.11.20)(jsdom@20.0.2)(sass@1.56.1) packages/connectors/connector-aliyun-sms: dependencies: @@ -476,7 +476,7 @@ importers: version: 15.2.3(rollup@4.12.0) '@rollup/plugin-typescript': specifier: ^11.1.6 - version: 11.1.6(rollup@4.12.0)(typescript@5.3.3) + version: 11.1.6(rollup@4.12.0)(tslib@2.6.2)(typescript@5.3.3) '@silverhand/eslint-config': specifier: 6.0.1 version: 6.0.1(eslint@8.57.0)(prettier@3.0.0)(typescript@5.3.3) @@ -491,7 +491,7 @@ importers: version: 6.0.2 '@vitest/coverage-v8': specifier: ^1.4.0 - version: 1.4.0(vitest@1.4.0) + version: 1.4.0(vitest@1.4.0(@types/node@20.11.20)(jsdom@20.0.2)(sass@1.56.1)) eslint: specifier: ^8.56.0 version: 8.57.0 @@ -518,7 +518,7 @@ importers: version: 5.3.3 vitest: specifier: ^1.4.0 - version: 1.4.0(@types/node@20.11.20) + version: 1.4.0(@types/node@20.11.20)(jsdom@20.0.2)(sass@1.56.1) packages/connectors/connector-apple: dependencies: @@ -555,7 +555,7 @@ importers: version: 15.2.3(rollup@4.12.0) '@rollup/plugin-typescript': specifier: ^11.1.6 - version: 11.1.6(rollup@4.12.0)(typescript@5.3.3) + version: 11.1.6(rollup@4.12.0)(tslib@2.6.2)(typescript@5.3.3) '@silverhand/eslint-config': specifier: 6.0.1 version: 6.0.1(eslint@8.57.0)(prettier@3.0.0)(typescript@5.3.3) @@ -570,7 +570,7 @@ importers: version: 6.0.2 '@vitest/coverage-v8': specifier: ^1.4.0 - version: 1.4.0(vitest@1.4.0) + version: 1.4.0(vitest@1.4.0(@types/node@20.11.20)(jsdom@20.0.2)(sass@1.56.1)) eslint: specifier: ^8.56.0 version: 8.57.0 @@ -597,7 +597,7 @@ importers: version: 5.3.3 vitest: specifier: ^1.4.0 - version: 1.4.0(@types/node@20.11.20) + version: 1.4.0(@types/node@20.11.20)(jsdom@20.0.2)(sass@1.56.1) packages/connectors/connector-aws-ses: dependencies: @@ -634,7 +634,7 @@ importers: version: 15.2.3(rollup@4.12.0) '@rollup/plugin-typescript': specifier: ^11.1.6 - version: 11.1.6(rollup@4.12.0)(typescript@5.3.3) + version: 11.1.6(rollup@4.12.0)(tslib@2.6.2)(typescript@5.3.3) '@silverhand/eslint-config': specifier: 6.0.1 version: 6.0.1(eslint@8.57.0)(prettier@3.0.0)(typescript@5.3.3) @@ -649,7 +649,7 @@ importers: version: 6.0.2 '@vitest/coverage-v8': specifier: ^1.4.0 - version: 1.4.0(vitest@1.4.0) + version: 1.4.0(vitest@1.4.0(@types/node@20.11.20)(jsdom@20.0.2)(sass@1.56.1)) eslint: specifier: ^8.56.0 version: 8.57.0 @@ -676,7 +676,7 @@ importers: version: 5.3.3 vitest: specifier: ^1.4.0 - version: 1.4.0(@types/node@20.11.20) + version: 1.4.0(@types/node@20.11.20)(jsdom@20.0.2)(sass@1.56.1) packages/connectors/connector-azuread: dependencies: @@ -710,7 +710,7 @@ importers: version: 15.2.3(rollup@4.12.0) '@rollup/plugin-typescript': specifier: ^11.1.6 - version: 11.1.6(rollup@4.12.0)(typescript@5.3.3) + version: 11.1.6(rollup@4.12.0)(tslib@2.6.2)(typescript@5.3.3) '@silverhand/eslint-config': specifier: 6.0.1 version: 6.0.1(eslint@8.57.0)(prettier@3.0.0)(typescript@5.3.3) @@ -725,7 +725,7 @@ importers: version: 6.0.2 '@vitest/coverage-v8': specifier: ^1.4.0 - version: 1.4.0(vitest@1.4.0) + version: 1.4.0(vitest@1.4.0(@types/node@20.11.20)(jsdom@20.0.2)(sass@1.56.1)) eslint: specifier: ^8.56.0 version: 8.57.0 @@ -752,7 +752,7 @@ importers: version: 5.3.3 vitest: specifier: ^1.4.0 - version: 1.4.0(@types/node@20.11.20) + version: 1.4.0(@types/node@20.11.20)(jsdom@20.0.2)(sass@1.56.1) packages/connectors/connector-discord: dependencies: @@ -783,7 +783,7 @@ importers: version: 15.2.3(rollup@4.12.0) '@rollup/plugin-typescript': specifier: ^11.1.6 - version: 11.1.6(rollup@4.12.0)(typescript@5.3.3) + version: 11.1.6(rollup@4.12.0)(tslib@2.6.2)(typescript@5.3.3) '@silverhand/eslint-config': specifier: 6.0.1 version: 6.0.1(eslint@8.57.0)(prettier@3.0.0)(typescript@5.3.3) @@ -798,7 +798,7 @@ importers: version: 6.0.2 '@vitest/coverage-v8': specifier: ^1.4.0 - version: 1.4.0(vitest@1.4.0) + version: 1.4.0(vitest@1.4.0(@types/node@20.11.20)(jsdom@20.0.2)(sass@1.56.1)) eslint: specifier: ^8.56.0 version: 8.57.0 @@ -825,7 +825,7 @@ importers: version: 5.3.3 vitest: specifier: ^1.4.0 - version: 1.4.0(@types/node@20.11.20) + version: 1.4.0(@types/node@20.11.20)(jsdom@20.0.2)(sass@1.56.1) packages/connectors/connector-facebook: dependencies: @@ -856,7 +856,7 @@ importers: version: 15.2.3(rollup@4.12.0) '@rollup/plugin-typescript': specifier: ^11.1.6 - version: 11.1.6(rollup@4.12.0)(typescript@5.3.3) + version: 11.1.6(rollup@4.12.0)(tslib@2.6.2)(typescript@5.3.3) '@silverhand/eslint-config': specifier: 6.0.1 version: 6.0.1(eslint@8.57.0)(prettier@3.0.0)(typescript@5.3.3) @@ -871,7 +871,7 @@ importers: version: 6.0.2 '@vitest/coverage-v8': specifier: ^1.4.0 - version: 1.4.0(vitest@1.4.0) + version: 1.4.0(vitest@1.4.0(@types/node@20.11.20)(jsdom@20.0.2)(sass@1.56.1)) eslint: specifier: ^8.56.0 version: 8.57.0 @@ -898,7 +898,7 @@ importers: version: 5.3.3 vitest: specifier: ^1.4.0 - version: 1.4.0(@types/node@20.11.20) + version: 1.4.0(@types/node@20.11.20)(jsdom@20.0.2)(sass@1.56.1) packages/connectors/connector-feishu-web: dependencies: @@ -929,7 +929,7 @@ importers: version: 15.2.3(rollup@4.12.0) '@rollup/plugin-typescript': specifier: ^11.1.6 - version: 11.1.6(rollup@4.12.0)(typescript@5.3.3) + version: 11.1.6(rollup@4.12.0)(tslib@2.6.2)(typescript@5.3.3) '@silverhand/eslint-config': specifier: 6.0.1 version: 6.0.1(eslint@8.57.0)(prettier@3.0.0)(typescript@5.3.3) @@ -944,7 +944,7 @@ importers: version: 6.0.2 '@vitest/coverage-v8': specifier: ^1.4.0 - version: 1.4.0(vitest@1.4.0) + version: 1.4.0(vitest@1.4.0(@types/node@20.11.20)(jsdom@20.0.2)(sass@1.56.1)) eslint: specifier: ^8.56.0 version: 8.57.0 @@ -971,7 +971,7 @@ importers: version: 5.3.3 vitest: specifier: ^1.4.0 - version: 1.4.0(@types/node@20.11.20) + version: 1.4.0(@types/node@20.11.20)(jsdom@20.0.2)(sass@1.56.1) packages/connectors/connector-github: dependencies: @@ -1005,7 +1005,7 @@ importers: version: 15.2.3(rollup@4.12.0) '@rollup/plugin-typescript': specifier: ^11.1.6 - version: 11.1.6(rollup@4.12.0)(typescript@5.3.3) + version: 11.1.6(rollup@4.12.0)(tslib@2.6.2)(typescript@5.3.3) '@silverhand/eslint-config': specifier: 6.0.1 version: 6.0.1(eslint@8.57.0)(prettier@3.0.0)(typescript@5.3.3) @@ -1020,7 +1020,7 @@ importers: version: 6.0.2 '@vitest/coverage-v8': specifier: ^1.4.0 - version: 1.4.0(vitest@1.4.0) + version: 1.4.0(vitest@1.4.0(@types/node@20.11.20)(jsdom@20.0.2)(sass@1.56.1)) eslint: specifier: ^8.56.0 version: 8.57.0 @@ -1047,7 +1047,7 @@ importers: version: 5.3.3 vitest: specifier: ^1.4.0 - version: 1.4.0(@types/node@20.11.20) + version: 1.4.0(@types/node@20.11.20)(jsdom@20.0.2)(sass@1.56.1) packages/connectors/connector-google: dependencies: @@ -1078,7 +1078,7 @@ importers: version: 15.2.3(rollup@4.12.0) '@rollup/plugin-typescript': specifier: ^11.1.6 - version: 11.1.6(rollup@4.12.0)(typescript@5.3.3) + version: 11.1.6(rollup@4.12.0)(tslib@2.6.2)(typescript@5.3.3) '@silverhand/eslint-config': specifier: 6.0.1 version: 6.0.1(eslint@8.57.0)(prettier@3.0.0)(typescript@5.3.3) @@ -1093,7 +1093,7 @@ importers: version: 6.0.2 '@vitest/coverage-v8': specifier: ^1.4.0 - version: 1.4.0(vitest@1.4.0) + version: 1.4.0(vitest@1.4.0(@types/node@20.11.20)(jsdom@20.0.2)(sass@1.56.1)) eslint: specifier: ^8.56.0 version: 8.57.0 @@ -1120,7 +1120,7 @@ importers: version: 5.3.3 vitest: specifier: ^1.4.0 - version: 1.4.0(@types/node@20.11.20) + version: 1.4.0(@types/node@20.11.20)(jsdom@20.0.2)(sass@1.56.1) packages/connectors/connector-huggingface: dependencies: @@ -1151,7 +1151,7 @@ importers: version: 15.2.3(rollup@4.14.3) '@rollup/plugin-typescript': specifier: ^11.1.6 - version: 11.1.6(rollup@4.14.3)(typescript@5.3.3) + version: 11.1.6(rollup@4.14.3)(tslib@2.6.2)(typescript@5.3.3) '@silverhand/eslint-config': specifier: 6.0.1 version: 6.0.1(eslint@8.57.0)(prettier@3.0.0)(typescript@5.3.3) @@ -1166,7 +1166,7 @@ importers: version: 6.0.2 '@vitest/coverage-v8': specifier: ^1.4.0 - version: 1.4.0(vitest@1.4.0) + version: 1.4.0(vitest@1.4.0(@types/node@20.12.7)(jsdom@20.0.2)(sass@1.56.1)) eslint: specifier: ^8.56.0 version: 8.57.0 @@ -1193,7 +1193,7 @@ importers: version: 5.3.3 vitest: specifier: ^1.4.0 - version: 1.4.0(@types/node@20.12.7) + version: 1.4.0(@types/node@20.12.7)(jsdom@20.0.2)(sass@1.56.1) packages/connectors/connector-kakao: dependencies: @@ -1224,7 +1224,7 @@ importers: version: 15.2.3(rollup@4.12.0) '@rollup/plugin-typescript': specifier: ^11.1.6 - version: 11.1.6(rollup@4.12.0)(typescript@5.3.3) + version: 11.1.6(rollup@4.12.0)(tslib@2.6.2)(typescript@5.3.3) '@silverhand/eslint-config': specifier: 6.0.1 version: 6.0.1(eslint@8.57.0)(prettier@3.0.0)(typescript@5.3.3) @@ -1239,7 +1239,7 @@ importers: version: 6.0.2 '@vitest/coverage-v8': specifier: ^1.4.0 - version: 1.4.0(vitest@1.4.0) + version: 1.4.0(vitest@1.4.0(@types/node@20.11.20)(jsdom@20.0.2)(sass@1.56.1)) eslint: specifier: ^8.56.0 version: 8.57.0 @@ -1266,7 +1266,7 @@ importers: version: 5.3.3 vitest: specifier: ^1.4.0 - version: 1.4.0(@types/node@20.11.20) + version: 1.4.0(@types/node@20.11.20)(jsdom@20.0.2)(sass@1.56.1) packages/connectors/connector-logto-email: dependencies: @@ -1300,7 +1300,7 @@ importers: version: 15.2.3(rollup@4.12.0) '@rollup/plugin-typescript': specifier: ^11.1.6 - version: 11.1.6(rollup@4.12.0)(typescript@5.3.3) + version: 11.1.6(rollup@4.12.0)(tslib@2.6.2)(typescript@5.3.3) '@silverhand/eslint-config': specifier: 6.0.1 version: 6.0.1(eslint@8.57.0)(prettier@3.0.0)(typescript@5.3.3) @@ -1315,7 +1315,7 @@ importers: version: 6.0.2 '@vitest/coverage-v8': specifier: ^1.4.0 - version: 1.4.0(vitest@1.4.0) + version: 1.4.0(vitest@1.4.0(@types/node@20.11.20)(jsdom@20.0.2)(sass@1.56.1)) eslint: specifier: ^8.56.0 version: 8.57.0 @@ -1342,7 +1342,7 @@ importers: version: 5.3.3 vitest: specifier: ^1.4.0 - version: 1.4.0(@types/node@20.11.20) + version: 1.4.0(@types/node@20.11.20)(jsdom@20.0.2)(sass@1.56.1) packages/connectors/connector-logto-sms: dependencies: @@ -1373,7 +1373,7 @@ importers: version: 15.2.3(rollup@4.12.0) '@rollup/plugin-typescript': specifier: ^11.1.6 - version: 11.1.6(rollup@4.12.0)(typescript@5.3.3) + version: 11.1.6(rollup@4.12.0)(tslib@2.6.2)(typescript@5.3.3) '@silverhand/eslint-config': specifier: 6.0.1 version: 6.0.1(eslint@8.57.0)(prettier@3.0.0)(typescript@5.3.3) @@ -1388,7 +1388,7 @@ importers: version: 6.0.2 '@vitest/coverage-v8': specifier: ^1.4.0 - version: 1.4.0(vitest@1.4.0) + version: 1.4.0(vitest@1.4.0(@types/node@20.11.20)(jsdom@20.0.2)(sass@1.56.1)) eslint: specifier: ^8.56.0 version: 8.57.0 @@ -1415,7 +1415,7 @@ importers: version: 5.3.3 vitest: specifier: ^1.4.0 - version: 1.4.0(@types/node@20.11.20) + version: 1.4.0(@types/node@20.11.20)(jsdom@20.0.2)(sass@1.56.1) packages/connectors/connector-logto-social-demo: dependencies: @@ -1446,7 +1446,7 @@ importers: version: 15.2.3(rollup@4.12.0) '@rollup/plugin-typescript': specifier: ^11.1.6 - version: 11.1.6(rollup@4.12.0)(typescript@5.3.3) + version: 11.1.6(rollup@4.12.0)(tslib@2.6.2)(typescript@5.3.3) '@silverhand/eslint-config': specifier: 6.0.1 version: 6.0.1(eslint@8.57.0)(prettier@3.0.0)(typescript@5.3.3) @@ -1461,7 +1461,7 @@ importers: version: 6.0.2 '@vitest/coverage-v8': specifier: ^1.4.0 - version: 1.4.0(vitest@1.4.0) + version: 1.4.0(vitest@1.4.0(@types/node@20.11.20)(jsdom@20.0.2)(sass@1.56.1)) eslint: specifier: ^8.56.0 version: 8.57.0 @@ -1488,7 +1488,7 @@ importers: version: 5.3.3 vitest: specifier: ^1.4.0 - version: 1.4.0(@types/node@20.11.20) + version: 1.4.0(@types/node@20.11.20)(jsdom@20.0.2)(sass@1.56.1) packages/connectors/connector-mailgun: dependencies: @@ -1519,7 +1519,7 @@ importers: version: 15.2.3(rollup@4.12.0) '@rollup/plugin-typescript': specifier: ^11.1.6 - version: 11.1.6(rollup@4.12.0)(typescript@5.3.3) + version: 11.1.6(rollup@4.12.0)(tslib@2.6.2)(typescript@5.3.3) '@silverhand/eslint-config': specifier: 6.0.1 version: 6.0.1(eslint@8.57.0)(prettier@3.0.0)(typescript@5.3.3) @@ -1534,7 +1534,7 @@ importers: version: 6.0.2 '@vitest/coverage-v8': specifier: ^1.4.0 - version: 1.4.0(vitest@1.4.0) + version: 1.4.0(vitest@1.4.0(@types/node@20.11.20)(jsdom@20.0.2)(sass@1.56.1)) eslint: specifier: ^8.56.0 version: 8.57.0 @@ -1561,7 +1561,7 @@ importers: version: 5.3.3 vitest: specifier: ^1.4.0 - version: 1.4.0(@types/node@20.11.20) + version: 1.4.0(@types/node@20.11.20)(jsdom@20.0.2)(sass@1.56.1) packages/connectors/connector-mock-email: dependencies: @@ -1592,7 +1592,7 @@ importers: version: 15.2.3(rollup@4.12.0) '@rollup/plugin-typescript': specifier: ^11.1.6 - version: 11.1.6(rollup@4.12.0)(typescript@5.3.3) + version: 11.1.6(rollup@4.12.0)(tslib@2.6.2)(typescript@5.3.3) '@silverhand/eslint-config': specifier: 6.0.1 version: 6.0.1(eslint@8.57.0)(prettier@3.0.0)(typescript@5.3.3) @@ -1607,7 +1607,7 @@ importers: version: 6.0.2 '@vitest/coverage-v8': specifier: ^1.4.0 - version: 1.4.0(vitest@1.4.0) + version: 1.4.0(vitest@1.4.0(@types/node@20.11.20)(jsdom@20.0.2)(sass@1.56.1)) eslint: specifier: ^8.56.0 version: 8.57.0 @@ -1634,7 +1634,7 @@ importers: version: 5.3.3 vitest: specifier: ^1.4.0 - version: 1.4.0(@types/node@20.11.20) + version: 1.4.0(@types/node@20.11.20)(jsdom@20.0.2)(sass@1.56.1) packages/connectors/connector-mock-email-alternative: dependencies: @@ -1665,7 +1665,7 @@ importers: version: 15.2.3(rollup@4.12.0) '@rollup/plugin-typescript': specifier: ^11.1.6 - version: 11.1.6(rollup@4.12.0)(typescript@5.3.3) + version: 11.1.6(rollup@4.12.0)(tslib@2.6.2)(typescript@5.3.3) '@silverhand/eslint-config': specifier: 6.0.1 version: 6.0.1(eslint@8.57.0)(prettier@3.0.0)(typescript@5.3.3) @@ -1680,7 +1680,7 @@ importers: version: 6.0.2 '@vitest/coverage-v8': specifier: ^1.4.0 - version: 1.4.0(vitest@1.4.0) + version: 1.4.0(vitest@1.4.0(@types/node@20.11.20)(jsdom@20.0.2)(sass@1.56.1)) eslint: specifier: ^8.56.0 version: 8.57.0 @@ -1707,7 +1707,7 @@ importers: version: 5.3.3 vitest: specifier: ^1.4.0 - version: 1.4.0(@types/node@20.11.20) + version: 1.4.0(@types/node@20.11.20)(jsdom@20.0.2)(sass@1.56.1) packages/connectors/connector-mock-sms: dependencies: @@ -1738,7 +1738,7 @@ importers: version: 15.2.3(rollup@4.12.0) '@rollup/plugin-typescript': specifier: ^11.1.6 - version: 11.1.6(rollup@4.12.0)(typescript@5.3.3) + version: 11.1.6(rollup@4.12.0)(tslib@2.6.2)(typescript@5.3.3) '@silverhand/eslint-config': specifier: 6.0.1 version: 6.0.1(eslint@8.57.0)(prettier@3.0.0)(typescript@5.3.3) @@ -1753,7 +1753,7 @@ importers: version: 6.0.2 '@vitest/coverage-v8': specifier: ^1.4.0 - version: 1.4.0(vitest@1.4.0) + version: 1.4.0(vitest@1.4.0(@types/node@20.11.20)(jsdom@20.0.2)(sass@1.56.1)) eslint: specifier: ^8.56.0 version: 8.57.0 @@ -1780,7 +1780,7 @@ importers: version: 5.3.3 vitest: specifier: ^1.4.0 - version: 1.4.0(@types/node@20.11.20) + version: 1.4.0(@types/node@20.11.20)(jsdom@20.0.2)(sass@1.56.1) packages/connectors/connector-mock-social: dependencies: @@ -1811,7 +1811,7 @@ importers: version: 15.2.3(rollup@4.12.0) '@rollup/plugin-typescript': specifier: ^11.1.6 - version: 11.1.6(rollup@4.12.0)(typescript@5.3.3) + version: 11.1.6(rollup@4.12.0)(tslib@2.6.2)(typescript@5.3.3) '@silverhand/eslint-config': specifier: 6.0.1 version: 6.0.1(eslint@8.57.0)(prettier@3.0.0)(typescript@5.3.3) @@ -1826,7 +1826,7 @@ importers: version: 6.0.2 '@vitest/coverage-v8': specifier: ^1.4.0 - version: 1.4.0(vitest@1.4.0) + version: 1.4.0(vitest@1.4.0(@types/node@20.11.20)(jsdom@20.0.2)(sass@1.56.1)) eslint: specifier: ^8.56.0 version: 8.57.0 @@ -1853,7 +1853,7 @@ importers: version: 5.3.3 vitest: specifier: ^1.4.0 - version: 1.4.0(@types/node@20.11.20) + version: 1.4.0(@types/node@20.11.20)(jsdom@20.0.2)(sass@1.56.1) packages/connectors/connector-naver: dependencies: @@ -1884,7 +1884,7 @@ importers: version: 15.2.3(rollup@4.12.0) '@rollup/plugin-typescript': specifier: ^11.1.6 - version: 11.1.6(rollup@4.12.0)(typescript@5.3.3) + version: 11.1.6(rollup@4.12.0)(tslib@2.6.2)(typescript@5.3.3) '@silverhand/eslint-config': specifier: 6.0.1 version: 6.0.1(eslint@8.57.0)(prettier@3.0.0)(typescript@5.3.3) @@ -1899,7 +1899,7 @@ importers: version: 6.0.2 '@vitest/coverage-v8': specifier: ^1.4.0 - version: 1.4.0(vitest@1.4.0) + version: 1.4.0(vitest@1.4.0(@types/node@20.11.20)(jsdom@20.0.2)(sass@1.56.1)) eslint: specifier: ^8.56.0 version: 8.57.0 @@ -1926,7 +1926,7 @@ importers: version: 5.3.3 vitest: specifier: ^1.4.0 - version: 1.4.0(@types/node@20.11.20) + version: 1.4.0(@types/node@20.11.20)(jsdom@20.0.2)(sass@1.56.1) packages/connectors/connector-oauth2: dependencies: @@ -1966,7 +1966,7 @@ importers: version: 15.2.3(rollup@4.12.0) '@rollup/plugin-typescript': specifier: ^11.1.6 - version: 11.1.6(rollup@4.12.0)(typescript@5.3.3) + version: 11.1.6(rollup@4.12.0)(tslib@2.6.2)(typescript@5.3.3) '@silverhand/eslint-config': specifier: 6.0.1 version: 6.0.1(eslint@8.57.0)(prettier@3.0.0)(typescript@5.3.3) @@ -1981,7 +1981,7 @@ importers: version: 6.0.2 '@vitest/coverage-v8': specifier: ^1.4.0 - version: 1.4.0(vitest@1.4.0) + version: 1.4.0(vitest@1.4.0(@types/node@20.11.20)(jsdom@20.0.2)(sass@1.56.1)) eslint: specifier: ^8.56.0 version: 8.57.0 @@ -2008,7 +2008,7 @@ importers: version: 5.3.3 vitest: specifier: ^1.4.0 - version: 1.4.0(@types/node@20.11.20) + version: 1.4.0(@types/node@20.11.20)(jsdom@20.0.2)(sass@1.56.1) packages/connectors/connector-oidc: dependencies: @@ -2051,7 +2051,7 @@ importers: version: 15.2.3(rollup@4.12.0) '@rollup/plugin-typescript': specifier: ^11.1.6 - version: 11.1.6(rollup@4.12.0)(typescript@5.3.3) + version: 11.1.6(rollup@4.12.0)(tslib@2.6.2)(typescript@5.3.3) '@silverhand/eslint-config': specifier: 6.0.1 version: 6.0.1(eslint@8.57.0)(prettier@3.0.0)(typescript@5.3.3) @@ -2066,7 +2066,7 @@ importers: version: 6.0.2 '@vitest/coverage-v8': specifier: ^1.4.0 - version: 1.4.0(vitest@1.4.0) + version: 1.4.0(vitest@1.4.0(@types/node@20.11.20)(jsdom@20.0.2)(sass@1.56.1)) eslint: specifier: ^8.56.0 version: 8.57.0 @@ -2093,7 +2093,7 @@ importers: version: 5.3.3 vitest: specifier: ^1.4.0 - version: 1.4.0(@types/node@20.11.20) + version: 1.4.0(@types/node@20.11.20)(jsdom@20.0.2)(sass@1.56.1) packages/connectors/connector-saml: dependencies: @@ -2130,7 +2130,7 @@ importers: version: 15.2.3(rollup@4.12.0) '@rollup/plugin-typescript': specifier: ^11.1.6 - version: 11.1.6(rollup@4.12.0)(typescript@5.3.3) + version: 11.1.6(rollup@4.12.0)(tslib@2.6.2)(typescript@5.3.3) '@silverhand/eslint-config': specifier: 6.0.1 version: 6.0.1(eslint@8.57.0)(prettier@3.0.0)(typescript@5.3.3) @@ -2145,7 +2145,7 @@ importers: version: 6.0.2 '@vitest/coverage-v8': specifier: ^1.4.0 - version: 1.4.0(vitest@1.4.0) + version: 1.4.0(vitest@1.4.0(@types/node@20.11.20)(jsdom@20.0.2)(sass@1.56.1)) eslint: specifier: ^8.56.0 version: 8.57.0 @@ -2172,7 +2172,7 @@ importers: version: 5.3.3 vitest: specifier: ^1.4.0 - version: 1.4.0(@types/node@20.11.20) + version: 1.4.0(@types/node@20.11.20)(jsdom@20.0.2)(sass@1.56.1) packages/connectors/connector-sendgrid-email: dependencies: @@ -2203,7 +2203,7 @@ importers: version: 15.2.3(rollup@4.12.0) '@rollup/plugin-typescript': specifier: ^11.1.6 - version: 11.1.6(rollup@4.12.0)(typescript@5.3.3) + version: 11.1.6(rollup@4.12.0)(tslib@2.6.2)(typescript@5.3.3) '@silverhand/eslint-config': specifier: 6.0.1 version: 6.0.1(eslint@8.57.0)(prettier@3.0.0)(typescript@5.3.3) @@ -2218,7 +2218,7 @@ importers: version: 6.0.2 '@vitest/coverage-v8': specifier: ^1.4.0 - version: 1.4.0(vitest@1.4.0) + version: 1.4.0(vitest@1.4.0(@types/node@20.11.20)(jsdom@20.0.2)(sass@1.56.1)) eslint: specifier: ^8.56.0 version: 8.57.0 @@ -2245,7 +2245,7 @@ importers: version: 5.3.3 vitest: specifier: ^1.4.0 - version: 1.4.0(@types/node@20.11.20) + version: 1.4.0(@types/node@20.11.20)(jsdom@20.0.2)(sass@1.56.1) packages/connectors/connector-smsaero: dependencies: @@ -2276,7 +2276,7 @@ importers: version: 15.2.3(rollup@4.12.0) '@rollup/plugin-typescript': specifier: ^11.1.6 - version: 11.1.6(rollup@4.12.0)(typescript@5.3.3) + version: 11.1.6(rollup@4.12.0)(tslib@2.6.2)(typescript@5.3.3) '@silverhand/eslint-config': specifier: 6.0.1 version: 6.0.1(eslint@8.57.0)(prettier@3.0.0)(typescript@5.3.3) @@ -2291,7 +2291,7 @@ importers: version: 6.0.2 '@vitest/coverage-v8': specifier: ^1.4.0 - version: 1.4.0(vitest@1.4.0) + version: 1.4.0(vitest@1.4.0(@types/node@20.11.20)(jsdom@20.0.2)(sass@1.56.1)) eslint: specifier: ^8.56.0 version: 8.57.0 @@ -2318,7 +2318,7 @@ importers: version: 5.3.3 vitest: specifier: ^1.4.0 - version: 1.4.0(@types/node@20.11.20) + version: 1.4.0(@types/node@20.11.20)(jsdom@20.0.2)(sass@1.56.1) packages/connectors/connector-smtp: dependencies: @@ -2352,7 +2352,7 @@ importers: version: 15.2.3(rollup@4.12.0) '@rollup/plugin-typescript': specifier: ^11.1.6 - version: 11.1.6(rollup@4.12.0)(typescript@5.3.3) + version: 11.1.6(rollup@4.12.0)(tslib@2.6.2)(typescript@5.3.3) '@silverhand/eslint-config': specifier: 6.0.1 version: 6.0.1(eslint@8.57.0)(prettier@3.0.0)(typescript@5.3.3) @@ -2370,7 +2370,7 @@ importers: version: 6.0.2 '@vitest/coverage-v8': specifier: ^1.4.0 - version: 1.4.0(vitest@1.4.0) + version: 1.4.0(vitest@1.4.0(@types/node@20.11.20)(jsdom@20.0.2)(sass@1.56.1)) eslint: specifier: ^8.56.0 version: 8.57.0 @@ -2397,7 +2397,7 @@ importers: version: 5.3.3 vitest: specifier: ^1.4.0 - version: 1.4.0(@types/node@20.11.20) + version: 1.4.0(@types/node@20.11.20)(jsdom@20.0.2)(sass@1.56.1) packages/connectors/connector-tencent-sms: dependencies: @@ -2428,7 +2428,7 @@ importers: version: 15.2.3(rollup@4.12.0) '@rollup/plugin-typescript': specifier: ^11.1.6 - version: 11.1.6(rollup@4.12.0)(typescript@5.3.3) + version: 11.1.6(rollup@4.12.0)(tslib@2.6.2)(typescript@5.3.3) '@silverhand/eslint-config': specifier: 6.0.1 version: 6.0.1(eslint@8.57.0)(prettier@3.0.0)(typescript@5.3.3) @@ -2443,7 +2443,7 @@ importers: version: 6.0.2 '@vitest/coverage-v8': specifier: ^1.4.0 - version: 1.4.0(vitest@1.4.0) + version: 1.4.0(vitest@1.4.0(@types/node@20.11.20)(jsdom@20.0.2)(sass@1.56.1)) eslint: specifier: ^8.56.0 version: 8.57.0 @@ -2470,7 +2470,7 @@ importers: version: 5.3.3 vitest: specifier: ^1.4.0 - version: 1.4.0(@types/node@20.11.20) + version: 1.4.0(@types/node@20.11.20)(jsdom@20.0.2)(sass@1.56.1) packages/connectors/connector-twilio-sms: dependencies: @@ -2501,7 +2501,7 @@ importers: version: 15.2.3(rollup@4.12.0) '@rollup/plugin-typescript': specifier: ^11.1.6 - version: 11.1.6(rollup@4.12.0)(typescript@5.3.3) + version: 11.1.6(rollup@4.12.0)(tslib@2.6.2)(typescript@5.3.3) '@silverhand/eslint-config': specifier: 6.0.1 version: 6.0.1(eslint@8.57.0)(prettier@3.0.0)(typescript@5.3.3) @@ -2516,7 +2516,7 @@ importers: version: 6.0.2 '@vitest/coverage-v8': specifier: ^1.4.0 - version: 1.4.0(vitest@1.4.0) + version: 1.4.0(vitest@1.4.0(@types/node@20.11.20)(jsdom@20.0.2)(sass@1.56.1)) eslint: specifier: ^8.56.0 version: 8.57.0 @@ -2543,7 +2543,7 @@ importers: version: 5.3.3 vitest: specifier: ^1.4.0 - version: 1.4.0(@types/node@20.11.20) + version: 1.4.0(@types/node@20.11.20)(jsdom@20.0.2)(sass@1.56.1) packages/connectors/connector-wechat-native: dependencies: @@ -2574,7 +2574,7 @@ importers: version: 15.2.3(rollup@4.12.0) '@rollup/plugin-typescript': specifier: ^11.1.6 - version: 11.1.6(rollup@4.12.0)(typescript@5.3.3) + version: 11.1.6(rollup@4.12.0)(tslib@2.6.2)(typescript@5.3.3) '@silverhand/eslint-config': specifier: 6.0.1 version: 6.0.1(eslint@8.57.0)(prettier@3.0.0)(typescript@5.3.3) @@ -2589,7 +2589,7 @@ importers: version: 6.0.2 '@vitest/coverage-v8': specifier: ^1.4.0 - version: 1.4.0(vitest@1.4.0) + version: 1.4.0(vitest@1.4.0(@types/node@20.11.20)(jsdom@20.0.2)(sass@1.56.1)) eslint: specifier: ^8.56.0 version: 8.57.0 @@ -2616,7 +2616,7 @@ importers: version: 5.3.3 vitest: specifier: ^1.4.0 - version: 1.4.0(@types/node@20.11.20) + version: 1.4.0(@types/node@20.11.20)(jsdom@20.0.2)(sass@1.56.1) packages/connectors/connector-wechat-web: dependencies: @@ -2647,7 +2647,7 @@ importers: version: 15.2.3(rollup@4.12.0) '@rollup/plugin-typescript': specifier: ^11.1.6 - version: 11.1.6(rollup@4.12.0)(typescript@5.3.3) + version: 11.1.6(rollup@4.12.0)(tslib@2.6.2)(typescript@5.3.3) '@silverhand/eslint-config': specifier: 6.0.1 version: 6.0.1(eslint@8.57.0)(prettier@3.0.0)(typescript@5.3.3) @@ -2662,7 +2662,7 @@ importers: version: 6.0.2 '@vitest/coverage-v8': specifier: ^1.4.0 - version: 1.4.0(vitest@1.4.0) + version: 1.4.0(vitest@1.4.0(@types/node@20.11.20)(jsdom@20.0.2)(sass@1.56.1)) eslint: specifier: ^8.56.0 version: 8.57.0 @@ -2689,7 +2689,7 @@ importers: version: 5.3.3 vitest: specifier: ^1.4.0 - version: 1.4.0(@types/node@20.11.20) + version: 1.4.0(@types/node@20.11.20)(jsdom@20.0.2)(sass@1.56.1) packages/connectors/connector-wecom: dependencies: @@ -2720,7 +2720,7 @@ importers: version: 15.2.3(rollup@4.12.0) '@rollup/plugin-typescript': specifier: ^11.1.6 - version: 11.1.6(rollup@4.12.0)(typescript@5.3.3) + version: 11.1.6(rollup@4.12.0)(tslib@2.6.2)(typescript@5.3.3) '@silverhand/eslint-config': specifier: 6.0.1 version: 6.0.1(eslint@8.57.0)(prettier@3.0.0)(typescript@5.3.3) @@ -2735,7 +2735,7 @@ importers: version: 6.0.2 '@vitest/coverage-v8': specifier: ^1.4.0 - version: 1.4.0(vitest@1.4.0) + version: 1.4.0(vitest@1.4.0(@types/node@20.10.4)(jsdom@20.0.2)(sass@1.56.1)) eslint: specifier: ^8.56.0 version: 8.57.0 @@ -2762,7 +2762,7 @@ importers: version: 5.3.3 vitest: specifier: ^1.4.0 - version: 1.4.0(@types/node@20.10.4) + version: 1.4.0(@types/node@20.10.4)(jsdom@20.0.2)(sass@1.56.1) packages/console: devDependencies: @@ -2804,7 +2804,7 @@ importers: version: 1.6.22(react@18.2.0) '@monaco-editor/react': specifier: ^4.6.0 - version: 4.6.0(monaco-editor@0.47.0)(react-dom@18.2.0)(react@18.2.0) + version: 4.6.0(monaco-editor@0.47.0)(react-dom@18.2.0(react@18.2.0))(react@18.2.0) '@parcel/compressor-brotli': specifier: 2.9.3 version: 2.9.3(@parcel/core@2.9.3) @@ -2816,7 +2816,7 @@ importers: version: 2.9.3 '@parcel/transformer-mdx': specifier: 2.9.3 - version: 2.9.3(@mdx-js/react@1.6.22)(@parcel/core@2.9.3) + version: 2.9.3(@mdx-js/react@1.6.22(react@18.2.0))(@parcel/core@2.9.3) '@parcel/transformer-sass': specifier: 2.9.3 version: 2.9.3(@parcel/core@2.9.3) @@ -2828,7 +2828,7 @@ importers: version: 6.0.1(eslint@8.57.0)(prettier@3.0.0)(typescript@5.3.3) '@silverhand/eslint-config-react': specifier: 6.0.2 - version: 6.0.2(eslint@8.57.0)(postcss@8.4.31)(prettier@3.0.0)(stylelint@15.11.0)(typescript@5.3.3) + version: 6.0.2(eslint@8.57.0)(postcss@8.4.31)(prettier@3.0.0)(stylelint@15.11.0(typescript@5.3.3))(typescript@5.3.3) '@silverhand/essentials': specifier: ^2.9.0 version: 2.9.0 @@ -2840,13 +2840,13 @@ importers: version: 6.0.0(typescript@5.3.3) '@swc/core': specifier: ^1.3.52 - version: 1.3.52 + version: 1.3.52(@swc/helpers@0.5.1) '@swc/jest': specifier: ^0.2.26 - version: 0.2.26(@swc/core@1.3.52) + version: 0.2.26(@swc/core@1.3.52(@swc/helpers@0.5.1)) '@testing-library/react': specifier: ^15.0.0 - version: 15.0.2(react-dom@18.2.0)(react@18.2.0) + version: 15.0.2(react-dom@18.2.0(react@18.2.0))(react@18.2.0) '@types/color': specifier: ^3.0.3 version: 3.0.3 @@ -2933,7 +2933,7 @@ importers: version: 3.0.0 jest: specifier: ^29.7.0 - version: 29.7.0(@types/node@20.12.7)(ts-node@10.9.2) + version: 29.7.0(@types/node@20.12.7)(ts-node@10.9.2(@swc/core@1.3.52(@swc/helpers@0.5.1))(@types/node@20.12.7)(typescript@5.3.3)) jest-environment-jsdom: specifier: ^29.0.0 version: 29.2.2 @@ -2942,7 +2942,7 @@ importers: version: 2.0.0 jest-transformer-svg: specifier: ^2.0.0 - version: 2.0.0(jest@29.7.0)(react@18.2.0) + version: 2.0.0(jest@29.7.0(@types/node@20.12.7)(ts-node@10.9.2(@swc/core@1.3.52(@swc/helpers@0.5.1))(@types/node@20.12.7)(typescript@5.3.3)))(react@18.2.0) just-kebab-case: specifier: ^4.2.0 version: 4.2.0 @@ -2966,7 +2966,7 @@ importers: version: 0.5.0(overlayscrollbars@2.0.3)(react@18.2.0) parcel: specifier: 2.9.3 - version: 2.9.3(postcss@8.4.31) + version: 2.9.3(@swc/helpers@0.5.1)(postcss@8.4.31)(srcset@4.0.0) postcss: specifier: ^8.4.31 version: 8.4.31 @@ -2990,7 +2990,7 @@ importers: version: 18.2.0 react-animate-height: specifier: ^3.0.4 - version: 3.0.4(react-dom@18.2.0)(react@18.2.0) + version: 3.0.4(react-dom@18.2.0(react@18.2.0))(react@18.2.0) react-color: specifier: ^2.19.3 version: 2.19.3(react@18.2.0) @@ -3017,31 +3017,31 @@ importers: version: 7.43.9(react@18.2.0) react-hot-toast: specifier: ^2.2.0 - version: 2.2.0(csstype@3.0.11)(react-dom@18.2.0)(react@18.2.0) + version: 2.2.0(csstype@3.0.11)(react-dom@18.2.0(react@18.2.0))(react@18.2.0) react-i18next: specifier: ^12.3.1 - version: 12.3.1(i18next@22.4.15)(react-dom@18.2.0)(react@18.2.0) + version: 12.3.1(i18next@22.4.15)(react-dom@18.2.0(react@18.2.0))(react@18.2.0) react-markdown: specifier: ^9.0.0 version: 9.0.0(@types/react@18.0.31)(react@18.2.0) react-modal: specifier: ^3.15.1 - version: 3.15.1(react-dom@18.2.0)(react@18.2.0) + version: 3.15.1(react-dom@18.2.0(react@18.2.0))(react@18.2.0) react-paginate: specifier: ^8.1.3 version: 8.1.3(react@18.2.0) react-router-dom: specifier: ^6.10.0 - version: 6.10.0(react-dom@18.2.0)(react@18.2.0) + version: 6.10.0(react-dom@18.2.0(react@18.2.0))(react@18.2.0) react-syntax-highlighter: specifier: ^15.5.0 version: 15.5.0(react@18.2.0) react-timer-hook: specifier: ^3.0.5 - version: 3.0.5(react-dom@18.2.0)(react@18.2.0) + version: 3.0.5(react-dom@18.2.0(react@18.2.0))(react@18.2.0) recharts: specifier: ^2.1.13 - version: 2.1.13(prop-types@15.8.1)(react-dom@18.2.0)(react@18.2.0) + version: 2.1.13(prop-types@15.8.1)(react-dom@18.2.0(react@18.2.0))(react@18.2.0) remark-gfm: specifier: ^4.0.0 version: 4.0.0 @@ -3056,7 +3056,7 @@ importers: version: 4.0.0 ts-node: specifier: ^10.9.2 - version: 10.9.2(@swc/core@1.3.52)(@types/node@20.12.7)(typescript@5.3.3) + version: 10.9.2(@swc/core@1.3.52(@swc/helpers@0.5.1))(@types/node@20.12.7)(typescript@5.3.3) tslib: specifier: ^2.4.1 version: 2.4.1 @@ -3336,7 +3336,7 @@ importers: version: 8.57.0 jest: specifier: ^29.7.0 - version: 29.7.0(@types/node@20.10.4) + version: 29.7.0(@types/node@20.10.4)(ts-node@10.9.2(@types/node@20.10.4)(typescript@5.3.3)) jest-matcher-specific-error: specifier: ^1.0.0 version: 1.0.0 @@ -3402,7 +3402,7 @@ importers: version: 6.0.1(eslint@8.57.0)(prettier@3.0.0)(typescript@5.3.3) '@silverhand/eslint-config-react': specifier: 6.0.2 - version: 6.0.2(eslint@8.57.0)(postcss@8.4.31)(prettier@3.0.0)(stylelint@15.11.0)(typescript@5.3.3) + version: 6.0.2(eslint@8.57.0)(postcss@8.4.31)(prettier@3.0.0)(stylelint@15.11.0(typescript@5.3.3))(typescript@5.3.3) '@silverhand/ts-config': specifier: 6.0.0 version: 6.0.0(typescript@5.3.3) @@ -3435,7 +3435,7 @@ importers: version: 15.0.2 parcel: specifier: 2.9.3 - version: 2.9.3(postcss@8.4.31) + version: 2.9.3(@swc/helpers@0.5.1)(postcss@8.4.31)(srcset@4.0.0) postcss: specifier: ^8.4.31 version: 8.4.31 @@ -3450,7 +3450,7 @@ importers: version: 18.2.0(react@18.2.0) react-i18next: specifier: ^12.3.1 - version: 12.3.1(i18next@22.4.15)(react-dom@18.2.0)(react@18.2.0) + version: 12.3.1(i18next@22.4.15)(react-dom@18.2.0(react@18.2.0))(react@18.2.0) stylelint: specifier: ^15.0.0 version: 15.11.0(typescript@5.3.3) @@ -3504,13 +3504,13 @@ importers: version: 9.6.1(react@18.2.0) '@react-spring/web': specifier: ^9.6.1 - version: 9.6.1(react-dom@18.2.0)(react@18.2.0) + version: 9.6.1(react-dom@18.2.0(react@18.2.0))(react@18.2.0) '@silverhand/eslint-config': specifier: 6.0.1 version: 6.0.1(eslint@8.57.0)(prettier@3.0.0)(typescript@5.3.3) '@silverhand/eslint-config-react': specifier: 6.0.2 - version: 6.0.2(eslint@8.57.0)(postcss@8.4.31)(prettier@3.0.0)(stylelint@15.11.0)(typescript@5.3.3) + version: 6.0.2(eslint@8.57.0)(postcss@8.4.31)(prettier@3.0.0)(stylelint@15.11.0(typescript@5.3.3))(typescript@5.3.3) '@silverhand/essentials': specifier: ^2.9.0 version: 2.9.0 @@ -3528,16 +3528,16 @@ importers: version: 9.0.1 '@swc/core': specifier: ^1.3.52 - version: 1.3.52 + version: 1.3.52(@swc/helpers@0.5.1) '@swc/jest': specifier: ^0.2.26 - version: 0.2.26(@swc/core@1.3.52) + version: 0.2.26(@swc/core@1.3.52(@swc/helpers@0.5.1)) '@testing-library/react': specifier: ^15.0.0 - version: 15.0.2(react-dom@18.2.0)(react@18.2.0) + version: 15.0.2(react-dom@18.2.0(react@18.2.0))(react@18.2.0) '@testing-library/react-hooks': specifier: ^8.0.1 - version: 8.0.1(@types/react@18.0.31)(react-dom@18.2.0)(react@18.2.0) + version: 8.0.1(@types/react@18.0.31)(react-dom@18.2.0(react@18.2.0))(react@18.2.0) '@types/color': specifier: ^3.0.3 version: 3.0.3 @@ -3588,7 +3588,7 @@ importers: version: 3.0.0 jest: specifier: ^29.7.0 - version: 29.7.0(@types/node@20.12.7) + version: 29.7.0(@types/node@20.12.7)(ts-node@10.9.2(@swc/core@1.3.52(@swc/helpers@0.5.1))(@types/node@20.12.7)(typescript@5.3.3)) jest-environment-jsdom: specifier: ^29.0.0 version: 29.2.2 @@ -3597,7 +3597,7 @@ importers: version: 2.0.0 jest-transformer-svg: specifier: ^2.0.0 - version: 2.0.0(jest@29.7.0)(react@18.2.0) + version: 2.0.0(jest@29.7.0(@types/node@20.12.7)(ts-node@10.9.2(@swc/core@1.3.52(@swc/helpers@0.5.1))(@types/node@20.12.7)(typescript@5.3.3)))(react@18.2.0) js-base64: specifier: ^3.7.5 version: 3.7.5 @@ -3612,10 +3612,10 @@ importers: version: 15.0.2 parcel: specifier: 2.9.3 - version: 2.9.3(postcss@8.4.31) + version: 2.9.3(@swc/helpers@0.5.1)(postcss@8.4.31)(srcset@4.0.0) parcel-resolver-ignore: specifier: ^2.1.3 - version: 2.1.3(parcel@2.9.3) + version: 2.1.3(parcel@2.9.3(@swc/helpers@0.5.1)(postcss@8.4.31)(srcset@4.0.0)) postcss: specifier: ^8.4.31 version: 8.4.31 @@ -3630,7 +3630,7 @@ importers: version: 18.2.0 react-device-detect: specifier: ^2.2.3 - version: 2.2.3(react-dom@18.2.0)(react@18.2.0) + version: 2.2.3(react-dom@18.2.0(react@18.2.0))(react@18.2.0) react-dom: specifier: ^18.0.0 version: 18.2.0(react@18.2.0) @@ -3642,19 +3642,19 @@ importers: version: 7.34.0(react@18.2.0) react-i18next: specifier: ^12.3.1 - version: 12.3.1(i18next@22.4.15)(react-dom@18.2.0)(react@18.2.0) + version: 12.3.1(i18next@22.4.15)(react-dom@18.2.0(react@18.2.0))(react@18.2.0) react-modal: specifier: ^3.15.1 - version: 3.15.1(react-dom@18.2.0)(react@18.2.0) + version: 3.15.1(react-dom@18.2.0(react@18.2.0))(react@18.2.0) react-router-dom: specifier: ^6.10.0 - version: 6.10.0(react-dom@18.2.0)(react@18.2.0) + version: 6.10.0(react-dom@18.2.0(react@18.2.0))(react@18.2.0) react-string-replace: specifier: ^1.0.0 version: 1.0.0 react-timer-hook: specifier: ^3.0.5 - version: 3.0.5(react-dom@18.2.0)(react@18.2.0) + version: 3.0.5(react-dom@18.2.0(react@18.2.0))(react@18.2.0) react-top-loading-bar: specifier: ^2.3.1 version: 2.3.1(react@18.2.0) @@ -3736,13 +3736,13 @@ importers: version: 10.0.0 jest: specifier: ^29.7.0 - version: 29.7.0(@types/node@20.10.4) + version: 29.7.0(@types/node@20.10.4)(ts-node@10.9.2(@types/node@20.10.4)(typescript@5.3.3)) jest-matcher-specific-error: specifier: ^1.0.0 version: 1.0.0 jest-puppeteer: specifier: ^10.0.1 - version: 10.0.1(puppeteer@22.6.5)(typescript@5.3.3) + version: 10.0.1(puppeteer@22.6.5(typescript@5.3.3))(typescript@5.3.3) jose: specifier: ^5.0.0 version: 5.0.1 @@ -3886,7 +3886,7 @@ importers: version: 0.0.33 '@vitest/coverage-v8': specifier: ^1.4.0 - version: 1.4.0(vitest@1.4.0) + version: 1.4.0(vitest@1.4.0(@types/node@20.10.4)(jsdom@20.0.2)(sass@1.56.1)) camelcase: specifier: ^8.0.0 version: 8.0.0 @@ -3913,7 +3913,7 @@ importers: version: 5.3.3 vitest: specifier: ^1.4.0 - version: 1.4.0(@types/node@20.10.4) + version: 1.4.0(@types/node@20.10.4)(jsdom@20.0.2)(sass@1.56.1) packages/shared: dependencies: @@ -3947,7 +3947,7 @@ importers: version: 20.10.4 '@vitest/coverage-v8': specifier: ^1.4.0 - version: 1.4.0(vitest@1.4.0) + version: 1.4.0(vitest@1.4.0(@types/node@20.10.4)(jsdom@20.0.2)(sass@1.56.1)) eslint: specifier: ^8.56.0 version: 8.57.0 @@ -3962,7 +3962,7 @@ importers: version: 5.3.3 vitest: specifier: ^1.4.0 - version: 1.4.0(@types/node@20.10.4) + version: 1.4.0(@types/node@20.10.4)(jsdom@20.0.2)(sass@1.56.1) packages/toolkit/connector-kit: dependencies: @@ -3994,7 +3994,7 @@ importers: version: 20.10.4 '@vitest/coverage-v8': specifier: ^1.4.0 - version: 1.4.0(vitest@1.4.0) + version: 1.4.0(vitest@1.4.0(@types/node@20.10.4)(jsdom@20.0.2)(sass@1.56.1)) eslint: specifier: ^8.56.0 version: 8.57.0 @@ -4009,7 +4009,7 @@ importers: version: 5.3.3 vitest: specifier: ^1.4.0 - version: 1.4.0(@types/node@20.10.4) + version: 1.4.0(@types/node@20.10.4)(jsdom@20.0.2)(sass@1.56.1) packages/toolkit/core-kit: dependencies: @@ -4035,7 +4035,7 @@ importers: version: 6.0.1(eslint@8.57.0)(prettier@3.0.0)(typescript@5.3.3) '@silverhand/eslint-config-react': specifier: 6.0.2 - version: 6.0.2(eslint@8.57.0)(postcss@8.4.31)(prettier@3.0.0)(stylelint@15.11.0)(typescript@5.3.3) + version: 6.0.2(eslint@8.57.0)(postcss@8.4.31)(prettier@3.0.0)(stylelint@15.11.0(typescript@5.3.3))(typescript@5.3.3) '@silverhand/ts-config': specifier: 6.0.0 version: 6.0.0(typescript@5.3.3) @@ -4053,7 +4053,7 @@ importers: version: 18.0.31 '@vitest/coverage-v8': specifier: ^1.4.0 - version: 1.4.0(vitest@1.4.0) + version: 1.4.0(vitest@1.4.0(@types/node@20.10.4)(jsdom@20.0.2)(sass@1.56.1)) eslint: specifier: ^8.56.0 version: 8.57.0 @@ -4074,7 +4074,7 @@ importers: version: 5.3.3 vitest: specifier: ^1.4.0 - version: 1.4.0(@types/node@20.10.4) + version: 1.4.0(@types/node@20.10.4)(jsdom@20.0.2)(sass@1.56.1) packages/toolkit/language-kit: optionalDependencies: @@ -4093,7 +4093,7 @@ importers: version: 20.10.4 '@vitest/coverage-v8': specifier: ^1.4.0 - version: 1.4.0(vitest@1.4.0) + version: 1.4.0(vitest@1.4.0(@types/node@20.10.4)(jsdom@20.0.2)(sass@1.56.1)) eslint: specifier: ^8.56.0 version: 8.57.0 @@ -4108,7 +4108,7 @@ importers: version: 5.3.3 vitest: specifier: ^1.4.0 - version: 1.4.0(@types/node@20.10.4) + version: 1.4.0(@types/node@20.10.4)(jsdom@20.0.2)(sass@1.56.1) packages: @@ -5215,7 +5215,7 @@ packages: '@logto/react@3.0.8': resolution: {integrity: sha512-p3pV4rX4g8ZwHQ159mxI+pP3Bwome47dNEmP1hI8/10WqdIPXGYTnfYn5c2l4Y2DyslYyK3ur2Sy4i4K6ept9A==} peerDependencies: - react: '>=16.8.0 || ^18.0.0' + react: '>=16.8.0' '@manypkg/find-root@1.1.0': resolution: {integrity: sha512-mki5uBvhHzO8kYYix/WRy2WX8S3B5wdVSc9D6KcU5lQNglP2yt58/VfLuAK49glRXChosY8ap2oJ1qgma3GUVA==} @@ -5229,7 +5229,7 @@ packages: '@mdx-js/react@1.6.22': resolution: {integrity: sha512-TDoPum4SHdfPiGSAaRBw7ECyI8VaHpK8GJugbJIJuqyh6kzw9ZLJZW3HGL3NNrJGxcAixUvqROm+YuQOo5eXtg==} peerDependencies: - react: ^16.13.1 || ^17.0.0 || ^18.0.0 + react: ^16.13.1 || ^17.0.0 '@mdx-js/util@1.6.22': resolution: {integrity: sha512-H1rQc1ZOHANWBvPcW+JpGwr+juXSxM8Q8YCkm3GhZd8REu1fHR3z99CErO1p9pkcfcxZnMdIZdIsXkOHY0NilA==} @@ -5898,7 +5898,7 @@ packages: resolution: {integrity: sha512-4PqhypLqrX5FVXimKBz3S1c+usDns3N/XG66n2FQtO1FIa8WUVw1CsuWHT+tkqeIxDR1PRQX1e8Iwyy7vPclPA==} engines: {node: ^20.9.0} peerDependencies: - stylelint: ^15.0.0 || ^16.0.0 + stylelint: ^15.0.0 '@silverhand/eslint-config@6.0.1': resolution: {integrity: sha512-v7VbAiNgVwcjwGXe4LK6qNVKgltcm4XX9dkYgyaD22vcYCtp1BSd8NVsPDISV1nAwwirCklL0KSDtcD7pxkbHw==} @@ -6334,7 +6334,7 @@ packages: engines: {node: '>=12'} peerDependencies: '@types/react': ^16.9.0 || ^17.0.0 - react: ^16.9.0 || ^17.0.0 || ^18.0.0 + react: ^16.9.0 || ^17.0.0 react-dom: ^16.9.0 || ^17.0.0 react-test-renderer: ^16.9.0 || ^17.0.0 peerDependenciesMeta: @@ -9577,7 +9577,7 @@ packages: jest-transformer-svg@2.0.0: resolution: {integrity: sha512-+f6er7UZTiHTeel9nma1i0NTAU8AjbEvhK2RYUoMxTNihwo98z2rrrDBIbppZI6ACDzeul3bhRmI9M6d25J/Nw==} peerDependencies: - jest: ^28.1.0 || ^29.1.2 + jest: ^28.1.0 react: ^17.0.0 || ^18.0.0 jest-util@29.5.0: @@ -10675,7 +10675,7 @@ packages: resolution: {integrity: sha512-uCNTnkfWW74veoiEv3kSwoLelKt4e8gTNv65D771X3il0x5g5Yo0fUbro7SpQzR9yNgi23cvB2mQHTTdQH96pA==} peerDependencies: overlayscrollbars: ^2.0.0 - react: '>=16.8.0 || ^18.0.0' + react: '>=16.8.0' overlayscrollbars@2.0.3: resolution: {integrity: sha512-boOkJFER1Tc21sxF4a7ghGl+ETV3WtP7YgsUyDPo1VTHUIPdQLfnTzMyOOdMkKkVcpJOYMKwwr4m+saCtgawCg==} @@ -10772,9 +10772,6 @@ packages: resolution: {integrity: sha512-2GTVocFkwblV/TIg9AmT7TI2fO4xdWkyN8aFUEVtiVNWt96GTR3FgQyHFValfCbcj1k9Xf962Ws2hYXYUr9k1Q==} engines: {node: '>= 12.0.0'} hasBin: true - peerDependenciesMeta: - '@parcel/core': - optional: true parent-module@1.0.1: resolution: {integrity: sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==} @@ -11257,7 +11254,7 @@ packages: resolution: {integrity: sha512-k+mBS8yCzpFp+7BdrHsL5bXd6CO/2bYO2SvRGKfxK+Ss3nzplAJLlgnd6Zhcxe/avdpy/CgcziicFj7pIHgG5g==} engines: {node: '>= 12.0.0'} peerDependencies: - react: '>=16.8.0 || ^18.0.0' + react: '>=16.8.0' react-dom: '>=16.8.0' react-color@2.19.3: @@ -11274,7 +11271,7 @@ packages: react-device-detect@2.2.3: resolution: {integrity: sha512-buYY3qrCnQVlIFHrC5UcUoAj7iANs/+srdkwsnNjI7anr3Tt7UY6MqNxtMLlr0tMBied0O49UZVK8XKs3ZIiPw==} peerDependencies: - react: '>= 0.14.0 || ^18.0.0' + react: '>= 0.14.0' react-dom: '>= 0.14.0' react-dnd-html5-backend@16.0.0: @@ -11286,7 +11283,7 @@ packages: '@types/hoist-non-react-statics': '>= 3.3.1' '@types/node': '>= 12' '@types/react': '>= 16' - react: '>= 16.14 || ^18.0.0' + react: '>= 16.14' peerDependenciesMeta: '@types/hoist-non-react-statics': optional: true @@ -11298,19 +11295,19 @@ packages: react-dom@18.2.0: resolution: {integrity: sha512-6IMTriUmvsjHUjNtEDudZfuDQUoWXVxKHhlEGSk81n4YFS+r/Kl99wXiwlVXtPBtJenozv2P+hxDsw9eA7Xo6g==} peerDependencies: - react: ^18.2.0 || ^18.0.0 + react: ^18.2.0 react-dropzone@14.2.3: resolution: {integrity: sha512-O3om8I+PkFKbxCukfIR3QAGftYXDZfOE2N1mr/7qebQJHs7U+/RSL/9xomJNpRg9kM5h9soQSdf0Gc7OHF5Fug==} engines: {node: '>= 10.13'} peerDependencies: - react: '>= 16.8 || 18.0.0 || ^18.0.0' + react: '>= 16.8 || 18.0.0' react-error-boundary@3.1.4: resolution: {integrity: sha512-uM9uPzZJTF6wRQORmSrvOIgt4lJ9MC1sNgEOj2XGsDTRE4kmpWxg7ENK9EWNKJRMAOY9z0MuF4yIfl6gp4sotA==} engines: {node: '>=10', npm: '>=6'} peerDependencies: - react: '>=16.13.1 || ^18.0.0' + react: '>=16.13.1' react-error-overlay@6.0.9: resolution: {integrity: sha512-nQTTcUu+ATDbrSD1BZHr5kgSD4oF8OFjxun8uAaL8RwPBacGBNPf/yAuVVdx17N8XNzRDMrZ9XcKZHCjPW+9ew==} @@ -11321,32 +11318,32 @@ packages: react-helmet@6.1.0: resolution: {integrity: sha512-4uMzEY9nlDlgxr61NL3XbKRy1hEkXmKNXhjbAIOVw5vcFrsdYbH2FEwcNyWvWinl103nXgzYNlns9ca+8kFiWw==} peerDependencies: - react: '>=16.3.0 || ^18.0.0' + react: '>=16.3.0' react-hook-form@7.34.0: resolution: {integrity: sha512-s0/TJ09NVlEk2JPp3yit1WnMuPNBXFmUKEQPulgDi9pYBw/ZmmAFHe6AXWq73Y+kp8ye4OcMf0Jv+i/qLPektg==} engines: {node: '>=12.22.0'} peerDependencies: - react: ^16.8.0 || ^17 || ^18 || ^18.0.0 + react: ^16.8.0 || ^17 || ^18 react-hook-form@7.43.9: resolution: {integrity: sha512-AUDN3Pz2NSeoxQ7Hs6OhQhDr6gtF9YRuutGDwPQqhSUAHJSgGl2VeY3qN19MG0SucpjgDiuMJ4iC5T5uB+eaNQ==} engines: {node: '>=12.22.0'} peerDependencies: - react: ^16.8.0 || ^17 || ^18 || ^18.0.0 + react: ^16.8.0 || ^17 || ^18 react-hot-toast@2.2.0: resolution: {integrity: sha512-248rXw13uhf/6TNDVzagX+y7R8J183rp7MwUMNkcrBRyHj/jWOggfXTGlM8zAOuh701WyVW+eUaWG2LeSufX9g==} engines: {node: '>=10'} peerDependencies: - react: '>=16 || ^18.0.0' + react: '>=16' react-dom: '>=16' react-i18next@12.3.1: resolution: {integrity: sha512-5v8E2XjZDFzK7K87eSwC7AJcAkcLt5xYZ4+yTPDAW1i7C93oOY1dnr4BaQM7un4Hm+GmghuiPvevWwlca5PwDA==} peerDependencies: i18next: '>= 19.0.0' - react: '>= 16.8.0 || ^18.0.0' + react: '>= 16.8.0' react-dom: '*' react-native: '*' peerDependenciesMeta: @@ -11371,19 +11368,19 @@ packages: resolution: {integrity: sha512-v6yNf3AB8GfJ8lCpUvzxAXKxgsHpdmWPlcVRQ6Nocsezp255E/IDrF31kLQsPJeB/cKto/geUwjU36wH784FCA==} peerDependencies: '@types/react': '>=18' - react: '>=18 || ^18.0.0' + react: '>=18' react-modal@3.15.1: resolution: {integrity: sha512-duB9bxOaYg7Zt6TMFldIFxQRtSP+Dg3F1ZX3FXxSUn+3tZZ/9JCgeAQKDg7rhZSAqopq8TFRw3yIbnx77gyFTw==} engines: {node: '>=8'} peerDependencies: - react: ^0.14.0 || ^15.0.0 || ^16 || ^17 || ^18 || ^18.0.0 + react: ^0.14.0 || ^15.0.0 || ^16 || ^17 || ^18 react-dom: ^0.14.0 || ^15.0.0 || ^16 || ^17 || ^18 react-paginate@8.1.3: resolution: {integrity: sha512-zBp80DBRcaeBnAeHUfbGKD0XHfbGNUolQ+S60Ymfs8o7rusYaJYZMAt1j93ADDNLlzRmJ0tMF/NeTlcdKf7dlQ==} peerDependencies: - react: ^16 || ^17 || ^18 || ^18.0.0 + react: ^16 || ^17 || ^18 react-refresh@0.9.0: resolution: {integrity: sha512-Gvzk7OZpiqKSkxsQvO/mbTN1poglhmAV7gR/DdIrRrSMXraRQQlfikRJOr3Nb9GTMPC5kof948Zy6jJZIFtDvQ==} @@ -11399,14 +11396,14 @@ packages: resolution: {integrity: sha512-E5dfxRPuXKJqzwSe/qGcqdwa18QiWC6f3H3cWXM24qj4N0/beCIf/CWTipop2xm7mR0RCS99NnaqPNjHtrAzCg==} engines: {node: '>=14'} peerDependencies: - react: '>=16.8 || ^18.0.0' + react: '>=16.8' react-dom: '>=16.8' react-router@6.10.0: resolution: {integrity: sha512-Nrg0BWpQqrC3ZFFkyewrflCud9dio9ME3ojHCF/WLsprJVzkq3q3UeEhMCAW1dobjeGbWgjNn/PVF6m46ANxXQ==} engines: {node: '>=14'} peerDependencies: - react: '>=16.8 || ^18.0.0' + react: '>=16.8' react-side-effect@2.1.2: resolution: {integrity: sha512-PVjOcvVOyIILrYoyGEpDN3vmYNLdy1CajSFNt4TDsVQC5KpTijDvWVoR+/7Rz2xT978D8/ZtFceXxzsPwZEDvw==} @@ -11427,24 +11424,24 @@ packages: react-syntax-highlighter@15.5.0: resolution: {integrity: sha512-+zq2myprEnQmH5yw6Gqc8lD55QHnpKaU8TOcFeC/Lg/MQSs8UknEA0JC4nTZGFAXC2J2Hyj/ijJ7NlabyPi2gg==} peerDependencies: - react: '>= 0.14.0 || ^18.0.0' + react: '>= 0.14.0' react-timer-hook@3.0.5: resolution: {integrity: sha512-n+98SdmYvui2ne3KyWb3Ldu4k0NYQa3g/VzW6VEIfZJ8GAk/jJsIY700M8Nd2vNSTj05c7wKyQfJBqZ0x7zfiA==} peerDependencies: - react: '>=16.8.0 || ^18.0.0' + react: '>=16.8.0' react-dom: '>=16.8.0' react-top-loading-bar@2.3.1: resolution: {integrity: sha512-rQk2Nm+TOBrM1C4E3e6KwT65iXyRSgBHjCkr2FNja1S51WaPulRA5nKj/xazuQ3x89wDDdGsrqkqy0RBIfd0xg==} engines: {node: '>=10'} peerDependencies: - react: ^16 || ^17 || ^18 || ^18.0.0 + react: ^16 || ^17 || ^18 react-transition-group@2.9.0: resolution: {integrity: sha512-+HzNTCHpeQyl4MJ/bdE0u6XRMe9+XG/+aL4mCxVN4DnPBQ0/5bfHWPDuOZUzYdMj94daZaZdCCc1Dzt9R/xSSg==} peerDependencies: - react: '>=15.0.0 || ^18.0.0' + react: '>=15.0.0' react-dom: '>=15.0.0' react@18.2.0: @@ -12100,7 +12097,7 @@ packages: resolution: {integrity: sha512-E4IoDwgJqG+Q3LjeZGXNi3uOXOH5Sx6mCyxp1V4eaAm1DhuA+3X40c2GtobEIHfCv6itN/T3QKRb4V4/snIxUg==} engines: {node: '>=16'} peerDependencies: - stylelint: '>=14 || ^16.0.0' + stylelint: '>=14' stylelint-declaration-block-no-ignored-properties@2.8.0: resolution: {integrity: sha512-Ws8Cav7Y+SPN0JsV407LrnNXWOrqGjxShf+37GBtnU/C58Syve9c0+I/xpLcFOosST3ternykn3Lp77f3ITnFw==} @@ -12111,13 +12108,13 @@ packages: stylelint-order@6.0.4: resolution: {integrity: sha512-0UuKo4+s1hgQ/uAxlYU4h0o0HS4NiQDud0NAUNI0aa8FJdmYHA5ZZTFHiV5FpmE3071e9pZx5j0QpVJW5zOCUA==} peerDependencies: - stylelint: ^14.0.0 || ^15.0.0 || ^16.0.1 || ^16.0.0 + stylelint: ^14.0.0 || ^15.0.0 || ^16.0.1 stylelint-scss@6.2.1: resolution: {integrity: sha512-ZoGLbVb1keZYRVGQlhB8G6sZOoNqw61whzzzGFWp05N12ErqLFfBv3JPrXiMLZaW98sBS7K/vUQhRnvUj4vwdw==} engines: {node: '>=18.12.0'} peerDependencies: - stylelint: ^16.0.2 || ^16.0.0 + stylelint: ^16.0.2 stylelint@15.11.0: resolution: {integrity: sha512-78O4c6IswZ9TzpcIiQJIN49K3qNoXTM8zEJzhaTE/xRTCZswaovSEVIa/uwbOltZrk16X4jAxjaOhzz/hTm1Kw==} @@ -12560,7 +12557,7 @@ packages: resolution: {integrity: sha512-FbY/ynor7wZV55v1EvvAvu8CvSoEKT1azS2zFb/aLlL0vySbqTM7x9fIcaOJN++E52mVINNDe2VmWWd+Q00S+A==} engines: {node: '>=10'} peerDependencies: - react: '>=16 || ^18.0.0' + react: '>=16' use-sync-external-store@1.2.0: resolution: {integrity: sha512-eEgnFxGQ1Ife9bzYs6VLi8/4X6CObHMw9Qr9tPY43iKwsPw8xE8+EFsf/2cFZ5S3esXgpWgtSCtLNS41F+sKPA==} @@ -14157,7 +14154,7 @@ snapshots: '@commitlint/types': 19.0.3 chalk: 5.3.0 cosmiconfig: 8.3.6(typescript@5.0.2) - cosmiconfig-typescript-loader: 5.0.0(@types/node@20.12.7)(cosmiconfig@8.3.6)(typescript@5.0.2) + cosmiconfig-typescript-loader: 5.0.0(@types/node@20.12.7)(cosmiconfig@8.3.6(typescript@5.0.2))(typescript@5.0.2) lodash.isplainobject: 4.0.6 lodash.merge: 4.6.2 lodash.uniq: 4.5.0 @@ -14218,7 +14215,7 @@ snapshots: '@csstools/css-tokenizer@2.2.4': {} - '@csstools/media-query-list-parser@2.1.9(@csstools/css-parser-algorithms@2.6.1)(@csstools/css-tokenizer@2.2.4)': + '@csstools/media-query-list-parser@2.1.9(@csstools/css-parser-algorithms@2.6.1(@csstools/css-tokenizer@2.2.4))(@csstools/css-tokenizer@2.2.4)': dependencies: '@csstools/css-parser-algorithms': 2.6.1(@csstools/css-tokenizer@2.2.4) '@csstools/css-tokenizer': 2.2.4 @@ -14416,7 +14413,7 @@ snapshots: jest-util: 29.7.0 slash: 3.0.0 - '@jest/core@29.7.0(ts-node@10.9.2)': + '@jest/core@29.7.0(ts-node@10.9.2(@swc/core@1.3.52(@swc/helpers@0.5.1))(@types/node@20.12.7)(typescript@5.3.3))': dependencies: '@jest/console': 29.7.0 '@jest/reporters': 29.7.0 @@ -14430,7 +14427,42 @@ snapshots: exit: 0.1.2 graceful-fs: 4.2.11 jest-changed-files: 29.7.0 - jest-config: 29.7.0(@types/node@20.12.7)(ts-node@10.9.2) + jest-config: 29.7.0(@types/node@20.12.7)(ts-node@10.9.2(@swc/core@1.3.52(@swc/helpers@0.5.1))(@types/node@20.12.7)(typescript@5.3.3)) + jest-haste-map: 29.7.0 + jest-message-util: 29.7.0 + jest-regex-util: 29.6.3 + jest-resolve: 29.7.0 + jest-resolve-dependencies: 29.7.0 + jest-runner: 29.7.0 + jest-runtime: 29.7.0 + jest-snapshot: 29.7.0 + jest-util: 29.7.0 + jest-validate: 29.7.0 + jest-watcher: 29.7.0 + micromatch: 4.0.5 + pretty-format: 29.7.0 + slash: 3.0.0 + strip-ansi: 6.0.1 + transitivePeerDependencies: + - babel-plugin-macros + - supports-color + - ts-node + + '@jest/core@29.7.0(ts-node@10.9.2(@types/node@20.10.4)(typescript@5.3.3))': + dependencies: + '@jest/console': 29.7.0 + '@jest/reporters': 29.7.0 + '@jest/test-result': 29.7.0 + '@jest/transform': 29.7.0 + '@jest/types': 29.6.3 + '@types/node': 20.12.7 + ansi-escapes: 4.3.2 + chalk: 4.1.2 + ci-info: 3.8.0 + exit: 0.1.2 + graceful-fs: 4.2.11 + jest-changed-files: 29.7.0 + jest-config: 29.7.0(@types/node@20.12.7)(ts-node@10.9.2(@types/node@20.10.4)(typescript@5.3.3)) jest-haste-map: 29.7.0 jest-message-util: 29.7.0 jest-regex-util: 29.6.3 @@ -14807,7 +14839,7 @@ snapshots: monaco-editor: 0.47.0 state-local: 1.0.7 - '@monaco-editor/react@4.6.0(monaco-editor@0.47.0)(react-dom@18.2.0)(react@18.2.0)': + '@monaco-editor/react@4.6.0(monaco-editor@0.47.0)(react-dom@18.2.0(react@18.2.0))(react@18.2.0)': dependencies: '@monaco-editor/loader': 1.4.0(monaco-editor@0.47.0) monaco-editor: 0.47.0 @@ -14941,17 +14973,17 @@ snapshots: transitivePeerDependencies: - '@parcel/core' - '@parcel/config-default@2.9.3(@parcel/core@2.9.3)(postcss@8.4.31)': + '@parcel/config-default@2.9.3(@parcel/core@2.9.3)(@swc/helpers@0.5.1)(postcss@8.4.31)(srcset@4.0.0)': dependencies: '@parcel/bundler-default': 2.9.3(@parcel/core@2.9.3) '@parcel/compressor-raw': 2.9.3(@parcel/core@2.9.3) '@parcel/core': 2.9.3 '@parcel/namer-default': 2.9.3(@parcel/core@2.9.3) '@parcel/optimizer-css': 2.9.3(@parcel/core@2.9.3) - '@parcel/optimizer-htmlnano': 2.9.3(@parcel/core@2.9.3)(postcss@8.4.31) + '@parcel/optimizer-htmlnano': 2.9.3(@parcel/core@2.9.3)(postcss@8.4.31)(srcset@4.0.0) '@parcel/optimizer-image': 2.9.3(@parcel/core@2.9.3) '@parcel/optimizer-svgo': 2.9.3(@parcel/core@2.9.3) - '@parcel/optimizer-swc': 2.9.3(@parcel/core@2.9.3) + '@parcel/optimizer-swc': 2.9.3(@parcel/core@2.9.3)(@swc/helpers@0.5.1) '@parcel/packager-css': 2.9.3(@parcel/core@2.9.3) '@parcel/packager-html': 2.9.3(@parcel/core@2.9.3) '@parcel/packager-js': 2.9.3(@parcel/core@2.9.3) @@ -15078,10 +15110,10 @@ snapshots: transitivePeerDependencies: - '@parcel/core' - '@parcel/optimizer-htmlnano@2.9.3(@parcel/core@2.9.3)(postcss@8.4.31)': + '@parcel/optimizer-htmlnano@2.9.3(@parcel/core@2.9.3)(postcss@8.4.31)(srcset@4.0.0)': dependencies: '@parcel/plugin': 2.9.3(@parcel/core@2.9.3) - htmlnano: 2.0.3(postcss@8.4.31)(svgo@2.8.0) + htmlnano: 2.0.3(postcss@8.4.31)(srcset@4.0.0)(svgo@2.8.0) nullthrows: 1.1.1 posthtml: 0.16.6 svgo: 2.8.0 @@ -15112,13 +15144,13 @@ snapshots: transitivePeerDependencies: - '@parcel/core' - '@parcel/optimizer-swc@2.9.3(@parcel/core@2.9.3)': + '@parcel/optimizer-swc@2.9.3(@parcel/core@2.9.3)(@swc/helpers@0.5.1)': dependencies: '@parcel/diagnostic': 2.9.3 '@parcel/plugin': 2.9.3(@parcel/core@2.9.3) '@parcel/source-map': 2.1.1 '@parcel/utils': 2.9.3 - '@swc/core': 1.3.52 + '@swc/core': 1.3.52(@swc/helpers@0.5.1) nullthrows: 1.1.1 transitivePeerDependencies: - '@parcel/core' @@ -15333,7 +15365,7 @@ snapshots: transitivePeerDependencies: - '@parcel/core' - '@parcel/transformer-mdx@2.9.3(@mdx-js/react@1.6.22)(@parcel/core@2.9.3)': + '@parcel/transformer-mdx@2.9.3(@mdx-js/react@1.6.22(react@18.2.0))(@parcel/core@2.9.3)': dependencies: '@mdx-js/mdx': 1.6.22 '@mdx-js/react': 1.6.22(react@18.2.0) @@ -15532,7 +15564,7 @@ snapshots: '@react-spring/types@9.6.1': {} - '@react-spring/web@9.6.1(react-dom@18.2.0)(react@18.2.0)': + '@react-spring/web@9.6.1(react-dom@18.2.0(react@18.2.0))(react@18.2.0)': dependencies: '@react-spring/animated': 9.6.1(react@18.2.0) '@react-spring/core': 9.6.1(react@18.2.0) @@ -15577,6 +15609,7 @@ snapshots: glob: 8.1.0 is-reference: 1.2.1 magic-string: 0.30.7 + optionalDependencies: rollup: 4.12.0 '@rollup/plugin-commonjs@25.0.7(rollup@4.14.3)': @@ -15587,16 +15620,19 @@ snapshots: glob: 8.1.0 is-reference: 1.2.1 magic-string: 0.30.7 + optionalDependencies: rollup: 4.14.3 '@rollup/plugin-json@6.1.0(rollup@4.12.0)': dependencies: '@rollup/pluginutils': 5.1.0(rollup@4.12.0) + optionalDependencies: rollup: 4.12.0 '@rollup/plugin-json@6.1.0(rollup@4.14.3)': dependencies: '@rollup/pluginutils': 5.1.0(rollup@4.14.3) + optionalDependencies: rollup: 4.14.3 '@rollup/plugin-node-resolve@15.2.3(rollup@4.12.0)': @@ -15607,6 +15643,7 @@ snapshots: is-builtin-module: 3.2.1 is-module: 1.0.0 resolve: 1.22.2 + optionalDependencies: rollup: 4.12.0 '@rollup/plugin-node-resolve@15.2.3(rollup@4.14.3)': @@ -15617,27 +15654,33 @@ snapshots: is-builtin-module: 3.2.1 is-module: 1.0.0 resolve: 1.22.2 + optionalDependencies: rollup: 4.14.3 - '@rollup/plugin-typescript@11.1.6(rollup@4.12.0)(typescript@5.3.3)': + '@rollup/plugin-typescript@11.1.6(rollup@4.12.0)(tslib@2.6.2)(typescript@5.3.3)': dependencies: '@rollup/pluginutils': 5.1.0(rollup@4.12.0) resolve: 1.22.8 - rollup: 4.12.0 typescript: 5.3.3 + optionalDependencies: + rollup: 4.12.0 + tslib: 2.6.2 - '@rollup/plugin-typescript@11.1.6(rollup@4.14.3)(typescript@5.3.3)': + '@rollup/plugin-typescript@11.1.6(rollup@4.14.3)(tslib@2.6.2)(typescript@5.3.3)': dependencies: '@rollup/pluginutils': 5.1.0(rollup@4.14.3) resolve: 1.22.8 - rollup: 4.14.3 typescript: 5.3.3 + optionalDependencies: + rollup: 4.14.3 + tslib: 2.6.2 '@rollup/pluginutils@5.1.0(rollup@4.12.0)': dependencies: '@types/estree': 1.0.5 estree-walker: 2.0.2 picomatch: 2.3.1 + optionalDependencies: rollup: 4.12.0 '@rollup/pluginutils@5.1.0(rollup@4.14.3)': @@ -15645,6 +15688,7 @@ snapshots: '@types/estree': 1.0.5 estree-walker: 2.0.2 picomatch: 2.3.1 + optionalDependencies: rollup: 4.14.3 '@rollup/rollup-android-arm-eabi@4.12.0': @@ -15749,17 +15793,17 @@ snapshots: '@sideway/pinpoint@2.0.0': {} - '@silverhand/eslint-config-react@6.0.2(eslint@8.57.0)(postcss@8.4.31)(prettier@3.0.0)(stylelint@15.11.0)(typescript@5.3.3)': + '@silverhand/eslint-config-react@6.0.2(eslint@8.57.0)(postcss@8.4.31)(prettier@3.0.0)(stylelint@15.11.0(typescript@5.3.3))(typescript@5.3.3)': dependencies: '@silverhand/eslint-config': 6.0.1(eslint@8.57.0)(prettier@3.0.0)(typescript@5.3.3) - eslint-config-xo-react: 0.27.0(eslint-plugin-react-hooks@4.6.0)(eslint-plugin-react@7.34.1)(eslint@8.57.0) + eslint-config-xo-react: 0.27.0(eslint-plugin-react-hooks@4.6.0(eslint@8.57.0))(eslint-plugin-react@7.34.1(eslint@8.57.0))(eslint@8.57.0) eslint-plugin-jsx-a11y: 6.8.0(eslint@8.57.0) eslint-plugin-react: 7.34.1(eslint@8.57.0) eslint-plugin-react-hooks: 4.6.0(eslint@8.57.0) postcss-scss: 4.0.9(postcss@8.4.31) stylelint: 15.11.0(typescript@5.3.3) - stylelint-config-xo: 0.22.0(stylelint@15.11.0) - stylelint-scss: 6.2.1(stylelint@15.11.0) + stylelint-config-xo: 0.22.0(stylelint@15.11.0(typescript@5.3.3)) + stylelint-scss: 6.2.1(stylelint@15.11.0(typescript@5.3.3)) transitivePeerDependencies: - '@types/eslint' - eslint @@ -15773,23 +15817,23 @@ snapshots: '@silverhand/eslint-config@6.0.1(eslint@8.57.0)(prettier@3.0.0)(typescript@5.3.3)': dependencies: '@silverhand/eslint-plugin-fp': 2.5.0(eslint@8.57.0) - '@typescript-eslint/eslint-plugin': 7.7.0(@typescript-eslint/parser@7.7.0)(eslint@8.57.0)(typescript@5.3.3) + '@typescript-eslint/eslint-plugin': 7.7.0(@typescript-eslint/parser@7.7.0(eslint@8.57.0)(typescript@5.3.3))(eslint@8.57.0)(typescript@5.3.3) '@typescript-eslint/parser': 7.7.0(eslint@8.57.0)(typescript@5.3.3) eslint: 8.57.0 eslint-config-prettier: 9.1.0(eslint@8.57.0) eslint-config-xo: 0.44.0(eslint@8.57.0) - eslint-config-xo-typescript: 4.0.0(@typescript-eslint/eslint-plugin@7.7.0)(@typescript-eslint/parser@7.7.0)(eslint@8.57.0)(typescript@5.3.3) - eslint-import-resolver-typescript: 3.6.1(@typescript-eslint/parser@7.7.0)(eslint-plugin-import@2.29.1)(eslint@8.57.0) + eslint-config-xo-typescript: 4.0.0(@typescript-eslint/eslint-plugin@7.7.0(@typescript-eslint/parser@7.7.0(eslint@8.57.0)(typescript@5.3.3))(eslint@8.57.0)(typescript@5.3.3))(@typescript-eslint/parser@7.7.0(eslint@8.57.0)(typescript@5.3.3))(eslint@8.57.0)(typescript@5.3.3) + eslint-import-resolver-typescript: 3.6.1(@typescript-eslint/parser@7.7.0(eslint@8.57.0)(typescript@5.3.3))(eslint-plugin-import@2.29.1)(eslint@8.57.0) eslint-plugin-consistent-default-export-name: 0.0.15 eslint-plugin-eslint-comments: 3.2.0(eslint@8.57.0) - eslint-plugin-import: 2.29.1(@typescript-eslint/parser@7.7.0)(eslint-import-resolver-typescript@3.6.1)(eslint@8.57.0) + eslint-plugin-import: 2.29.1(@typescript-eslint/parser@7.7.0(eslint@8.57.0)(typescript@5.3.3))(eslint-import-resolver-typescript@3.6.1)(eslint@8.57.0) eslint-plugin-n: 17.2.1(eslint@8.57.0) eslint-plugin-no-use-extend-native: 0.5.0 - eslint-plugin-prettier: 5.1.3(eslint-config-prettier@9.1.0)(eslint@8.57.0)(prettier@3.0.0) + eslint-plugin-prettier: 5.1.3(eslint-config-prettier@9.1.0(eslint@8.57.0))(eslint@8.57.0)(prettier@3.0.0) eslint-plugin-promise: 6.1.1(eslint@8.57.0) eslint-plugin-sql: 2.1.0(eslint@8.57.0) eslint-plugin-unicorn: 52.0.0(eslint@8.57.0) - eslint-plugin-unused-imports: 3.1.0(@typescript-eslint/eslint-plugin@7.7.0)(eslint@8.57.0) + eslint-plugin-unused-imports: 3.1.0(@typescript-eslint/eslint-plugin@7.7.0(@typescript-eslint/parser@7.7.0(eslint@8.57.0)(typescript@5.3.3))(eslint@8.57.0)(typescript@5.3.3))(eslint@8.57.0) prettier: 3.0.0 transitivePeerDependencies: - '@types/eslint' @@ -16311,7 +16355,7 @@ snapshots: '@swc/core-win32-x64-msvc@1.3.52': optional: true - '@swc/core@1.3.52': + '@swc/core@1.3.52(@swc/helpers@0.5.1)': optionalDependencies: '@swc/core-darwin-arm64': 1.3.52 '@swc/core-darwin-x64': 1.3.52 @@ -16323,15 +16367,16 @@ snapshots: '@swc/core-win32-arm64-msvc': 1.3.52 '@swc/core-win32-ia32-msvc': 1.3.52 '@swc/core-win32-x64-msvc': 1.3.52 + '@swc/helpers': 0.5.1 '@swc/helpers@0.5.1': dependencies: tslib: 2.6.2 - '@swc/jest@0.2.26(@swc/core@1.3.52)': + '@swc/jest@0.2.26(@swc/core@1.3.52(@swc/helpers@0.5.1))': dependencies: '@jest/create-cache-key-function': 27.5.1 - '@swc/core': 1.3.52 + '@swc/core': 1.3.52(@swc/helpers@0.5.1) jsonc-parser: 3.2.0 '@szmarczak/http-timer@5.0.1': @@ -16349,15 +16394,16 @@ snapshots: lz-string: 1.5.0 pretty-format: 27.5.1 - '@testing-library/react-hooks@8.0.1(@types/react@18.0.31)(react-dom@18.2.0)(react@18.2.0)': + '@testing-library/react-hooks@8.0.1(@types/react@18.0.31)(react-dom@18.2.0(react@18.2.0))(react@18.2.0)': dependencies: '@babel/runtime': 7.21.0 - '@types/react': 18.0.31 react: 18.2.0 - react-dom: 18.2.0(react@18.2.0) react-error-boundary: 3.1.4(react@18.2.0) + optionalDependencies: + '@types/react': 18.0.31 + react-dom: 18.2.0(react@18.2.0) - '@testing-library/react@15.0.2(react-dom@18.2.0)(react@18.2.0)': + '@testing-library/react@15.0.2(react-dom@18.2.0(react@18.2.0))(react@18.2.0)': dependencies: '@babel/runtime': 7.21.0 '@testing-library/dom': 10.0.0 @@ -16778,7 +16824,7 @@ snapshots: '@types/node': 20.12.7 optional: true - '@typescript-eslint/eslint-plugin@7.7.0(@typescript-eslint/parser@7.7.0)(eslint@8.57.0)(typescript@5.3.3)': + '@typescript-eslint/eslint-plugin@7.7.0(@typescript-eslint/parser@7.7.0(eslint@8.57.0)(typescript@5.3.3))(eslint@8.57.0)(typescript@5.3.3)': dependencies: '@eslint-community/regexpp': 4.10.0 '@typescript-eslint/parser': 7.7.0(eslint@8.57.0)(typescript@5.3.3) @@ -16793,6 +16839,7 @@ snapshots: natural-compare: 1.4.0 semver: 7.6.0 ts-api-utils: 1.3.0(typescript@5.3.3) + optionalDependencies: typescript: 5.3.3 transitivePeerDependencies: - supports-color @@ -16805,6 +16852,7 @@ snapshots: '@typescript-eslint/visitor-keys': 7.7.0 debug: 4.3.4 eslint: 8.57.0 + optionalDependencies: typescript: 5.3.3 transitivePeerDependencies: - supports-color @@ -16821,6 +16869,7 @@ snapshots: debug: 4.3.4 eslint: 8.57.0 ts-api-utils: 1.3.0(typescript@5.3.3) + optionalDependencies: typescript: 5.3.3 transitivePeerDependencies: - supports-color @@ -16837,6 +16886,7 @@ snapshots: minimatch: 9.0.4 semver: 7.6.0 ts-api-utils: 1.3.0(typescript@5.3.3) + optionalDependencies: typescript: 5.3.3 transitivePeerDependencies: - supports-color @@ -16862,7 +16912,27 @@ snapshots: '@ungap/structured-clone@1.2.0': {} - '@vitest/coverage-v8@1.4.0(vitest@1.4.0)': + '@vitest/coverage-v8@1.4.0(vitest@1.4.0(@types/node@20.10.4)(jsdom@20.0.2)(sass@1.56.1))': + 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.10.4)(jsdom@20.0.2)(sass@1.56.1) + transitivePeerDependencies: + - supports-color + + '@vitest/coverage-v8@1.4.0(vitest@1.4.0(@types/node@20.11.20)(jsdom@20.0.2)(sass@1.56.1))': dependencies: '@ampproject/remapping': 2.3.0 '@bcoe/v8-coverage': 0.2.3 @@ -16878,7 +16948,27 @@ snapshots: strip-literal: 2.0.0 test-exclude: 6.0.0 v8-to-istanbul: 9.2.0 - vitest: 1.4.0(@types/node@20.10.4) + vitest: 1.4.0(@types/node@20.11.20)(jsdom@20.0.2)(sass@1.56.1) + transitivePeerDependencies: + - supports-color + + '@vitest/coverage-v8@1.4.0(vitest@1.4.0(@types/node@20.12.7)(jsdom@20.0.2)(sass@1.56.1))': + 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.12.7)(jsdom@20.0.2)(sass@1.56.1) transitivePeerDependencies: - supports-color @@ -16992,11 +17082,11 @@ snapshots: - supports-color ajv-draft-04@1.0.0(ajv@8.12.0): - dependencies: + optionalDependencies: ajv: 8.12.0 ajv-formats@2.1.1(ajv@8.12.0): - dependencies: + optionalDependencies: ajv: 8.12.0 ajv@6.12.6: @@ -17727,7 +17817,7 @@ snapshots: core-js@3.34.0: {} - cosmiconfig-typescript-loader@5.0.0(@types/node@20.12.7)(cosmiconfig@8.3.6)(typescript@5.0.2): + cosmiconfig-typescript-loader@5.0.0(@types/node@20.12.7)(cosmiconfig@8.3.6(typescript@5.0.2))(typescript@5.0.2): dependencies: '@types/node': 20.12.7 cosmiconfig: 8.3.6(typescript@5.0.2) @@ -17748,6 +17838,7 @@ snapshots: js-yaml: 4.1.0 parse-json: 5.2.0 path-type: 4.0.0 + optionalDependencies: typescript: 5.0.2 cosmiconfig@8.3.6(typescript@5.3.3): @@ -17756,6 +17847,7 @@ snapshots: js-yaml: 4.1.0 parse-json: 5.2.0 path-type: 4.0.0 + optionalDependencies: typescript: 5.3.3 cosmiconfig@9.0.0(typescript@5.3.3): @@ -17764,19 +17856,20 @@ snapshots: import-fresh: 3.3.0 js-yaml: 4.1.0 parse-json: 5.2.0 + optionalDependencies: typescript: 5.3.3 create-eslint-index@1.0.0: dependencies: lodash.get: 4.4.2 - create-jest@29.7.0(@types/node@20.10.4): + create-jest@29.7.0(@types/node@20.10.4)(ts-node@10.9.2(@types/node@20.10.4)(typescript@5.3.3)): dependencies: '@jest/types': 29.6.3 chalk: 4.1.2 exit: 0.1.2 graceful-fs: 4.2.11 - jest-config: 29.7.0(@types/node@20.10.4) + jest-config: 29.7.0(@types/node@20.10.4)(ts-node@10.9.2(@types/node@20.10.4)(typescript@5.3.3)) jest-util: 29.7.0 prompts: 2.4.2 transitivePeerDependencies: @@ -17785,13 +17878,13 @@ snapshots: - supports-color - ts-node - create-jest@29.7.0(@types/node@20.12.7)(ts-node@10.9.2): + create-jest@29.7.0(@types/node@20.12.7)(ts-node@10.9.2(@swc/core@1.3.52(@swc/helpers@0.5.1))(@types/node@20.12.7)(typescript@5.3.3)): dependencies: '@jest/types': 29.6.3 chalk: 4.1.2 exit: 0.1.2 graceful-fs: 4.2.11 - jest-config: 29.7.0(@types/node@20.12.7)(ts-node@10.9.2) + jest-config: 29.7.0(@types/node@20.12.7)(ts-node@10.9.2(@swc/core@1.3.52(@swc/helpers@0.5.1))(@types/node@20.12.7)(typescript@5.3.3)) jest-util: 29.7.0 prompts: 2.4.2 transitivePeerDependencies: @@ -17953,6 +18046,7 @@ snapshots: debug@3.2.7(supports-color@5.5.0): dependencies: ms: 2.1.3 + optionalDependencies: supports-color: 5.5.0 debug@4.3.4: @@ -18400,15 +18494,15 @@ snapshots: dependencies: eslint: 8.57.0 - eslint-config-xo-react@0.27.0(eslint-plugin-react-hooks@4.6.0)(eslint-plugin-react@7.34.1)(eslint@8.57.0): + eslint-config-xo-react@0.27.0(eslint-plugin-react-hooks@4.6.0(eslint@8.57.0))(eslint-plugin-react@7.34.1(eslint@8.57.0))(eslint@8.57.0): dependencies: eslint: 8.57.0 eslint-plugin-react: 7.34.1(eslint@8.57.0) eslint-plugin-react-hooks: 4.6.0(eslint@8.57.0) - eslint-config-xo-typescript@4.0.0(@typescript-eslint/eslint-plugin@7.7.0)(@typescript-eslint/parser@7.7.0)(eslint@8.57.0)(typescript@5.3.3): + eslint-config-xo-typescript@4.0.0(@typescript-eslint/eslint-plugin@7.7.0(@typescript-eslint/parser@7.7.0(eslint@8.57.0)(typescript@5.3.3))(eslint@8.57.0)(typescript@5.3.3))(@typescript-eslint/parser@7.7.0(eslint@8.57.0)(typescript@5.3.3))(eslint@8.57.0)(typescript@5.3.3): dependencies: - '@typescript-eslint/eslint-plugin': 7.7.0(@typescript-eslint/parser@7.7.0)(eslint@8.57.0)(typescript@5.3.3) + '@typescript-eslint/eslint-plugin': 7.7.0(@typescript-eslint/parser@7.7.0(eslint@8.57.0)(typescript@5.3.3))(eslint@8.57.0)(typescript@5.3.3) '@typescript-eslint/parser': 7.7.0(eslint@8.57.0)(typescript@5.3.3) eslint: 8.57.0 typescript: 5.3.3 @@ -18426,13 +18520,13 @@ snapshots: transitivePeerDependencies: - supports-color - eslint-import-resolver-typescript@3.6.1(@typescript-eslint/parser@7.7.0)(eslint-plugin-import@2.29.1)(eslint@8.57.0): + eslint-import-resolver-typescript@3.6.1(@typescript-eslint/parser@7.7.0(eslint@8.57.0)(typescript@5.3.3))(eslint-plugin-import@2.29.1)(eslint@8.57.0): dependencies: debug: 4.3.4 enhanced-resolve: 5.16.0 eslint: 8.57.0 - eslint-module-utils: 2.8.1(@typescript-eslint/parser@7.7.0)(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.1)(eslint@8.57.0) - eslint-plugin-import: 2.29.1(@typescript-eslint/parser@7.7.0)(eslint-import-resolver-typescript@3.6.1)(eslint@8.57.0) + eslint-module-utils: 2.8.1(@typescript-eslint/parser@7.7.0(eslint@8.57.0)(typescript@5.3.3))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.1(@typescript-eslint/parser@7.7.0(eslint@8.57.0)(typescript@5.3.3))(eslint-plugin-import@2.29.1)(eslint@8.57.0))(eslint@8.57.0) + eslint-plugin-import: 2.29.1(@typescript-eslint/parser@7.7.0(eslint@8.57.0)(typescript@5.3.3))(eslint-import-resolver-typescript@3.6.1)(eslint@8.57.0) fast-glob: 3.3.2 get-tsconfig: 4.7.3 is-core-module: 2.13.1 @@ -18443,13 +18537,14 @@ snapshots: - eslint-import-resolver-webpack - supports-color - eslint-module-utils@2.8.1(@typescript-eslint/parser@7.7.0)(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.1)(eslint@8.57.0): + eslint-module-utils@2.8.1(@typescript-eslint/parser@7.7.0(eslint@8.57.0)(typescript@5.3.3))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.1(@typescript-eslint/parser@7.7.0(eslint@8.57.0)(typescript@5.3.3))(eslint-plugin-import@2.29.1)(eslint@8.57.0))(eslint@8.57.0): dependencies: - '@typescript-eslint/parser': 7.7.0(eslint@8.57.0)(typescript@5.3.3) debug: 3.2.7(supports-color@5.5.0) + optionalDependencies: + '@typescript-eslint/parser': 7.7.0(eslint@8.57.0)(typescript@5.3.3) eslint: 8.57.0 eslint-import-resolver-node: 0.3.9 - eslint-import-resolver-typescript: 3.6.1(@typescript-eslint/parser@7.7.0)(eslint-plugin-import@2.29.1)(eslint@8.57.0) + eslint-import-resolver-typescript: 3.6.1(@typescript-eslint/parser@7.7.0(eslint@8.57.0)(typescript@5.3.3))(eslint-plugin-import@2.29.1)(eslint@8.57.0) transitivePeerDependencies: - supports-color @@ -18471,9 +18566,8 @@ snapshots: eslint: 8.57.0 ignore: 5.3.1 - eslint-plugin-import@2.29.1(@typescript-eslint/parser@7.7.0)(eslint-import-resolver-typescript@3.6.1)(eslint@8.57.0): + eslint-plugin-import@2.29.1(@typescript-eslint/parser@7.7.0(eslint@8.57.0)(typescript@5.3.3))(eslint-import-resolver-typescript@3.6.1)(eslint@8.57.0): dependencies: - '@typescript-eslint/parser': 7.7.0(eslint@8.57.0)(typescript@5.3.3) array-includes: 3.1.8 array.prototype.findlastindex: 1.2.5 array.prototype.flat: 1.3.2 @@ -18482,7 +18576,7 @@ snapshots: doctrine: 2.1.0 eslint: 8.57.0 eslint-import-resolver-node: 0.3.9 - eslint-module-utils: 2.8.1(@typescript-eslint/parser@7.7.0)(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.1)(eslint@8.57.0) + eslint-module-utils: 2.8.1(@typescript-eslint/parser@7.7.0(eslint@8.57.0)(typescript@5.3.3))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.1(@typescript-eslint/parser@7.7.0(eslint@8.57.0)(typescript@5.3.3))(eslint-plugin-import@2.29.1)(eslint@8.57.0))(eslint@8.57.0) hasown: 2.0.2 is-core-module: 2.13.1 is-glob: 4.0.3 @@ -18492,6 +18586,8 @@ snapshots: object.values: 1.2.0 semver: 6.3.1 tsconfig-paths: 3.15.0 + optionalDependencies: + '@typescript-eslint/parser': 7.7.0(eslint@8.57.0)(typescript@5.3.3) transitivePeerDependencies: - eslint-import-resolver-typescript - eslint-import-resolver-webpack @@ -18536,13 +18632,14 @@ snapshots: is-obj-prop: 1.0.0 is-proto-prop: 2.0.0 - eslint-plugin-prettier@5.1.3(eslint-config-prettier@9.1.0)(eslint@8.57.0)(prettier@3.0.0): + eslint-plugin-prettier@5.1.3(eslint-config-prettier@9.1.0(eslint@8.57.0))(eslint@8.57.0)(prettier@3.0.0): dependencies: eslint: 8.57.0 - eslint-config-prettier: 9.1.0(eslint@8.57.0) prettier: 3.0.0 prettier-linter-helpers: 1.0.0 synckit: 0.8.8 + optionalDependencies: + eslint-config-prettier: 9.1.0(eslint@8.57.0) eslint-plugin-promise@6.1.1(eslint@8.57.0): dependencies: @@ -18607,11 +18704,12 @@ snapshots: transitivePeerDependencies: - supports-color - eslint-plugin-unused-imports@3.1.0(@typescript-eslint/eslint-plugin@7.7.0)(eslint@8.57.0): + eslint-plugin-unused-imports@3.1.0(@typescript-eslint/eslint-plugin@7.7.0(@typescript-eslint/parser@7.7.0(eslint@8.57.0)(typescript@5.3.3))(eslint@8.57.0)(typescript@5.3.3))(eslint@8.57.0): dependencies: - '@typescript-eslint/eslint-plugin': 7.7.0(@typescript-eslint/parser@7.7.0)(eslint@8.57.0)(typescript@5.3.3) eslint: 8.57.0 eslint-rule-composer: 0.3.0 + optionalDependencies: + '@typescript-eslint/eslint-plugin': 7.7.0(@typescript-eslint/parser@7.7.0(eslint@8.57.0)(typescript@5.3.3))(eslint@8.57.0)(typescript@5.3.3) eslint-rule-composer@0.3.0: {} @@ -19381,13 +19479,15 @@ snapshots: html-void-elements@1.0.5: {} - htmlnano@2.0.3(postcss@8.4.31)(svgo@2.8.0): + htmlnano@2.0.3(postcss@8.4.31)(srcset@4.0.0)(svgo@2.8.0): dependencies: cosmiconfig: 7.1.0 - postcss: 8.4.31 posthtml: 0.16.6 - svgo: 2.8.0 timsort: 0.3.0 + optionalDependencies: + postcss: 8.4.31 + srcset: 4.0.0 + svgo: 2.8.0 htmlparser2@7.2.0: dependencies: @@ -19662,7 +19762,7 @@ snapshots: is-date-object@1.0.5: dependencies: - has-tostringtag: 1.0.0 + has-tostringtag: 1.0.2 is-decimal@1.0.4: {} @@ -19680,7 +19780,7 @@ snapshots: is-generator-function@1.0.10: dependencies: - has-tostringtag: 1.0.0 + has-tostringtag: 1.0.2 is-get-set-prop@1.0.0: dependencies: @@ -19746,7 +19846,7 @@ snapshots: is-regex@1.1.4: dependencies: call-bind: 1.0.7 - has-tostringtag: 1.0.0 + has-tostringtag: 1.0.2 is-set@2.0.3: {} @@ -19908,16 +20008,16 @@ snapshots: - babel-plugin-macros - supports-color - jest-cli@29.7.0(@types/node@20.10.4): + jest-cli@29.7.0(@types/node@20.10.4)(ts-node@10.9.2(@types/node@20.10.4)(typescript@5.3.3)): dependencies: - '@jest/core': 29.7.0(ts-node@10.9.2) + '@jest/core': 29.7.0(ts-node@10.9.2(@types/node@20.10.4)(typescript@5.3.3)) '@jest/test-result': 29.7.0 '@jest/types': 29.6.3 chalk: 4.1.2 - create-jest: 29.7.0(@types/node@20.10.4) + create-jest: 29.7.0(@types/node@20.10.4)(ts-node@10.9.2(@types/node@20.10.4)(typescript@5.3.3)) exit: 0.1.2 import-local: 3.1.0 - jest-config: 29.7.0(@types/node@20.10.4) + jest-config: 29.7.0(@types/node@20.10.4)(ts-node@10.9.2(@types/node@20.10.4)(typescript@5.3.3)) jest-util: 29.7.0 jest-validate: 29.7.0 yargs: 17.7.2 @@ -19927,16 +20027,16 @@ snapshots: - supports-color - ts-node - jest-cli@29.7.0(@types/node@20.12.7): + jest-cli@29.7.0(@types/node@20.12.7)(ts-node@10.9.2(@swc/core@1.3.52(@swc/helpers@0.5.1))(@types/node@20.12.7)(typescript@5.3.3)): dependencies: - '@jest/core': 29.7.0(ts-node@10.9.2) + '@jest/core': 29.7.0(ts-node@10.9.2(@swc/core@1.3.52(@swc/helpers@0.5.1))(@types/node@20.12.7)(typescript@5.3.3)) '@jest/test-result': 29.7.0 '@jest/types': 29.6.3 chalk: 4.1.2 - create-jest: 29.7.0(@types/node@20.12.7)(ts-node@10.9.2) + create-jest: 29.7.0(@types/node@20.12.7)(ts-node@10.9.2(@swc/core@1.3.52(@swc/helpers@0.5.1))(@types/node@20.12.7)(typescript@5.3.3)) exit: 0.1.2 import-local: 3.1.0 - jest-config: 29.7.0(@types/node@20.12.7)(ts-node@10.9.2) + jest-config: 29.7.0(@types/node@20.12.7)(ts-node@10.9.2(@swc/core@1.3.52(@swc/helpers@0.5.1))(@types/node@20.12.7)(typescript@5.3.3)) jest-util: 29.7.0 jest-validate: 29.7.0 yargs: 17.7.2 @@ -19946,31 +20046,42 @@ snapshots: - supports-color - ts-node - jest-cli@29.7.0(@types/node@20.12.7)(ts-node@10.9.2): + jest-config@29.7.0(@types/node@20.10.4)(ts-node@10.9.2(@types/node@20.10.4)(typescript@5.3.3)): dependencies: - '@jest/core': 29.7.0(ts-node@10.9.2) - '@jest/test-result': 29.7.0 + '@babel/core': 7.24.4 + '@jest/test-sequencer': 29.7.0 '@jest/types': 29.6.3 + babel-jest: 29.7.0(@babel/core@7.24.4) chalk: 4.1.2 - create-jest: 29.7.0(@types/node@20.12.7)(ts-node@10.9.2) - exit: 0.1.2 - import-local: 3.1.0 - jest-config: 29.7.0(@types/node@20.12.7)(ts-node@10.9.2) + ci-info: 3.8.0 + deepmerge: 4.3.1 + glob: 7.2.3 + graceful-fs: 4.2.11 + jest-circus: 29.7.0 + jest-environment-node: 29.7.0 + jest-get-type: 29.6.3 + jest-regex-util: 29.6.3 + jest-resolve: 29.7.0 + jest-runner: 29.7.0 jest-util: 29.7.0 jest-validate: 29.7.0 - yargs: 17.7.2 + micromatch: 4.0.5 + parse-json: 5.2.0 + pretty-format: 29.7.0 + slash: 3.0.0 + strip-json-comments: 3.1.1 + optionalDependencies: + '@types/node': 20.10.4 + ts-node: 10.9.2(@types/node@20.10.4)(typescript@5.3.3) transitivePeerDependencies: - - '@types/node' - babel-plugin-macros - supports-color - - ts-node - jest-config@29.7.0(@types/node@20.10.4): + jest-config@29.7.0(@types/node@20.12.7)(ts-node@10.9.2(@swc/core@1.3.52(@swc/helpers@0.5.1))(@types/node@20.12.7)(typescript@5.3.3)): dependencies: '@babel/core': 7.24.4 '@jest/test-sequencer': 29.7.0 '@jest/types': 29.6.3 - '@types/node': 20.10.4 babel-jest: 29.7.0(@babel/core@7.24.4) chalk: 4.1.2 ci-info: 3.8.0 @@ -19990,16 +20101,18 @@ snapshots: pretty-format: 29.7.0 slash: 3.0.0 strip-json-comments: 3.1.1 + optionalDependencies: + '@types/node': 20.12.7 + ts-node: 10.9.2(@swc/core@1.3.52(@swc/helpers@0.5.1))(@types/node@20.12.7)(typescript@5.3.3) transitivePeerDependencies: - babel-plugin-macros - supports-color - jest-config@29.7.0(@types/node@20.12.7)(ts-node@10.9.2): + jest-config@29.7.0(@types/node@20.12.7)(ts-node@10.9.2(@types/node@20.10.4)(typescript@5.3.3)): dependencies: '@babel/core': 7.24.4 '@jest/test-sequencer': 29.7.0 '@jest/types': 29.6.3 - '@types/node': 20.12.7 babel-jest: 29.7.0(@babel/core@7.24.4) chalk: 4.1.2 ci-info: 3.8.0 @@ -20019,7 +20132,9 @@ snapshots: pretty-format: 29.7.0 slash: 3.0.0 strip-json-comments: 3.1.1 - ts-node: 10.9.2(@swc/core@1.3.52)(@types/node@20.12.7)(typescript@5.3.3) + optionalDependencies: + '@types/node': 20.12.7 + ts-node: 10.9.2(@types/node@20.10.4)(typescript@5.3.3) transitivePeerDependencies: - babel-plugin-macros - supports-color @@ -20177,10 +20292,10 @@ snapshots: jest-util: 29.7.0 jest-pnp-resolver@1.2.2(jest-resolve@29.7.0): - dependencies: + optionalDependencies: jest-resolve: 29.7.0 - jest-puppeteer@10.0.1(puppeteer@22.6.5)(typescript@5.3.3): + jest-puppeteer@10.0.1(puppeteer@22.6.5(typescript@5.3.3))(typescript@5.3.3): dependencies: expect-puppeteer: 10.0.0 jest-environment-puppeteer: 10.0.1(typescript@5.3.3) @@ -20293,9 +20408,9 @@ snapshots: jest-transform-stub@2.0.0: {} - jest-transformer-svg@2.0.0(jest@29.7.0)(react@18.2.0): + jest-transformer-svg@2.0.0(jest@29.7.0(@types/node@20.12.7)(ts-node@10.9.2(@swc/core@1.3.52(@swc/helpers@0.5.1))(@types/node@20.12.7)(typescript@5.3.3)))(react@18.2.0): dependencies: - jest: 29.7.0(@types/node@20.12.7)(ts-node@10.9.2) + jest: 29.7.0(@types/node@20.12.7)(ts-node@10.9.2(@swc/core@1.3.52(@swc/helpers@0.5.1))(@types/node@20.12.7)(typescript@5.3.3)) react: 18.2.0 jest-util@29.5.0: @@ -20350,36 +20465,24 @@ snapshots: merge-stream: 2.0.0 supports-color: 8.1.1 - jest@29.7.0(@types/node@20.10.4): - dependencies: - '@jest/core': 29.7.0(ts-node@10.9.2) - '@jest/types': 29.6.3 - import-local: 3.1.0 - jest-cli: 29.7.0(@types/node@20.10.4) - transitivePeerDependencies: - - '@types/node' - - babel-plugin-macros - - supports-color - - ts-node - - jest@29.7.0(@types/node@20.12.7): + jest@29.7.0(@types/node@20.10.4)(ts-node@10.9.2(@types/node@20.10.4)(typescript@5.3.3)): dependencies: - '@jest/core': 29.7.0(ts-node@10.9.2) + '@jest/core': 29.7.0(ts-node@10.9.2(@types/node@20.10.4)(typescript@5.3.3)) '@jest/types': 29.6.3 import-local: 3.1.0 - jest-cli: 29.7.0(@types/node@20.12.7) + jest-cli: 29.7.0(@types/node@20.10.4)(ts-node@10.9.2(@types/node@20.10.4)(typescript@5.3.3)) transitivePeerDependencies: - '@types/node' - babel-plugin-macros - supports-color - ts-node - jest@29.7.0(@types/node@20.12.7)(ts-node@10.9.2): + jest@29.7.0(@types/node@20.12.7)(ts-node@10.9.2(@swc/core@1.3.52(@swc/helpers@0.5.1))(@types/node@20.12.7)(typescript@5.3.3)): dependencies: - '@jest/core': 29.7.0(ts-node@10.9.2) + '@jest/core': 29.7.0(ts-node@10.9.2(@swc/core@1.3.52(@swc/helpers@0.5.1))(@types/node@20.12.7)(typescript@5.3.3)) '@jest/types': 29.6.3 import-local: 3.1.0 - jest-cli: 29.7.0(@types/node@20.12.7)(ts-node@10.9.2) + jest-cli: 29.7.0(@types/node@20.12.7)(ts-node@10.9.2(@swc/core@1.3.52(@swc/helpers@0.5.1))(@types/node@20.12.7)(typescript@5.3.3)) transitivePeerDependencies: - '@types/node' - babel-plugin-macros @@ -21815,13 +21918,13 @@ snapshots: pako@1.0.11: {} - parcel-resolver-ignore@2.1.3(parcel@2.9.3): + parcel-resolver-ignore@2.1.3(parcel@2.9.3(@swc/helpers@0.5.1)(postcss@8.4.31)(srcset@4.0.0)): dependencies: - parcel: 2.9.3(postcss@8.4.31) + parcel: 2.9.3(@swc/helpers@0.5.1)(postcss@8.4.31)(srcset@4.0.0) - parcel@2.9.3(postcss@8.4.31): + parcel@2.9.3(@swc/helpers@0.5.1)(postcss@8.4.31)(srcset@4.0.0): dependencies: - '@parcel/config-default': 2.9.3(@parcel/core@2.9.3)(postcss@8.4.31) + '@parcel/config-default': 2.9.3(@parcel/core@2.9.3)(@swc/helpers@0.5.1)(postcss@8.4.31)(srcset@4.0.0) '@parcel/core': 2.9.3 '@parcel/diagnostic': 2.9.3 '@parcel/events': 2.9.3 @@ -22293,7 +22396,7 @@ snapshots: iconv-lite: 0.4.24 unpipe: 1.0.0 - react-animate-height@3.0.4(react-dom@18.2.0)(react@18.2.0): + react-animate-height@3.0.4(react-dom@18.2.0(react@18.2.0))(react@18.2.0): dependencies: classnames: 2.3.1 react: 18.2.0 @@ -22315,7 +22418,7 @@ snapshots: react: 18.2.0 tween-functions: 1.2.0 - react-device-detect@2.2.3(react-dom@18.2.0)(react@18.2.0): + react-device-detect@2.2.3(react-dom@18.2.0(react@18.2.0))(react@18.2.0): dependencies: react: 18.2.0 react-dom: 18.2.0(react@18.2.0) @@ -22329,12 +22432,13 @@ snapshots: dependencies: '@react-dnd/invariant': 4.0.0 '@react-dnd/shallowequal': 4.0.0 - '@types/node': 20.12.7 - '@types/react': 18.0.31 dnd-core: 16.0.0 fast-deep-equal: 3.1.3 hoist-non-react-statics: 3.3.2 react: 18.2.0 + optionalDependencies: + '@types/node': 20.12.7 + '@types/react': 18.0.31 react-dom@18.2.0(react@18.2.0): dependencies: @@ -22374,7 +22478,7 @@ snapshots: dependencies: react: 18.2.0 - react-hot-toast@2.2.0(csstype@3.0.11)(react-dom@18.2.0)(react@18.2.0): + react-hot-toast@2.2.0(csstype@3.0.11)(react-dom@18.2.0(react@18.2.0))(react@18.2.0): dependencies: goober: 2.1.8(csstype@3.0.11) react: 18.2.0 @@ -22382,12 +22486,13 @@ snapshots: transitivePeerDependencies: - csstype - react-i18next@12.3.1(i18next@22.4.15)(react-dom@18.2.0)(react@18.2.0): + react-i18next@12.3.1(i18next@22.4.15)(react-dom@18.2.0(react@18.2.0))(react@18.2.0): dependencies: '@babel/runtime': 7.21.0 html-parse-stringify: 3.0.1 i18next: 22.4.15 react: 18.2.0 + optionalDependencies: react-dom: 18.2.0(react@18.2.0) react-is@16.13.1: {} @@ -22416,7 +22521,7 @@ snapshots: transitivePeerDependencies: - supports-color - react-modal@3.15.1(react-dom@18.2.0)(react@18.2.0): + react-modal@3.15.1(react-dom@18.2.0(react@18.2.0))(react@18.2.0): dependencies: exenv: 1.2.2 prop-types: 15.8.1 @@ -22432,13 +22537,13 @@ snapshots: react-refresh@0.9.0: {} - react-resize-detector@7.1.2(react-dom@18.2.0)(react@18.2.0): + react-resize-detector@7.1.2(react-dom@18.2.0(react@18.2.0))(react@18.2.0): dependencies: lodash: 4.17.21 react: 18.2.0 react-dom: 18.2.0(react@18.2.0) - react-router-dom@6.10.0(react-dom@18.2.0)(react@18.2.0): + react-router-dom@6.10.0(react-dom@18.2.0(react@18.2.0))(react@18.2.0): dependencies: '@remix-run/router': 1.5.0 react: 18.2.0 @@ -22454,13 +22559,13 @@ snapshots: dependencies: react: 18.2.0 - react-smooth@2.0.1(prop-types@15.8.1)(react-dom@18.2.0)(react@18.2.0): + react-smooth@2.0.1(prop-types@15.8.1)(react-dom@18.2.0(react@18.2.0))(react@18.2.0): dependencies: fast-equals: 2.0.4 prop-types: 15.8.1 react: 18.2.0 react-dom: 18.2.0(react@18.2.0) - react-transition-group: 2.9.0(react-dom@18.2.0)(react@18.2.0) + react-transition-group: 2.9.0(react-dom@18.2.0(react@18.2.0))(react@18.2.0) react-string-replace@1.0.0: {} @@ -22473,7 +22578,7 @@ snapshots: react: 18.2.0 refractor: 3.6.0 - react-timer-hook@3.0.5(react-dom@18.2.0)(react@18.2.0): + react-timer-hook@3.0.5(react-dom@18.2.0(react@18.2.0))(react@18.2.0): dependencies: react: 18.2.0 react-dom: 18.2.0(react@18.2.0) @@ -22482,7 +22587,7 @@ snapshots: dependencies: react: 18.2.0 - react-transition-group@2.9.0(react-dom@18.2.0)(react@18.2.0): + react-transition-group@2.9.0(react-dom@18.2.0(react@18.2.0))(react@18.2.0): dependencies: dom-helpers: 3.4.0 loose-envify: 1.4.0 @@ -22547,7 +22652,7 @@ snapshots: dependencies: decimal.js-light: 2.5.1 - recharts@2.1.13(prop-types@15.8.1)(react-dom@18.2.0)(react@18.2.0): + recharts@2.1.13(prop-types@15.8.1)(react-dom@18.2.0(react@18.2.0))(react@18.2.0): dependencies: classnames: 2.3.1 d3-interpolate: 3.0.1 @@ -22559,8 +22664,8 @@ snapshots: react: 18.2.0 react-dom: 18.2.0(react@18.2.0) react-is: 16.13.1 - react-resize-detector: 7.1.2(react-dom@18.2.0)(react@18.2.0) - react-smooth: 2.0.1(prop-types@15.8.1)(react-dom@18.2.0)(react@18.2.0) + react-resize-detector: 7.1.2(react-dom@18.2.0(react@18.2.0))(react@18.2.0) + react-smooth: 2.0.1(prop-types@15.8.1)(react-dom@18.2.0(react@18.2.0))(react@18.2.0) recharts-scale: 0.4.5 reduce-css-calc: 2.1.8 @@ -22815,6 +22920,7 @@ snapshots: colorette: 2.0.20 gzip-size: 7.0.0 pretty-bytes: 6.1.1 + optionalDependencies: rollup: 4.12.0 rollup-plugin-output-size@1.3.0(rollup@4.14.3): @@ -22822,6 +22928,7 @@ snapshots: colorette: 2.0.20 gzip-size: 7.0.0 pretty-bytes: 6.1.1 + optionalDependencies: rollup: 4.14.3 rollup@4.12.0: @@ -23297,23 +23404,23 @@ snapshots: dependencies: inline-style-parser: 0.1.1 - stylelint-config-xo@0.22.0(stylelint@15.11.0): + stylelint-config-xo@0.22.0(stylelint@15.11.0(typescript@5.3.3)): dependencies: stylelint: 15.11.0(typescript@5.3.3) - stylelint-declaration-block-no-ignored-properties: 2.8.0(stylelint@15.11.0) - stylelint-order: 6.0.4(stylelint@15.11.0) + stylelint-declaration-block-no-ignored-properties: 2.8.0(stylelint@15.11.0(typescript@5.3.3)) + stylelint-order: 6.0.4(stylelint@15.11.0(typescript@5.3.3)) - stylelint-declaration-block-no-ignored-properties@2.8.0(stylelint@15.11.0): + stylelint-declaration-block-no-ignored-properties@2.8.0(stylelint@15.11.0(typescript@5.3.3)): dependencies: stylelint: 15.11.0(typescript@5.3.3) - stylelint-order@6.0.4(stylelint@15.11.0): + stylelint-order@6.0.4(stylelint@15.11.0(typescript@5.3.3)): dependencies: postcss: 8.4.38 postcss-sorting: 8.0.2(postcss@8.4.38) stylelint: 15.11.0(typescript@5.3.3) - stylelint-scss@6.2.1(stylelint@15.11.0): + stylelint-scss@6.2.1(stylelint@15.11.0(typescript@5.3.3)): dependencies: known-css-properties: 0.29.0 postcss-media-query-parser: 0.2.3 @@ -23326,7 +23433,7 @@ snapshots: dependencies: '@csstools/css-parser-algorithms': 2.6.1(@csstools/css-tokenizer@2.2.4) '@csstools/css-tokenizer': 2.2.4 - '@csstools/media-query-list-parser': 2.1.9(@csstools/css-parser-algorithms@2.6.1)(@csstools/css-tokenizer@2.2.4) + '@csstools/media-query-list-parser': 2.1.9(@csstools/css-parser-algorithms@2.6.1(@csstools/css-tokenizer@2.2.4))(@csstools/css-tokenizer@2.2.4) '@csstools/selector-specificity': 3.0.3(postcss-selector-parser@6.0.16) balanced-match: 2.0.0 colord: 2.9.3 @@ -23572,10 +23679,9 @@ snapshots: dependencies: typescript: 5.3.3 - ts-node@10.9.2(@swc/core@1.3.52)(@types/node@20.12.7)(typescript@5.3.3): + ts-node@10.9.2(@swc/core@1.3.52(@swc/helpers@0.5.1))(@types/node@20.12.7)(typescript@5.3.3): dependencies: '@cspotcode/source-map-support': 0.8.1 - '@swc/core': 1.3.52 '@tsconfig/node10': 1.0.9 '@tsconfig/node12': 1.0.11 '@tsconfig/node14': 1.0.3 @@ -23590,6 +23696,27 @@ snapshots: typescript: 5.3.3 v8-compile-cache-lib: 3.0.1 yn: 3.1.1 + optionalDependencies: + '@swc/core': 1.3.52(@swc/helpers@0.5.1) + + ts-node@10.9.2(@types/node@20.10.4)(typescript@5.3.3): + dependencies: + '@cspotcode/source-map-support': 0.8.1 + '@tsconfig/node10': 1.0.9 + '@tsconfig/node12': 1.0.11 + '@tsconfig/node14': 1.0.3 + '@tsconfig/node16': 1.0.4 + '@types/node': 20.10.4 + acorn: 8.10.0 + acorn-walk: 8.2.0 + arg: 4.1.3 + create-require: 1.1.1 + diff: 4.0.2 + make-error: 1.3.6 + typescript: 5.3.3 + v8-compile-cache-lib: 3.0.1 + yn: 3.1.1 + optional: true tsconfig-paths@3.15.0: dependencies: @@ -23879,13 +24006,13 @@ snapshots: unist-util-stringify-position: 4.0.0 vfile-message: 4.0.2 - vite-node@1.4.0(@types/node@20.10.4): + vite-node@1.4.0(@types/node@20.10.4)(sass@1.56.1): dependencies: cac: 6.7.14 debug: 4.3.4 pathe: 1.1.2 picocolors: 1.0.0 - vite: 5.2.9(@types/node@20.10.4) + vite: 5.2.9(@types/node@20.10.4)(sass@1.56.1) transitivePeerDependencies: - '@types/node' - less @@ -23896,13 +24023,13 @@ snapshots: - supports-color - terser - vite-node@1.4.0(@types/node@20.11.20): + vite-node@1.4.0(@types/node@20.11.20)(sass@1.56.1): dependencies: cac: 6.7.14 debug: 4.3.4 pathe: 1.1.2 picocolors: 1.0.0 - vite: 5.2.9(@types/node@20.11.20) + vite: 5.2.9(@types/node@20.11.20)(sass@1.56.1) transitivePeerDependencies: - '@types/node' - less @@ -23913,13 +24040,13 @@ snapshots: - supports-color - terser - vite-node@1.4.0(@types/node@20.12.7): + vite-node@1.4.0(@types/node@20.12.7)(sass@1.56.1): dependencies: cac: 6.7.14 debug: 4.3.4 pathe: 1.1.2 picocolors: 1.0.0 - vite: 5.2.9(@types/node@20.12.7) + vite: 5.2.9(@types/node@20.12.7)(sass@1.56.1) transitivePeerDependencies: - '@types/node' - less @@ -23930,36 +24057,38 @@ snapshots: - supports-color - terser - vite@5.2.9(@types/node@20.10.4): + vite@5.2.9(@types/node@20.10.4)(sass@1.56.1): dependencies: - '@types/node': 20.10.4 esbuild: 0.20.2 postcss: 8.4.38 rollup: 4.14.3 optionalDependencies: + '@types/node': 20.10.4 fsevents: 2.3.3 + sass: 1.56.1 - vite@5.2.9(@types/node@20.11.20): + vite@5.2.9(@types/node@20.11.20)(sass@1.56.1): dependencies: - '@types/node': 20.11.20 esbuild: 0.20.2 postcss: 8.4.38 rollup: 4.14.3 optionalDependencies: + '@types/node': 20.11.20 fsevents: 2.3.3 + sass: 1.56.1 - vite@5.2.9(@types/node@20.12.7): + vite@5.2.9(@types/node@20.12.7)(sass@1.56.1): dependencies: - '@types/node': 20.12.7 esbuild: 0.20.2 postcss: 8.4.38 rollup: 4.14.3 optionalDependencies: + '@types/node': 20.12.7 fsevents: 2.3.3 + sass: 1.56.1 - vitest@1.4.0(@types/node@20.10.4): + vitest@1.4.0(@types/node@20.10.4)(jsdom@20.0.2)(sass@1.56.1): dependencies: - '@types/node': 20.10.4 '@vitest/expect': 1.4.0 '@vitest/runner': 1.4.0 '@vitest/snapshot': 1.4.0 @@ -23977,9 +24106,12 @@ snapshots: strip-literal: 2.0.0 tinybench: 2.6.0 tinypool: 0.8.2 - vite: 5.2.9(@types/node@20.10.4) - vite-node: 1.4.0(@types/node@20.10.4) + vite: 5.2.9(@types/node@20.10.4)(sass@1.56.1) + vite-node: 1.4.0(@types/node@20.10.4)(sass@1.56.1) why-is-node-running: 2.2.2 + optionalDependencies: + '@types/node': 20.10.4 + jsdom: 20.0.2 transitivePeerDependencies: - less - lightningcss @@ -23989,9 +24121,8 @@ snapshots: - supports-color - terser - vitest@1.4.0(@types/node@20.11.20): + vitest@1.4.0(@types/node@20.11.20)(jsdom@20.0.2)(sass@1.56.1): dependencies: - '@types/node': 20.11.20 '@vitest/expect': 1.4.0 '@vitest/runner': 1.4.0 '@vitest/snapshot': 1.4.0 @@ -24009,9 +24140,12 @@ snapshots: strip-literal: 2.0.0 tinybench: 2.6.0 tinypool: 0.8.2 - vite: 5.2.9(@types/node@20.11.20) - vite-node: 1.4.0(@types/node@20.11.20) + vite: 5.2.9(@types/node@20.11.20)(sass@1.56.1) + vite-node: 1.4.0(@types/node@20.11.20)(sass@1.56.1) why-is-node-running: 2.2.2 + optionalDependencies: + '@types/node': 20.11.20 + jsdom: 20.0.2 transitivePeerDependencies: - less - lightningcss @@ -24021,9 +24155,8 @@ snapshots: - supports-color - terser - vitest@1.4.0(@types/node@20.12.7): + vitest@1.4.0(@types/node@20.12.7)(jsdom@20.0.2)(sass@1.56.1): dependencies: - '@types/node': 20.12.7 '@vitest/expect': 1.4.0 '@vitest/runner': 1.4.0 '@vitest/snapshot': 1.4.0 @@ -24041,9 +24174,12 @@ snapshots: strip-literal: 2.0.0 tinybench: 2.6.0 tinypool: 0.8.2 - vite: 5.2.9(@types/node@20.12.7) - vite-node: 1.4.0(@types/node@20.12.7) + vite: 5.2.9(@types/node@20.12.7)(sass@1.56.1) + vite-node: 1.4.0(@types/node@20.12.7)(sass@1.56.1) why-is-node-running: 2.2.2 + optionalDependencies: + '@types/node': 20.12.7 + jsdom: 20.0.2 transitivePeerDependencies: - less - lightningcss From 1ef32d6d543598b2f16ff61acc55178edbef6b6e Mon Sep 17 00:00:00 2001 From: wangsijie Date: Mon, 13 May 2024 10:18:10 +0800 Subject: [PATCH 366/687] chore: add changeset for org api resource (#5719) chore: add change set for org api resource --- .changeset/thirty-cameras-explain.md | 13 +++++++++++++ 1 file changed, 13 insertions(+) create mode 100644 .changeset/thirty-cameras-explain.md diff --git a/.changeset/thirty-cameras-explain.md b/.changeset/thirty-cameras-explain.md new file mode 100644 index 00000000000..d8cf79297b2 --- /dev/null +++ b/.changeset/thirty-cameras-explain.md @@ -0,0 +1,13 @@ +--- +"@logto/core": minor +--- + +update token grant to support organization API resources + +Organization roles can be assigned with scopes (permissions) from the API resources, and the token grant now supports this. + +Once the user is consent to an application with "resources" assigned, the token grant will now include the scopes inherited from all assigned organization roles. + +Users can narrow down the scopes by passing `organization_id` when granting an access token, and the token will only include the scopes from the organization roles of the specified organization, the access token will contain an extra claim `organization_id` to indicate the organization the token is granted for. Then the resource server can use this claim to protect the resource with additional organization-level authorization. + +This change is backward compatible, and the existing token grant will continue to work as before. From 517c7330d418d11585d84888f1cb6fdfb9294f77 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 13 May 2024 10:32:46 +0800 Subject: [PATCH 367/687] chore(deps): update dependency @simplewebauthn/browser to v10 (#5703) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- packages/experience/package.json | 2 +- pnpm-lock.yaml | 61 +++++++++++++++++++------------- 2 files changed, 37 insertions(+), 26 deletions(-) diff --git a/packages/experience/package.json b/packages/experience/package.json index 9aae62021e3..526c736fc2c 100644 --- a/packages/experience/package.json +++ b/packages/experience/package.json @@ -39,7 +39,7 @@ "@silverhand/essentials": "^2.9.0", "@silverhand/ts-config": "6.0.0", "@silverhand/ts-config-react": "6.0.0", - "@simplewebauthn/browser": "^9.0.0", + "@simplewebauthn/browser": "^10.0.0", "@simplewebauthn/types": "^9.0.1", "@swc/core": "^1.3.52", "@swc/jest": "^0.2.26", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index caa106faa04..1560804ff6e 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -3521,8 +3521,8 @@ importers: specifier: 6.0.0 version: 6.0.0(typescript@5.3.3) '@simplewebauthn/browser': - specifier: ^9.0.0 - version: 9.0.1 + specifier: ^10.0.0 + version: 10.0.0 '@simplewebauthn/types': specifier: ^9.0.1 version: 9.0.1 @@ -4488,6 +4488,7 @@ packages: '@babel/plugin-proposal-object-rest-spread@7.12.1': resolution: {integrity: sha512-s6SowJIjzlhx8o7lsFx5zmY4At6CTtDvgNQDdPzkBQucle58A6b/TTeEBYtyDgmcXjUTM+vE8YOGHZzzbc/ioA==} + deprecated: This proposal has been merged to the ECMAScript standard and thus this plugin is no longer maintained. Please use @babel/plugin-transform-object-rest-spread instead. peerDependencies: '@babel/core': ^7.0.0-0 @@ -5933,13 +5934,16 @@ packages: peerDependencies: typescript: ^5.3.3 - '@simplewebauthn/browser@9.0.1': - resolution: {integrity: sha512-wD2WpbkaEP4170s13/HUxPcAV5y4ZXaKo1TfNklS5zDefPinIgXOpgz1kpEvobAsaLPa2KeH7AKKX/od1mrBJw==} + '@simplewebauthn/browser@10.0.0': + resolution: {integrity: sha512-hG0JMZD+LiLUbpQcAjS4d+t4gbprE/dLYop/CkE01ugU/9sKXflxV5s0DRjdz3uNMFecatRfb4ZLG3XvF8m5zg==} '@simplewebauthn/server@9.0.1': resolution: {integrity: sha512-XnilMoBygy2BOZjIHPxby+7ENx5ChN2wXfhd14mOgO/XitYMqdphTo/kwgxEI4/Je3lELK1h/eLDJqM2fIKS1w==} engines: {node: '>=16.0.0'} + '@simplewebauthn/types@10.0.0': + resolution: {integrity: sha512-SFXke7xkgPRowY2E+8djKbdEznTVnD5R6GO7GPTthpHrokLvNKw8C3lFZypTxLI7KkCfGPfhtqB3d7OVGGa9jQ==} + '@simplewebauthn/types@9.0.1': resolution: {integrity: sha512-tGSRP1QvsAvsJmnOlRQyw/mvK9gnPtjEc5fg2+m8n+QUa+D7rvrKkOYyfpy42GTs90X3RDOnqJgfHt+qO67/+w==} @@ -6795,6 +6799,7 @@ packages: abab@2.0.6: resolution: {integrity: sha512-j2afSsaIENvHZN2B8GOpF566vZ5WVk5opAiMTvWgaQT8DkbOqsTfvNAvHoRGU2zzP8cPoqys+xHTRDWW8L+/BA==} + deprecated: Use your platform's native atob() and btoa() methods instead abbrev@1.1.1: resolution: {integrity: sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==} @@ -7780,7 +7785,7 @@ packages: engines: {node: '>=6'} deep-equal@1.0.1: - resolution: {integrity: sha1-9dJgKStmDghO/0zbyfCK0yR0SLU=} + resolution: {integrity: sha512-bHtC0iYvWhyaTzvV3CZgPeZQqCOBGyGsVV7v4eevpdkLHfiSrXUdBG+qAuSz4RI70sszvjQ1QSZ98An1yNwpSw==} deep-is@0.1.4: resolution: {integrity: sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==} @@ -7824,7 +7829,7 @@ packages: engines: {node: '>=0.4.0'} delegates@1.0.0: - resolution: {integrity: sha1-hMbhWbgZBP3KWaDvRM2HDTElD5o=} + resolution: {integrity: sha512-bd2L678uiWATM6m5Z1VzNCErI3jiGzt6HGY8OVICs40JQq/HALfbyNJmp0UDakEY4pMMaN0Ly5om/B1VI/+xfQ==} depd@1.1.2: resolution: {integrity: sha512-7emPTl6Dpo6JRXOXjLRxck+FlLRX5847cLKEn00PLAgc3g2hTZZgr+e4c2v6QpSmLeFP3n5yUo7ft6avBK/5jQ==} @@ -7839,7 +7844,7 @@ packages: engines: {node: '>=6'} destroy@1.0.4: - resolution: {integrity: sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA=} + resolution: {integrity: sha512-3NdhDuEXnfun/z7x9GOElY49LoqVHoGScmOKwmxhsS8N5Y+Z8KyPPDnaSzqWgYt/ji4mqwfTS34Htrk0zPIXVg==} destroy@1.2.0: resolution: {integrity: sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==} @@ -7927,6 +7932,7 @@ packages: domexception@4.0.0: resolution: {integrity: sha512-A2is4PLG+eeSfoTMA95/s4pvAoSo2mKtiM5jlHkAVewmiO8ISFTFKZjH7UAM1Atli/OT/7JHOrJRJiMKUZKYBw==} engines: {node: '>=12'} + deprecated: Use your platform's native DOMException instead domhandler@4.3.1: resolution: {integrity: sha512-GrwoxYN+uWlzO8uhUXRl0P+kHE4GtVPfYzVLcUxPL7KNdHKj66vvlhiweIHqYYXWlw+T8iLMp42Lm67ghw4WMQ==} @@ -7966,7 +7972,7 @@ packages: resolution: {integrity: sha512-nagl3RYrbNv6kQkeJIpt6NJZy8twLB/2vtz6yN9Z4vRKHN4/QZJIEbqohALSgwKdnksuY3k5Addp5lg8sVoVcQ==} ee-first@1.1.1: - resolution: {integrity: sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0=} + resolution: {integrity: sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==} electron-to-chromium@1.4.281: resolution: {integrity: sha512-yer0w5wCYdFoZytfmbNhwiGI/3cW06+RV7E23ln4490DVMxs7PvYpbsrSmAiBn/V6gode8wvJlST2YfWgvzWIg==} @@ -7994,7 +8000,7 @@ packages: resolution: {integrity: sha512-ucAnuBEhUK4boH2HjVYG5Q2mQyPorvv0u/ocS+zhdw0S8AlHYY+GOFhP1Gio5z4icpP2ivFSvhtFjQi8+T9ppw==} encodeurl@1.0.2: - resolution: {integrity: sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k=} + resolution: {integrity: sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==} engines: {node: '>= 0.8'} end-of-stream@1.4.4: @@ -8077,7 +8083,7 @@ packages: engines: {node: '>=6'} escape-html@1.0.3: - resolution: {integrity: sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg=} + resolution: {integrity: sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==} escape-string-regexp@1.0.5: resolution: {integrity: sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==} @@ -8550,14 +8556,14 @@ packages: engines: {node: '>= 6'} format@0.2.2: - resolution: {integrity: sha1-1hcBB+nv3E7TDJ3DkBbflCtctYs=} + resolution: {integrity: sha512-wzsgA6WOq+09wrU1tsJ09udeR/YZRaeArL9e1wPbFg3GG2yDnC2ldKpxs4xunpFF9DgqCqOIra3bc1HWrJ37Ww==} engines: {node: '>=0.4.x'} formidable@3.5.1: resolution: {integrity: sha512-WJWKelbRHN41m5dumb0/k8TeAx7Id/y3a+Z7QfhxP/htI9Js5zYaEDtG8uMgG0vM0lOlqnmjE99/kfpOYi/0Og==} fresh@0.5.2: - resolution: {integrity: sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac=} + resolution: {integrity: sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==} engines: {node: '>= 0.6'} fs-exists-sync@0.1.0: @@ -9004,7 +9010,7 @@ packages: engines: {node: '>=16.17.0'} humanize-number@0.0.2: - resolution: {integrity: sha1-EcCvakcWQ2M1iFiASPF5lUFInBg=} + resolution: {integrity: sha512-un3ZAcNQGI7RzaWGZzQDH47HETM4Wrj6z6E4TId8Yeq9w5ZKUVB1nrT2jwFheTUjEmqcgTjXDc959jum+ai1kQ==} husky@9.0.7: resolution: {integrity: sha512-vWdusw+y12DUEeoZqW1kplOFqk3tedGV8qlga8/SF6a3lOiWLqGZZQvfWvY0fQYdfiRi/u1DFNpudTSV9l1aCg==} @@ -9026,7 +9032,7 @@ packages: engines: {node: '>=0.10.0'} icss-replace-symbols@1.1.0: - resolution: {integrity: sha1-Bupvg2ead0njhs/h/oEq5dsiPe0=} + resolution: {integrity: sha512-chIaY3Vh2mh2Q3RGXttaDIzeiPvaVXJ+C4DAh/w3c37SKZ/U6PGMmuicR2EQQp9bKG8zLMCl7I+PtIoOOPp8Gg==} icss-utils@5.1.0: resolution: {integrity: sha512-soFhflCVWLfRNOPU3iv5Z9VUdT44xFRbzjLsEzSr5AQmgqPMTHdU3PMT1Cf1ssx8fLNJDA1juftYl+PUcv3MqA==} @@ -9799,6 +9805,7 @@ packages: koa-router@12.0.0: resolution: {integrity: sha512-zGrdiXygGYW8WvrzeGsHZvKnHs4DzyGoqJ9a8iHlRkiwuEAOAPyI27//OlhoWdgFAEIM3qbUgr0KCuRaP/TCag==} engines: {node: '>= 12'} + deprecated: '**IMPORTANT 10x+ PERFORMANCE UPGRADE**: Please upgrade to v12.0.1+ as we have fixed an issue with debuglog causing 10x slower router benchmark performance, see https://github.com/koajs/router/pull/173' koa-send@5.0.1: resolution: {integrity: sha512-tmcyQ/wXXuxpDxyNXv5yNNkdAMdFRqwtegBXUaowiQzUKqJehttS0x2j0eOZDQAyloAth5w6wwBImnFzkUz3pQ==} @@ -10161,7 +10168,7 @@ packages: resolution: {integrity: sha512-/sKlQJCBYVY9Ers9hqzKou4H6V5UWc/M59TH2dvkt+84itfnq7uFOMLpOiOS4ujvHP4etln18fmIxA5R5fll0g==} media-typer@0.3.0: - resolution: {integrity: sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g=} + resolution: {integrity: sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ==} engines: {node: '>= 0.6'} meow@10.1.5: @@ -10611,7 +10618,7 @@ packages: engines: {node: ^10.13.0 || >=12.0.0} on-finished@2.3.0: - resolution: {integrity: sha1-IPEzZIGwg811M3mSoWlxqi2QaUc=} + resolution: {integrity: sha512-ikqdkGAAyf/X/gPhXGvfgAytDZtDbr+bkNUJ0N9h5MI/dmdgCs3l6hoHrcUv41sRKew3jIwrp4qQDXiK99Utww==} engines: {node: '>= 0.8'} on-finished@2.4.1: @@ -10630,7 +10637,7 @@ packages: engines: {node: '>=12'} only@0.0.2: - resolution: {integrity: sha1-Kv3oTQPlC5qO3EROMGEKcCle37Q=} + resolution: {integrity: sha512-Fvw+Jemq5fjjyWz6CpKx6w9s7xxqo3+JCyM0WXWeCSOboZ8ABkyvP8ID4CZuChA/wxSx+XSJmdOm8rGVyJ1hdQ==} openapi-schema-validator@12.1.3: resolution: {integrity: sha512-xTHOmxU/VQGUgo7Cm0jhwbklOKobXby+/237EG967+3TQEYJztMgX9Q5UE2taZKwyKPUq0j11dngpGjUuxz1hQ==} @@ -10799,7 +10806,7 @@ packages: engines: {node: '>= 0.8'} passthrough-counter@1.0.0: - resolution: {integrity: sha1-GWfZ5m2lcrXAI8eH2xEqOHqxZvo=} + resolution: {integrity: sha512-Wy8PXTLqPAN0oEgBrlnsXPMww3SYJ44tQ8aVrGAI4h4JZYCS0oYqsPqtPR8OhJpv6qFbpbB7XAn0liKV7EXubA==} path-exists@4.0.0: resolution: {integrity: sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==} @@ -11604,7 +11611,7 @@ packages: engines: {node: '>=8'} resolve-path@1.4.0: - resolution: {integrity: sha1-xL2p9e+y/OZSR4c6s2u02DT+Fvc=} + resolution: {integrity: sha512-i1xevIst/Qa+nA9olDxLWnLk8YZbi8R/7JPbCMcgyWaFR6bKWaexgJgEB5oc2PKMjYdrHynyz0NY+if+H98t1w==} engines: {node: '>= 0.8'} resolve-pkg-maps@1.0.0: @@ -11959,7 +11966,7 @@ packages: resolution: {integrity: sha512-d/5Z4/2iiCnHw6Xzghyhb+GcmF89bxwgXG60wjIiZaxnymbyOmI8Hk4VqHXiVVp6u2ysaskFfXg3ekCj4WNftQ==} statuses@1.5.0: - resolution: {integrity: sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow=} + resolution: {integrity: sha512-OpZ3zP+jT1PI7I8nemJX4AKmAX070ZkYPVWV/AaKTJl+tXCTGyVdC1a4SL8RUQYEwk/f34ZX8UTykN68FwrqAA==} engines: {node: '>= 0.6'} statuses@2.0.1: @@ -11990,7 +11997,7 @@ packages: engines: {node: '>=0.6.19'} string-hash@1.1.3: - resolution: {integrity: sha1-6Kr8CsGFW0Zmkp7X3RJ1311sgRs=} + resolution: {integrity: sha512-kJUvRUFK49aub+a7T1nNE66EJbZBMnBgoC1UbCZ5n6bsZKBRga4KgBRTMn/pFkeCZSYtNeSyMxPDM0AXWELk2A==} string-length@4.0.2: resolution: {integrity: sha512-+l6rNN5fYHNhZZy41RXsYptCjA2Igmq4EG7kZAYFQI1E1VTXarr6ZPXBg6eq7Y6eK4FEhY6AJlyuFIb/v/S0VQ==} @@ -11998,6 +12005,7 @@ packages: string-similarity@4.0.4: resolution: {integrity: sha512-/q/8Q4Bl4ZKAPjj8WerIBJWALKkaPRfrvhfF8k/B23i4nzrlRj2/go1m90In7nG/3XDSbOo0+pu6RvCTM9RGMQ==} + deprecated: Package no longer supported. Contact Support at https://www.npmjs.com/support for more info. string-width@4.2.3: resolution: {integrity: sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==} @@ -12306,7 +12314,8 @@ packages: resolution: {integrity: sha512-rjUWSqnfTNrjbB9NQWfPMH/xRK1deHeGsHoVfpxJ++XeYXE0d6B1En37AHfw3jtfTU7dzMzZL2jjpe8Qb5gLIQ==} trim@0.0.1: - resolution: {integrity: sha1-WFhUf2spB1fulczMZm+1AITEYN0=} + resolution: {integrity: sha512-YzQV+TZg4AxpKxaTHK3c3D+kRDCGVEE7LemdlQZoQXn0iennk10RsIoY6ikzAqJTc9Xjl9C1/waHom/J86ziAQ==} + deprecated: Use String.prototype.trim() instead trough@1.0.5: resolution: {integrity: sha512-rvuRbTarPXmMb79SmzEp8aqXNKcK+y0XaB298IXueQ8I2PsrATcPBCSPyK/dDNa2iWOhKlfNnOjdAOTBU/nkFA==} @@ -12667,7 +12676,7 @@ packages: optional: true void-elements@3.1.0: - resolution: {integrity: sha1-YU9/v42AHwu18GYfWy9XhXUOTwk=} + resolution: {integrity: sha512-Dhxzh5HZuiHQhbvTW9AMetFfBHDMYpo23Uo9btPXgdYP+3T5S+p+jgNy7spra+veYhBP2dCSgxR/i2Y02h5/6w==} engines: {node: '>=0.10.0'} w3c-xmlserializer@3.0.0: @@ -15881,9 +15890,9 @@ snapshots: dependencies: typescript: 5.3.3 - '@simplewebauthn/browser@9.0.1': + '@simplewebauthn/browser@10.0.0': dependencies: - '@simplewebauthn/types': 9.0.1 + '@simplewebauthn/types': 10.0.0 '@simplewebauthn/server@9.0.1': dependencies: @@ -15899,6 +15908,8 @@ snapshots: transitivePeerDependencies: - encoding + '@simplewebauthn/types@10.0.0': {} + '@simplewebauthn/types@9.0.1': {} '@sinclair/typebox@0.24.46': {} From d38ddf15b7d8459543ef502e7635601e6a6ebe61 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 13 May 2024 02:47:09 +0000 Subject: [PATCH 368/687] chore(deps): update dependency @simplewebauthn/types to v10 (#5704) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- packages/experience/package.json | 2 +- pnpm-lock.yaml | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/experience/package.json b/packages/experience/package.json index 526c736fc2c..7f5685163e1 100644 --- a/packages/experience/package.json +++ b/packages/experience/package.json @@ -40,7 +40,7 @@ "@silverhand/ts-config": "6.0.0", "@silverhand/ts-config-react": "6.0.0", "@simplewebauthn/browser": "^10.0.0", - "@simplewebauthn/types": "^9.0.1", + "@simplewebauthn/types": "^10.0.0", "@swc/core": "^1.3.52", "@swc/jest": "^0.2.26", "@testing-library/react": "^15.0.0", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 1560804ff6e..fc22c5fcfda 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -3524,8 +3524,8 @@ importers: specifier: ^10.0.0 version: 10.0.0 '@simplewebauthn/types': - specifier: ^9.0.1 - version: 9.0.1 + specifier: ^10.0.0 + version: 10.0.0 '@swc/core': specifier: ^1.3.52 version: 1.3.52(@swc/helpers@0.5.1) From b7d950b40cc528868248d39deafb0446de3a8de5 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 13 May 2024 11:05:08 +0800 Subject: [PATCH 369/687] fix(deps): update dependency @simplewebauthn/server to v10 (#5705) * fix(deps): update dependency @simplewebauthn/server to v10 * fix(core): update code to support @simplewebauthn/server v10 --------- Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> Co-authored-by: wangsijie --- packages/core/package.json | 2 +- .../src/routes/interaction/utils/webauthn.ts | 8 +- .../verifications/mfa-payload-verification.ts | 2 +- pnpm-lock.yaml | 111 +++--------------- 4 files changed, 22 insertions(+), 101 deletions(-) diff --git a/packages/core/package.json b/packages/core/package.json index 5f71ac05e60..66659006127 100644 --- a/packages/core/package.json +++ b/packages/core/package.json @@ -45,7 +45,7 @@ "@logto/shared": "workspace:^3.1.0", "@silverhand/essentials": "^2.9.0", "@silverhand/slonik": "31.0.0-beta.2", - "@simplewebauthn/server": "^9.0.0", + "@simplewebauthn/server": "^10.0.0", "@withtyped/client": "^0.8.7", "camelcase": "^8.0.0", "camelcase-keys": "^9.0.0", diff --git a/packages/core/src/routes/interaction/utils/webauthn.ts b/packages/core/src/routes/interaction/utils/webauthn.ts index ced78779a6f..c9f71077f44 100644 --- a/packages/core/src/routes/interaction/utils/webauthn.ts +++ b/packages/core/src/routes/interaction/utils/webauthn.ts @@ -37,7 +37,7 @@ export const generateWebAuthnRegistrationOptions = async ({ const options: GenerateRegistrationOptionsOpts = { rpName: rpId, rpID: rpId, - userID: id, + userID: Uint8Array.from(Buffer.from(id)), userName: getUserDisplayName({ username, primaryEmail, primaryPhone }) ?? 'Unnamed User', timeout: 60_000, attestationType: 'none', @@ -47,7 +47,7 @@ export const generateWebAuthnRegistrationOptions = async ({ verification.type === MfaFactor.WebAuthn ) .map(({ credentialId, transports }) => ({ - id: Uint8Array.from(Buffer.from(credentialId, 'base64')), + id: credentialId, type: 'public-key', transports, })), @@ -99,7 +99,7 @@ export const generateWebAuthnAuthenticationOptions = async ({ const options: GenerateAuthenticationOptionsOpts = { timeout: 60_000, allowCredentials: webAuthnVerifications.map(({ credentialId, transports }) => ({ - id: isoBase64URL.toBuffer(credentialId), + id: credentialId, type: 'public-key', transports, })), @@ -151,7 +151,7 @@ export const verifyWebAuthnAuthentication = async ({ expectedRPID: rpId, authenticator: { credentialPublicKey: isoBase64URL.toBuffer(publicKey), - credentialID: isoBase64URL.toBuffer(credentialId), + credentialID: credentialId, counter, transports, }, diff --git a/packages/core/src/routes/interaction/verifications/mfa-payload-verification.ts b/packages/core/src/routes/interaction/verifications/mfa-payload-verification.ts index c791ccb83f4..4fb69751640 100644 --- a/packages/core/src/routes/interaction/verifications/mfa-payload-verification.ts +++ b/packages/core/src/routes/interaction/verifications/mfa-payload-verification.ts @@ -106,7 +106,7 @@ const verifyBindWebAuthn = async ( return { type, - credentialId: isoBase64URL.fromBuffer(credentialID), + credentialId: credentialID, publicKey: isoBase64URL.fromBuffer(credentialPublicKey), counter, agent: userAgent, diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index fc22c5fcfda..f59cbbe08ea 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -3133,8 +3133,8 @@ importers: specifier: 31.0.0-beta.2 version: 31.0.0-beta.2 '@simplewebauthn/server': - specifier: ^9.0.0 - version: 9.0.1 + specifier: ^10.0.0 + version: 10.0.0 '@withtyped/client': specifier: ^0.8.7 version: 0.8.7(zod@3.22.4) @@ -4615,36 +4615,6 @@ packages: '@bcoe/v8-coverage@0.2.3': resolution: {integrity: sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==} - '@cbor-extract/cbor-extract-darwin-arm64@2.2.0': - resolution: {integrity: sha512-P7swiOAdF7aSi0H+tHtHtr6zrpF3aAq/W9FXx5HektRvLTM2O89xCyXF3pk7pLc7QpaY7AoaE8UowVf9QBdh3w==} - cpu: [arm64] - os: [darwin] - - '@cbor-extract/cbor-extract-darwin-x64@2.2.0': - resolution: {integrity: sha512-1liF6fgowph0JxBbYnAS7ZlqNYLf000Qnj4KjqPNW4GViKrEql2MgZnAsExhY9LSy8dnvA4C0qHEBgPrll0z0w==} - cpu: [x64] - os: [darwin] - - '@cbor-extract/cbor-extract-linux-arm64@2.2.0': - resolution: {integrity: sha512-rQvhNmDuhjTVXSPFLolmQ47/ydGOFXtbR7+wgkSY0bdOxCFept1hvg59uiLPT2fVDuJFuEy16EImo5tE2x3RsQ==} - cpu: [arm64] - os: [linux] - - '@cbor-extract/cbor-extract-linux-arm@2.2.0': - resolution: {integrity: sha512-QeBcBXk964zOytiedMPQNZr7sg0TNavZeuUCD6ON4vEOU/25+pLhNN6EDIKJ9VLTKaZ7K7EaAriyYQ1NQ05s/Q==} - cpu: [arm] - os: [linux] - - '@cbor-extract/cbor-extract-linux-x64@2.2.0': - resolution: {integrity: sha512-cWLAWtT3kNLHSvP4RKDzSTX9o0wvQEEAj4SKvhWuOVZxiDAeQazr9A+PSiRILK1VYMLeDml89ohxCnUNQNQNCw==} - cpu: [x64] - os: [linux] - - '@cbor-extract/cbor-extract-win32-x64@2.2.0': - resolution: {integrity: sha512-l2M+Z8DO2vbvADOBNLbbh9y5ST1RY5sqkWOg/58GkUPBYou/cuNZ68SGQ644f1CvZ8kcOxyZtw06+dxWHIoN/w==} - cpu: [x64] - os: [win32] - '@changesets/apply-release-plan@6.1.4': resolution: {integrity: sha512-FMpKF1fRlJyCZVYHr3CbinpZZ+6MwvOtWUuO8uo+svcATEoc1zRDcj23pAurJ2TZ/uVz1wFHH6K3NlACy0PLew==} @@ -5157,6 +5127,9 @@ packages: resolution: {integrity: sha512-ribfPYfHb+Uw3b27Eiw6NPqjhIhTpVFzEWLwyc/1Xp+DCdwRRyIlAUODX+9bPARF6aQtUu1+/PHzdNvRzcs/+Q==} engines: {node: '>= 12'} + '@levischuck/tiny-cbor@0.2.2': + resolution: {integrity: sha512-f5CnPw997Y2GQ8FAvtuVVC19FX8mwNNC+1XJcIi16n/LTJifKO6QBgGLgN3YEmqtGMk17SKSuoWES3imJVxAVw==} + '@lezer/common@0.15.12': resolution: {integrity: sha512-edfwCxNLnzq5pBA/yaIhwJ3U3Kz8VAUOTRg0hhxaizaI1N+qxV7EXDv/kLCkLeq2RzSFvxexlaj5Mzfn2kY0Ig==} @@ -5937,9 +5910,12 @@ packages: '@simplewebauthn/browser@10.0.0': resolution: {integrity: sha512-hG0JMZD+LiLUbpQcAjS4d+t4gbprE/dLYop/CkE01ugU/9sKXflxV5s0DRjdz3uNMFecatRfb4ZLG3XvF8m5zg==} - '@simplewebauthn/server@9.0.1': - resolution: {integrity: sha512-XnilMoBygy2BOZjIHPxby+7ENx5ChN2wXfhd14mOgO/XitYMqdphTo/kwgxEI4/Je3lELK1h/eLDJqM2fIKS1w==} - engines: {node: '>=16.0.0'} + '@simplewebauthn/server@10.0.0': + resolution: {integrity: sha512-w5eIoiF7ltg1sgggjY5Tx654j+DBuyEx2B3869jjmPp0xl2Z4BUP4kJ3yJ6DnZIv+ZYYntT3E6nZXNjPOQbrtw==} + engines: {node: '>=20.0.0'} + + '@simplewebauthn/types@10.0.0': + resolution: {integrity: sha512-SFXke7xkgPRowY2E+8djKbdEznTVnD5R6GO7GPTthpHrokLvNKw8C3lFZypTxLI7KkCfGPfhtqB3d7OVGGa9jQ==} '@simplewebauthn/types@10.0.0': resolution: {integrity: sha512-SFXke7xkgPRowY2E+8djKbdEznTVnD5R6GO7GPTthpHrokLvNKw8C3lFZypTxLI7KkCfGPfhtqB3d7OVGGa9jQ==} @@ -7272,13 +7248,6 @@ packages: caniuse-lite@1.0.30001610: resolution: {integrity: sha512-QFutAY4NgaelojVMjY63o6XlZyORPaLfyMnsl3HgnWdJUcX6K0oaJymHjH8PT5Gk7sTm8rvC/c5COUQKXqmOMA==} - cbor-extract@2.2.0: - resolution: {integrity: sha512-Ig1zM66BjLfTXpNgKpvBePq271BPOvu8MR0Jl080yG7Jsl+wAZunfrwiwA+9ruzm/WEdIV5QF/bjDZTqyAIVHA==} - hasBin: true - - cbor-x@1.5.4: - resolution: {integrity: sha512-PVKILDn+Rf6MRhhcyzGXi5eizn1i0i3F8Fe6UMMxXBnWkalq9+C5+VTmlIjAYM4iF2IYF2N+zToqAfYOp+3rfw==} - ccount@1.1.0: resolution: {integrity: sha512-vlNK021QdI7PNeiUh/lKkC/mNHHfV0m/Ad5JoI0TYtlBnJAslM/JIkm/tGC88bkLIwO6OQ5uV6ztS6kVAtCDlg==} @@ -7862,10 +7831,6 @@ packages: engines: {node: '>=0.10'} hasBin: true - detect-libc@2.0.2: - resolution: {integrity: sha512-UX6sGumvvqSaXgdKGUsgZWqcUyIXZ/vZTrlRT/iobiKhGL0zL4d3osHj3uqllWJK+i+sixDS/3COVEOFbupFyw==} - engines: {node: '>=8'} - detect-newline@3.1.0: resolution: {integrity: sha512-TLz+x/vEXm/Y7P7wn1EJFNLxYpUD4TgMosxY6fAVJUnJMbupHBOncxyWUG9OpTaH9EBD7uFI5LfEgmMOc54DsA==} engines: {node: '>=8'} @@ -10488,10 +10453,6 @@ packages: resolution: {integrity: sha512-YlCCc6Wffkx0kHkmam79GKvDQ6x+QZkMjFGrIMxgFNILFvGSbCp2fCBC55pGTT9gVaz8Na5CLmxt/urtzRv36w==} hasBin: true - node-gyp-build-optional-packages@5.1.1: - resolution: {integrity: sha512-+P72GAjVAbTxjjwUmwjVrqrdZROD4nf8KgpBoDxqXXTiYZZt/ud60dE5yvCSr9lRO8e8yv6kgJIC0K0PfZFVQw==} - hasBin: true - node-gyp-build@4.5.0: resolution: {integrity: sha512-2iGbaQBV+ITgCz76ZEjmhUKAKVf7xfY1sRl4UiKQspfZMH2h06SyhNsnSVy50cwkFQDGLyif6m/6uFXHkOZ6rg==} hasBin: true @@ -13937,24 +13898,6 @@ snapshots: '@bcoe/v8-coverage@0.2.3': {} - '@cbor-extract/cbor-extract-darwin-arm64@2.2.0': - optional: true - - '@cbor-extract/cbor-extract-darwin-x64@2.2.0': - optional: true - - '@cbor-extract/cbor-extract-linux-arm64@2.2.0': - optional: true - - '@cbor-extract/cbor-extract-linux-arm@2.2.0': - optional: true - - '@cbor-extract/cbor-extract-linux-x64@2.2.0': - optional: true - - '@cbor-extract/cbor-extract-win32-x64@2.2.0': - optional: true - '@changesets/apply-release-plan@6.1.4': dependencies: '@babel/runtime': 7.21.0 @@ -14723,6 +14666,8 @@ snapshots: transitivePeerDependencies: - supports-color + '@levischuck/tiny-cbor@0.2.2': {} + '@lezer/common@0.15.12': {} '@lezer/lr@0.15.8': @@ -15894,16 +15839,16 @@ snapshots: dependencies: '@simplewebauthn/types': 10.0.0 - '@simplewebauthn/server@9.0.1': + '@simplewebauthn/server@10.0.0': dependencies: '@hexagon/base64': 1.1.28 + '@levischuck/tiny-cbor': 0.2.2 '@peculiar/asn1-android': 2.3.10 '@peculiar/asn1-ecc': 2.3.8 '@peculiar/asn1-rsa': 2.3.8 '@peculiar/asn1-schema': 2.3.8 '@peculiar/asn1-x509': 2.3.8 - '@simplewebauthn/types': 9.0.1 - cbor-x: 1.5.4 + '@simplewebauthn/types': 10.0.0 cross-fetch: 4.0.0 transitivePeerDependencies: - encoding @@ -17567,22 +17512,6 @@ snapshots: caniuse-lite@1.0.30001610: {} - cbor-extract@2.2.0: - dependencies: - node-gyp-build-optional-packages: 5.1.1 - optionalDependencies: - '@cbor-extract/cbor-extract-darwin-arm64': 2.2.0 - '@cbor-extract/cbor-extract-darwin-x64': 2.2.0 - '@cbor-extract/cbor-extract-linux-arm': 2.2.0 - '@cbor-extract/cbor-extract-linux-arm64': 2.2.0 - '@cbor-extract/cbor-extract-linux-x64': 2.2.0 - '@cbor-extract/cbor-extract-win32-x64': 2.2.0 - optional: true - - cbor-x@1.5.4: - optionalDependencies: - cbor-extract: 2.2.0 - ccount@1.1.0: {} ccount@2.0.1: {} @@ -18156,9 +18085,6 @@ snapshots: detect-libc@1.0.3: {} - detect-libc@2.0.2: - optional: true - detect-newline@3.1.0: {} devlop@1.1.0: @@ -21594,11 +21520,6 @@ snapshots: node-gyp-build-optional-packages@5.0.7: optional: true - node-gyp-build-optional-packages@5.1.1: - dependencies: - detect-libc: 2.0.2 - optional: true - node-gyp-build@4.5.0: {} node-int64@0.4.0: {} From 0fc9f83b7e2c0e98c3a6463bdba6c0f77254ae6b Mon Sep 17 00:00:00 2001 From: wangsijie Date: Mon, 13 May 2024 11:05:30 +0800 Subject: [PATCH 370/687] fix(core): filter scopes for 3rd-party app (#5845) --- packages/core/src/oidc/resource.ts | 14 +- .../src/routes/interaction/consent/index.ts | 4 + .../src/routes/interaction/consent/utils.ts | 23 ++- .../third-party-sign-in/happy-path.test.ts | 145 ++++++++++++------ 4 files changed, 138 insertions(+), 48 deletions(-) diff --git a/packages/core/src/oidc/resource.ts b/packages/core/src/oidc/resource.ts index 91f3f5b5b00..37c43cf73c5 100644 --- a/packages/core/src/oidc/resource.ts +++ b/packages/core/src/oidc/resource.ts @@ -120,7 +120,11 @@ export const filterResourceScopesForTheThirdPartyApplication = async ( libraries: Libraries, applicationId: string, indicator: string, - scopes: ReadonlyArray<{ name: string; id: string }> + scopes: ReadonlyArray<{ name: string; id: string }>, + { + includeOrganizationResourceScopes = true, + includeResourceScopes = true, + }: { includeOrganizationResourceScopes?: boolean; includeResourceScopes?: boolean } = {} ) => { const { applications: { @@ -154,12 +158,16 @@ export const filterResourceScopesForTheThirdPartyApplication = async ( } // Get the API resource scopes that are enabled in the application - const userConsentResources = await getApplicationUserConsentResourceScopes(applicationId); + const userConsentResources = includeResourceScopes + ? await getApplicationUserConsentResourceScopes(applicationId) + : []; const userConsentResource = userConsentResources.find( ({ resource }) => resource.indicator === indicator ); const userConsentOrganizationResources = EnvSet.values.isDevFeaturesEnabled - ? await getApplicationUserConsentOrganizationResourceScopes(applicationId) + ? includeOrganizationResourceScopes + ? await getApplicationUserConsentOrganizationResourceScopes(applicationId) + : [] : []; const userConsentOrganizationResource = userConsentOrganizationResources.find( ({ resource }) => resource.indicator === indicator diff --git a/packages/core/src/routes/interaction/consent/index.ts b/packages/core/src/routes/interaction/consent/index.ts index d2f05f6773c..471c4b34ded 100644 --- a/packages/core/src/routes/interaction/consent/index.ts +++ b/packages/core/src/routes/interaction/consent/index.ts @@ -106,6 +106,7 @@ export default function consentRoutes( queries, libraries, userId, + applicationId, }); const organizationsWithMissingResourceScopes = await Promise.all( @@ -120,6 +121,7 @@ export default function consentRoutes( libraries, userId, organizationId: id, + applicationId, }); return { name, id, missingResourceScopes }; @@ -249,6 +251,7 @@ export default function consentRoutes( queries, libraries, userId: accountId, + applicationId: clientId, }); // Find the organizations if the application is requesting the organizations scope @@ -268,6 +271,7 @@ export default function consentRoutes( libraries, userId: accountId, organizationId: id, + applicationId: clientId, }); return { name, id, missingResourceScopes }; diff --git a/packages/core/src/routes/interaction/consent/utils.ts b/packages/core/src/routes/interaction/consent/utils.ts index eda88989721..d438bb43233 100644 --- a/packages/core/src/routes/interaction/consent/utils.ts +++ b/packages/core/src/routes/interaction/consent/utils.ts @@ -3,7 +3,10 @@ import { type MissingResourceScopes, type Scope, missingResourceScopesGuard } fr import { errors } from 'oidc-provider'; import { EnvSet } from '#src/env-set/index.js'; -import { findResourceScopes } from '#src/oidc/resource.js'; +import { + filterResourceScopesForTheThirdPartyApplication, + findResourceScopes, +} from '#src/oidc/resource.js'; import type Libraries from '#src/tenants/Libraries.js'; import type Queries from '#src/tenants/Queries.js'; import assertThat from '#src/utils/assert-that.js'; @@ -91,12 +94,14 @@ export const filterAndParseMissingResourceScopes = async ({ queries, libraries, userId, + applicationId, organizationId, }: { resourceScopes: Record; queries: Queries; libraries: Libraries; userId: string; + applicationId: string; organizationId?: string; }) => { const filteredResourceScopes = Object.fromEntries( @@ -118,9 +123,23 @@ export const filterAndParseMissingResourceScopes = async ({ organizationId, }); + // Filter the scopes for the third-party application. + // Although the "missingResourceScopes" from the prompt details are already filtered, + // there may be duplicated scopes from either resources or organization resources. + const filteredScopes = await filterResourceScopesForTheThirdPartyApplication( + libraries, + applicationId, + resourceIndicator, + scopes, + { + includeOrganizationResourceScopes: Boolean(organizationId), + includeResourceScopes: !organizationId, + } + ); + return [ resourceIndicator, - missingScopes.filter((scope) => scopes.some(({ name }) => name === scope)), + missingScopes.filter((scope) => filteredScopes.some(({ name }) => name === scope)), ]; } ) diff --git a/packages/integration-tests/src/tests/api/interaction/third-party-sign-in/happy-path.test.ts b/packages/integration-tests/src/tests/api/interaction/third-party-sign-in/happy-path.test.ts index 8c3e1bb453c..1d9ebea3121 100644 --- a/packages/integration-tests/src/tests/api/interaction/third-party-sign-in/happy-path.test.ts +++ b/packages/integration-tests/src/tests/api/interaction/third-party-sign-in/happy-path.test.ts @@ -136,61 +136,120 @@ describe('consent api', () => { await deleteUser(user.id); }); - it('get consent info with organization resource scopes', async () => { - const application = applications.get(thirdPartyApplicationName); - assert(application, new Error('application.not_found')); - - const resource = await createResource(generateResourceName(), generateResourceIndicator()); - const scope = await createScope(resource.id, generateScopeName()); - const scope2 = await createScope(resource.id, generateScopeName()); + describe('get consent info with organization resource scopes', () => { const roleApi = new OrganizationRoleApiTest(); - const role = await roleApi.create({ - name: generateRoleName(), - resourceScopeIds: [scope.id], - }); const organizationApi = new OrganizationApiTest(); - const organization = await organizationApi.create({ name: 'test_org' }); - const { userProfile, user } = await generateNewUser({ username: true, password: true }); - await organizationApi.addUsers(organization.id, [user.id]); - await organizationApi.addUserRoles(organization.id, user.id, [role.id]); - await assignUserConsentScopes(application.id, { - organizationResourceScopes: [scope.id], - userScopes: [UserScope.Organizations], + afterEach(async () => { + await roleApi.cleanUp(); + await organizationApi.cleanUp(); }); - const client = await initClient( - { - appId: application.id, - appSecret: application.secret, - scopes: [UserScope.Organizations, UserScope.Profile, scope.name, scope2.name], - resources: [resource.indicator], - }, - redirectUri - ); + it('should get scope list from orgniazation roles', async () => { + const application = applications.get(thirdPartyApplicationName); + assert(application, new Error('application.not_found')); - await client.successSend(putInteraction, { - event: InteractionEvent.SignIn, - identifier: { - username: userProfile.username, - password: userProfile.password, - }, + const resource = await createResource(generateResourceName(), generateResourceIndicator()); + const scope = await createScope(resource.id, generateScopeName()); + const scope2 = await createScope(resource.id, generateScopeName()); + const role = await roleApi.create({ + name: generateRoleName(), + resourceScopeIds: [scope.id], + }); + const organization = await organizationApi.create({ name: 'test_org' }); + const { userProfile, user } = await generateNewUser({ username: true, password: true }); + await organizationApi.addUsers(organization.id, [user.id]); + await organizationApi.addUserRoles(organization.id, user.id, [role.id]); + + await assignUserConsentScopes(application.id, { + organizationResourceScopes: [scope.id], + userScopes: [UserScope.Organizations], + }); + + const client = await initClient( + { + appId: application.id, + appSecret: application.secret, + scopes: [UserScope.Organizations, UserScope.Profile, scope.name, scope2.name], + resources: [resource.indicator], + }, + redirectUri + ); + + await client.successSend(putInteraction, { + event: InteractionEvent.SignIn, + identifier: { + username: userProfile.username, + password: userProfile.password, + }, + }); + + const { redirectTo } = await client.submitInteraction(); + + await client.processSession(redirectTo, false); + + const result = await client.send(getConsentInfo); + + expect(result.missingResourceScopes).toHaveLength(0); + // Only scope1, scope2 is removed + expect(result.organizations?.[0]?.missingResourceScopes).toHaveLength(1); + + await deleteResource(resource.id); + await deleteUser(user.id); }); - const { redirectTo } = await client.submitInteraction(); + it('should handle duplicated scopes which are assigned to either personal or organization', async () => { + const application = applications.get(thirdPartyApplicationName); + assert(application, new Error('application.not_found')); - await client.processSession(redirectTo, false); + const resource = await createResource(generateResourceName(), generateResourceIndicator()); + const scope = await createScope(resource.id, generateScopeName()); + const role = await roleApi.create({ + name: generateRoleName(), + resourceScopeIds: [scope.id], + }); + const organization = await organizationApi.create({ name: 'test_org' }); + const { userProfile, user } = await generateNewUser({ username: true, password: true }); + await organizationApi.addUsers(organization.id, [user.id]); + await organizationApi.addUserRoles(organization.id, user.id, [role.id]); - const result = await client.send(getConsentInfo); + // Assign the scope to resourceScopes but not to organizationResourceScopes + await assignUserConsentScopes(application.id, { + resourceScopes: [scope.id], + userScopes: [UserScope.Organizations], + }); - expect(result.missingResourceScopes).toHaveLength(0); - // Only scope1, scope2 is removed - expect(result.organizations?.[0]?.missingResourceScopes).toHaveLength(1); + const client = await initClient( + { + appId: application.id, + appSecret: application.secret, + scopes: [UserScope.Organizations, UserScope.Profile, scope.name], + resources: [resource.indicator], + }, + redirectUri + ); - await roleApi.cleanUp(); - await organizationApi.cleanUp(); - await deleteResource(resource.id); - await deleteUser(user.id); + await client.successSend(putInteraction, { + event: InteractionEvent.SignIn, + identifier: { + username: userProfile.username, + password: userProfile.password, + }, + }); + + const { redirectTo } = await client.submitInteraction(); + + await client.processSession(redirectTo, false); + + const result = await client.send(getConsentInfo); + + expect(result.missingResourceScopes).toHaveLength(0); + // No missing resource scopes, because the scope is only assigned to resourceScopes + expect(result.organizations?.[0]?.missingResourceScopes).toHaveLength(0); + + await deleteResource(resource.id); + await deleteUser(user.id); + }); }); describe('submit consent info', () => { From 393cf44af16ef5512d41f9de3518792de0a8917a Mon Sep 17 00:00:00 2001 From: wangsijie Date: Mon, 13 May 2024 11:25:19 +0800 Subject: [PATCH 371/687] chore: fix pnpm-lock (#5851) --- pnpm-lock.yaml | 14 +++----------- 1 file changed, 3 insertions(+), 11 deletions(-) diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index f59cbbe08ea..852646696d1 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -5917,12 +5917,6 @@ packages: '@simplewebauthn/types@10.0.0': resolution: {integrity: sha512-SFXke7xkgPRowY2E+8djKbdEznTVnD5R6GO7GPTthpHrokLvNKw8C3lFZypTxLI7KkCfGPfhtqB3d7OVGGa9jQ==} - '@simplewebauthn/types@10.0.0': - resolution: {integrity: sha512-SFXke7xkgPRowY2E+8djKbdEznTVnD5R6GO7GPTthpHrokLvNKw8C3lFZypTxLI7KkCfGPfhtqB3d7OVGGa9jQ==} - - '@simplewebauthn/types@9.0.1': - resolution: {integrity: sha512-tGSRP1QvsAvsJmnOlRQyw/mvK9gnPtjEc5fg2+m8n+QUa+D7rvrKkOYyfpy42GTs90X3RDOnqJgfHt+qO67/+w==} - '@sinclair/typebox@0.24.46': resolution: {integrity: sha512-ng4ut1z2MCBhK/NwDVwIQp3pAUOCs/KNaW3cBxdFB2xTDrOuo1xuNmpr/9HHFhxqIvHrs1NTH3KJg6q+JSy1Kw==} @@ -15855,8 +15849,6 @@ snapshots: '@simplewebauthn/types@10.0.0': {} - '@simplewebauthn/types@9.0.1': {} - '@sinclair/typebox@0.24.46': {} '@sinclair/typebox@0.25.21': {} @@ -19699,7 +19691,7 @@ snapshots: is-date-object@1.0.5: dependencies: - has-tostringtag: 1.0.2 + has-tostringtag: 1.0.0 is-decimal@1.0.4: {} @@ -19717,7 +19709,7 @@ snapshots: is-generator-function@1.0.10: dependencies: - has-tostringtag: 1.0.2 + has-tostringtag: 1.0.0 is-get-set-prop@1.0.0: dependencies: @@ -19783,7 +19775,7 @@ snapshots: is-regex@1.1.4: dependencies: call-bind: 1.0.7 - has-tostringtag: 1.0.2 + has-tostringtag: 1.0.0 is-set@2.0.3: {} From f85e1b80889c8994c222e18da634335ad942ad7b Mon Sep 17 00:00:00 2001 From: Xiao Yijun Date: Mon, 13 May 2024 12:10:12 +0800 Subject: [PATCH 372/687] ci(connector): build connectors before publish (#5853) --- .scripts/publish.js | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/.scripts/publish.js b/.scripts/publish.js index e47612dc4f3..77dec0d57ad 100644 --- a/.scripts/publish.js +++ b/.scripts/publish.js @@ -52,6 +52,10 @@ if (taggedPackages.length === 0) { try { execSync('pnpm prepack'); + /** + * Build connectors before publish since some connectors rely on the generated types from oauth2 connector package. + */ + execSync('pnpm connectors build'); execSync('pnpm -r publish'); execSync('git push --follow-tags'); } catch (error) { From 6fe6f87bc3e5464f5fb1206379710fcc39d29e27 Mon Sep 17 00:00:00 2001 From: Xiao Yijun Date: Mon, 13 May 2024 14:18:33 +0800 Subject: [PATCH 373/687] chore(console,experience): remove dev flags add changeset for organization updates (#5763) --- .changeset/loud-mice-divide.md | 12 ++ .../OrganizationScopesSelect/index.tsx | 34 ---- .../src/components/TemplateTable/index.tsx | 2 +- packages/console/src/consts/env.ts | 2 +- .../ConsoleContent/Sidebar/hook.tsx | 3 +- .../src/hooks/use-console-routes/index.tsx | 23 +-- .../routes/organizations.tsx | 5 - .../constants.ts | 15 -- .../index.tsx | 100 +++++----- .../ApplicationScopesAssignmentModal/type.ts | 5 - .../Permissions/PermissionsCard/index.tsx | 18 -- .../PermissionsCard/use-scopes-table.tsx | 11 +- .../Permissions/index.tsx | 8 +- .../src/pages/OrganizationDetails/index.tsx | 4 +- .../src/pages/OrganizationTemplate/index.tsx | 4 +- .../Guide/DynamicFormFields/index.module.scss | 55 ------ .../Guide/DynamicFormFields/index.tsx | 83 --------- .../Guide/Introduction/index.module.scss | 23 --- .../Guide/Introduction/index.tsx | 146 --------------- .../Guide/OrganizationInfo/index.tsx | 107 ----------- .../Guide/OrganizationPermissions/index.tsx | 143 -------------- .../Guide/OrganizationRoles/index.tsx | 174 ------------------ .../src/pages/Organizations/Guide/const.ts | 8 - .../src/pages/Organizations/Guide/index.tsx | 32 ---- .../components/FlexBox/index.module.scss | 0 .../Introduction/components/FlexBox/index.tsx | 0 .../InteractiveDiagram/index.module.scss | 0 .../components/InteractiveDiagram/index.tsx | 0 .../components/Panel/index.module.scss | 0 .../Introduction/components/Panel/index.tsx | 0 .../components/Permission/index.module.scss | 0 .../components/Permission/index.tsx | 0 .../components/Role/index.module.scss | 0 .../Introduction/components/Role/index.tsx | 0 .../components/Section/index.module.scss | 0 .../Introduction/components/Section/index.tsx | 0 .../components/User/index.module.scss | 0 .../Introduction/components/User/index.tsx | 0 .../Introduction/components/Vector/John.tsx | 0 .../Introduction/components/Vector/Sarah.tsx | 0 .../components/Vector/index.module.scss | 0 .../{Guide => Introduction}/index.module.scss | 29 ++- .../Organizations/Introduction/index.tsx | 112 +++++++++++ .../OrganizationsTable/index.tsx | 5 +- .../Organizations/PermissionModal/index.tsx | 106 ----------- .../Organizations/PermissionsCard/index.tsx | 121 ------------ .../pages/Organizations/RoleModal/index.tsx | 137 -------------- .../Organizations/RolesCard/index.module.scss | 7 - .../pages/Organizations/RolesCard/index.tsx | 127 ------------- .../Organizations/Settings/index.module.scss | 9 - .../pages/Organizations/Settings/index.tsx | 13 -- .../console/src/pages/Organizations/consts.ts | 2 - .../console/src/pages/Organizations/index.tsx | 69 +------ .../Consent/OrganizationSelector/index.tsx | 21 +-- .../pages/Consent/ScopesListCard/index.tsx | 62 +------ .../experience/src/pages/Consent/index.tsx | 11 +- .../admin-console/organizations.ts | 23 --- .../admin-console/organizations.ts | 22 --- .../admin-console/organizations.ts | 23 --- .../admin-console/organizations.ts | 23 --- .../admin-console/organizations.ts | 23 --- .../admin-console/organizations.ts | 23 --- .../admin-console/organizations.ts | 23 --- .../admin-console/organizations.ts | 23 --- .../admin-console/organizations.ts | 23 --- .../admin-console/organizations.ts | 23 --- .../admin-console/organizations.ts | 23 --- .../admin-console/organizations.ts | 23 --- .../admin-console/organizations.ts | 23 --- .../admin-console/organizations.ts | 23 --- .../admin-console/organizations.ts | 23 --- 71 files changed, 222 insertions(+), 1970 deletions(-) create mode 100644 .changeset/loud-mice-divide.md delete mode 100644 packages/console/src/components/OrganizationScopesSelect/index.tsx delete mode 100644 packages/console/src/pages/Organizations/Guide/DynamicFormFields/index.module.scss delete mode 100644 packages/console/src/pages/Organizations/Guide/DynamicFormFields/index.tsx delete mode 100644 packages/console/src/pages/Organizations/Guide/Introduction/index.module.scss delete mode 100644 packages/console/src/pages/Organizations/Guide/Introduction/index.tsx delete mode 100644 packages/console/src/pages/Organizations/Guide/OrganizationInfo/index.tsx delete mode 100644 packages/console/src/pages/Organizations/Guide/OrganizationPermissions/index.tsx delete mode 100644 packages/console/src/pages/Organizations/Guide/OrganizationRoles/index.tsx delete mode 100644 packages/console/src/pages/Organizations/Guide/const.ts delete mode 100644 packages/console/src/pages/Organizations/Guide/index.tsx rename packages/console/src/pages/Organizations/{Guide => }/Introduction/components/FlexBox/index.module.scss (100%) rename packages/console/src/pages/Organizations/{Guide => }/Introduction/components/FlexBox/index.tsx (100%) rename packages/console/src/pages/Organizations/{Guide => }/Introduction/components/InteractiveDiagram/index.module.scss (100%) rename packages/console/src/pages/Organizations/{Guide => }/Introduction/components/InteractiveDiagram/index.tsx (100%) rename packages/console/src/pages/Organizations/{Guide => }/Introduction/components/Panel/index.module.scss (100%) rename packages/console/src/pages/Organizations/{Guide => }/Introduction/components/Panel/index.tsx (100%) rename packages/console/src/pages/Organizations/{Guide => }/Introduction/components/Permission/index.module.scss (100%) rename packages/console/src/pages/Organizations/{Guide => }/Introduction/components/Permission/index.tsx (100%) rename packages/console/src/pages/Organizations/{Guide => }/Introduction/components/Role/index.module.scss (100%) rename packages/console/src/pages/Organizations/{Guide => }/Introduction/components/Role/index.tsx (100%) rename packages/console/src/pages/Organizations/{Guide => }/Introduction/components/Section/index.module.scss (100%) rename packages/console/src/pages/Organizations/{Guide => }/Introduction/components/Section/index.tsx (100%) rename packages/console/src/pages/Organizations/{Guide => }/Introduction/components/User/index.module.scss (100%) rename packages/console/src/pages/Organizations/{Guide => }/Introduction/components/User/index.tsx (100%) rename packages/console/src/pages/Organizations/{Guide => }/Introduction/components/Vector/John.tsx (100%) rename packages/console/src/pages/Organizations/{Guide => }/Introduction/components/Vector/Sarah.tsx (100%) rename packages/console/src/pages/Organizations/{Guide => }/Introduction/components/Vector/index.module.scss (100%) rename packages/console/src/pages/Organizations/{Guide => Introduction}/index.module.scss (82%) create mode 100644 packages/console/src/pages/Organizations/Introduction/index.tsx delete mode 100644 packages/console/src/pages/Organizations/PermissionModal/index.tsx delete mode 100644 packages/console/src/pages/Organizations/PermissionsCard/index.tsx delete mode 100644 packages/console/src/pages/Organizations/RoleModal/index.tsx delete mode 100644 packages/console/src/pages/Organizations/RolesCard/index.module.scss delete mode 100644 packages/console/src/pages/Organizations/RolesCard/index.tsx delete mode 100644 packages/console/src/pages/Organizations/Settings/index.module.scss delete mode 100644 packages/console/src/pages/Organizations/Settings/index.tsx delete mode 100644 packages/console/src/pages/Organizations/consts.ts diff --git a/.changeset/loud-mice-divide.md b/.changeset/loud-mice-divide.md new file mode 100644 index 00000000000..a4071141e1d --- /dev/null +++ b/.changeset/loud-mice-divide.md @@ -0,0 +1,12 @@ +--- +"@logto/console": minor +--- + +support adding API resource permissions to organization roles and organization permissions in 3rd-party applications + +## Updates + +- Separated the "Organization template" from the "Organization" page, establishing it as a standalone page for clearer navigation and functionality. +- Enhanced the "Organization template" page by adding functionality that allows users to click on an organization role, which then navigates to the organization role details page where users can view its corresponding permissions and general settings. +- Enabled the assignment of API resource permissions directly from the organization role details page, improving role management and access control. +- Split the permission list for third-party apps into two separate lists: user permissions and organization permissions. Users can now add user profile permissions and API resource permissions for users under user permissions, and add organization permissions and API resource permissions for organizations under organization permissions. diff --git a/packages/console/src/components/OrganizationScopesSelect/index.tsx b/packages/console/src/components/OrganizationScopesSelect/index.tsx deleted file mode 100644 index ca96a799f49..00000000000 --- a/packages/console/src/components/OrganizationScopesSelect/index.tsx +++ /dev/null @@ -1,34 +0,0 @@ -import { type OrganizationScope } from '@logto/schemas'; - -import MultiSelect, { type Option } from '@/ds-components/Select/MultiSelect'; -import useSearchValues from '@/hooks/use-search-values'; - -import Breakable from '../Breakable'; - -type Props = { - readonly value: Array>; - readonly onChange: (value: Array>) => void; - readonly keyword: string; - readonly setKeyword: (keyword: string) => void; -}; - -function OrganizationScopesSelect({ value, onChange, keyword, setKeyword }: Props) { - const { data: scopes, isLoading } = useSearchValues( - 'api/organization-scopes', - keyword - ); - - return ( - ({ value: id, title: name }))} - placeholder="organizations.search_permission_placeholder" - isOptionsLoading={isLoading} - renderOption={({ title, value }) => {title ?? value}} - onChange={onChange} - onSearch={setKeyword} - /> - ); -} - -export default OrganizationScopesSelect; diff --git a/packages/console/src/components/TemplateTable/index.tsx b/packages/console/src/components/TemplateTable/index.tsx index b3996088fe1..ed7faa430f7 100644 --- a/packages/console/src/components/TemplateTable/index.tsx +++ b/packages/console/src/components/TemplateTable/index.tsx @@ -31,7 +31,7 @@ type Props { users, auditLogs, roles, - isDevFeaturesEnabled && organizationTemplate, + organizationTemplate, organizations, - !isDevFeaturesEnabled && { - path: 'organization-guide/*', - element: , - children: [ - { index: true, element: }, - { path: steps.introduction, element: }, - { path: steps.permissions, element: }, - { path: steps.roles, element: }, - { path: steps.organizationInfo, element: }, - ], - }, { path: 'signing-keys', element: }, isCloud && tenantSettings, customizeJwt diff --git a/packages/console/src/hooks/use-console-routes/routes/organizations.tsx b/packages/console/src/hooks/use-console-routes/routes/organizations.tsx index 2bb58902607..0af56c47ffc 100644 --- a/packages/console/src/hooks/use-console-routes/routes/organizations.tsx +++ b/packages/console/src/hooks/use-console-routes/routes/organizations.tsx @@ -1,7 +1,6 @@ import { condArray } from '@silverhand/essentials'; import { Navigate, type RouteObject } from 'react-router-dom'; -import { isDevFeaturesEnabled } from '@/consts/env'; import OrganizationDetails from '@/pages/OrganizationDetails'; import Members from '@/pages/OrganizationDetails/Members'; import Settings from '@/pages/OrganizationDetails/Settings'; @@ -13,10 +12,6 @@ export const organizations: RouteObject = { children: condArray( { index: true, element: }, { path: 'create', element: }, - !isDevFeaturesEnabled && { - path: 'template', - element: , - }, { path: ':id/*', element: , diff --git a/packages/console/src/pages/ApplicationDetails/ApplicationDetailsContent/Permissions/PermissionsCard/ApplicationScopesAssignmentModal/constants.ts b/packages/console/src/pages/ApplicationDetails/ApplicationDetailsContent/Permissions/PermissionsCard/ApplicationScopesAssignmentModal/constants.ts index 3924688ecdc..da7ec52aa1f 100644 --- a/packages/console/src/pages/ApplicationDetails/ApplicationDetailsContent/Permissions/PermissionsCard/ApplicationScopesAssignmentModal/constants.ts +++ b/packages/console/src/pages/ApplicationDetails/ApplicationDetailsContent/Permissions/PermissionsCard/ApplicationScopesAssignmentModal/constants.ts @@ -2,21 +2,6 @@ import { ApplicationUserConsentScopeType } from '@logto/schemas'; import { type PermissionTabType } from './type'; -export const allLevelPermissionTabs: PermissionTabType = Object.freeze({ - [ApplicationUserConsentScopeType.UserScopes]: { - title: 'application_details.permissions.user_profile', - key: ApplicationUserConsentScopeType.UserScopes, - }, - [ApplicationUserConsentScopeType.ResourceScopes]: { - title: 'application_details.permissions.api_permissions', - key: ApplicationUserConsentScopeType.ResourceScopes, - }, - [ApplicationUserConsentScopeType.OrganizationScopes]: { - title: 'application_details.permissions.organization', - key: ApplicationUserConsentScopeType.OrganizationScopes, - }, -}); - export const userLevelPermissionsTabs: PermissionTabType = Object.freeze({ [ApplicationUserConsentScopeType.UserScopes]: { title: 'application_details.permissions.user_profile', diff --git a/packages/console/src/pages/ApplicationDetails/ApplicationDetailsContent/Permissions/PermissionsCard/ApplicationScopesAssignmentModal/index.tsx b/packages/console/src/pages/ApplicationDetails/ApplicationDetailsContent/Permissions/PermissionsCard/ApplicationScopesAssignmentModal/index.tsx index 6d01bc65608..c8028c28bed 100644 --- a/packages/console/src/pages/ApplicationDetails/ApplicationDetailsContent/Permissions/PermissionsCard/ApplicationScopesAssignmentModal/index.tsx +++ b/packages/console/src/pages/ApplicationDetails/ApplicationDetailsContent/Permissions/PermissionsCard/ApplicationScopesAssignmentModal/index.tsx @@ -8,11 +8,7 @@ import DataTransferBox from '@/ds-components/DataTransferBox'; import TabNav, { TabNavItem } from '@/ds-components/TabNav'; import TabWrapper from '@/ds-components/TabWrapper'; -import { - allLevelPermissionTabs, - organizationLevelPermissionsTab, - userLevelPermissionsTabs, -} from './constants'; +import { organizationLevelPermissionsTab, userLevelPermissionsTabs } from './constants'; import { ScopeLevel } from './type'; import useApplicationScopesAssignment from './use-application-scopes-assignment'; @@ -50,47 +46,33 @@ function ApplicationScopesAssignmentModal({ isOpen, onClose, applicationId, scop [scopesAssignment] ); - const tabs = useMemo(() => { - const getPermissionTabs = () => { - if (scopeLevel === ScopeLevel.All) { - return allLevelPermissionTabs; - } - - return scopeLevel === ScopeLevel.User - ? userLevelPermissionsTabs - : organizationLevelPermissionsTab; - }; - - return Object.values(getPermissionTabs()).map(({ title, key }) => { - const selectedDataCount = scopesAssignment[key].selectedData.length; - - return ( - { - setActiveTab(key); - }} - > - {`${String(t(title))}${selectedDataCount ? ` (${selectedDataCount})` : ''}`} - - ); - }); - }, [activeTab, scopeLevel, scopesAssignment, setActiveTab, t]); + const tabs = useMemo( + () => + Object.values( + scopeLevel === ScopeLevel.User ? userLevelPermissionsTabs : organizationLevelPermissionsTab + ).map(({ title, key }) => { + const selectedDataCount = scopesAssignment[key].selectedData.length; + + return ( + { + setActiveTab(key); + }} + > + {`${String(t(title))}${selectedDataCount ? ` (${selectedDataCount})` : ''}`} + + ); + }), + [activeTab, scopeLevel, scopesAssignment, setActiveTab, t] + ); const modalText = useMemo<{ title: AdminConsoleKey; subtitle: AdminConsoleKey; saveButton: AdminConsoleKey; }>(() => { - if (scopeLevel === ScopeLevel.All) { - return { - title: 'application_details.permissions.table_name', - subtitle: 'application_details.permissions.permissions_assignment_description', - saveButton: 'general.save', - }; - } - const scopeLevelPhrase = scopeLevel === ScopeLevel.User ? 'user' : 'organization'; return { @@ -115,7 +97,7 @@ function ApplicationScopesAssignmentModal({ isOpen, onClose, applicationId, scop onConfirm={onSubmitHandler} > {tabs} - {(scopeLevel === ScopeLevel.All || scopeLevel === ScopeLevel.User) && ( + {scopeLevel === ScopeLevel.User && ( <> )} - {(scopeLevel === ScopeLevel.All || scopeLevel === ScopeLevel.Organization) && ( - - - - )} {scopeLevel === ScopeLevel.Organization && ( - - - + <> + + + + + + + )} ); diff --git a/packages/console/src/pages/ApplicationDetails/ApplicationDetailsContent/Permissions/PermissionsCard/ApplicationScopesAssignmentModal/type.ts b/packages/console/src/pages/ApplicationDetails/ApplicationDetailsContent/Permissions/PermissionsCard/ApplicationScopesAssignmentModal/type.ts index 8f033fcc0cd..eadba05e3b5 100644 --- a/packages/console/src/pages/ApplicationDetails/ApplicationDetailsContent/Permissions/PermissionsCard/ApplicationScopesAssignmentModal/type.ts +++ b/packages/console/src/pages/ApplicationDetails/ApplicationDetailsContent/Permissions/PermissionsCard/ApplicationScopesAssignmentModal/type.ts @@ -35,11 +35,6 @@ export type ScopeAssignmentHook< export enum ScopeLevel { User = 'user', Organization = 'organization', - /** - * Only used when the new organization resource scope feature is not ready. - * Todo @xiaoyijun remove this when the new organization resource scope feature is ready. - */ - All = 'all', } export type PermissionTabType = Partial<{ diff --git a/packages/console/src/pages/ApplicationDetails/ApplicationDetailsContent/Permissions/PermissionsCard/index.tsx b/packages/console/src/pages/ApplicationDetails/ApplicationDetailsContent/Permissions/PermissionsCard/index.tsx index a8ee174b4c7..82a33fa4956 100644 --- a/packages/console/src/pages/ApplicationDetails/ApplicationDetailsContent/Permissions/PermissionsCard/index.tsx +++ b/packages/console/src/pages/ApplicationDetails/ApplicationDetailsContent/Permissions/PermissionsCard/index.tsx @@ -47,10 +47,6 @@ function PermissionsCard({ applicationId, scopeLevel }: Props) { const rowGroups = useMemo(() => { const { userLevelRowGroups, organizationLevelGroups } = parseRowGroup(data); - if (scopeLevel === ScopeLevel.All) { - return [...userLevelRowGroups, ...organizationLevelGroups]; - } - return scopeLevel === ScopeLevel.User ? userLevelRowGroups : organizationLevelGroups; }, [data, parseRowGroup, scopeLevel]); @@ -58,20 +54,6 @@ function PermissionsCard({ applicationId, scopeLevel }: Props) { formCard: Omit; tableName: AdminConsoleKey; }>(() => { - if (scopeLevel === ScopeLevel.All) { - return { - formCard: { - title: 'application_details.permissions.name', - description: 'application_details.permissions.description', - learnMoreLink: { - href: getDocumentationUrl(logtoThirdPartyAppPermissionsLink), - targetBlank: 'noopener', - }, - }, - tableName: 'application_details.permissions.table_name', - }; - } - const scopeLevelPhrase = scopeLevel === ScopeLevel.User ? 'user' : 'organization'; return { diff --git a/packages/console/src/pages/ApplicationDetails/ApplicationDetailsContent/Permissions/PermissionsCard/use-scopes-table.tsx b/packages/console/src/pages/ApplicationDetails/ApplicationDetailsContent/Permissions/PermissionsCard/use-scopes-table.tsx index 845661bee2c..19cfb566245 100644 --- a/packages/console/src/pages/ApplicationDetails/ApplicationDetailsContent/Permissions/PermissionsCard/use-scopes-table.tsx +++ b/packages/console/src/pages/ApplicationDetails/ApplicationDetailsContent/Permissions/PermissionsCard/use-scopes-table.tsx @@ -4,12 +4,10 @@ import { type ApplicationUserConsentScopesResponse, ApplicationUserConsentScopeType, } from '@logto/schemas'; -import { condArray } from '@silverhand/essentials'; import { useCallback, type ReactNode } from 'react'; import { useTranslation } from 'react-i18next'; import Tip from '@/assets/icons/tip.svg'; -import { isDevFeaturesEnabled } from '@/consts/env'; import IconButton from '@/ds-components/IconButton'; import { ToggleTip } from '@/ds-components/Tip'; import useApi from '@/hooks/use-api'; @@ -143,14 +141,7 @@ const useScopesTable = () => { organizationLevelGroups: [ // Hide the organization scopes group if there is no organization scopes ...(organizationScopesGroup.data.length > 0 ? [organizationScopesGroup] : []), - ...condArray( - /** - * Hide the organization resource scopes group if the organization resource scopes feature is not ready - */ - isDevFeaturesEnabled && - organizationResourceScopesGroup.length > 0 && - organizationResourceScopesGroup - ), + ...(organizationResourceScopesGroup.length > 0 ? organizationResourceScopesGroup : []), ], }; }, diff --git a/packages/console/src/pages/ApplicationDetails/ApplicationDetailsContent/Permissions/index.tsx b/packages/console/src/pages/ApplicationDetails/ApplicationDetailsContent/Permissions/index.tsx index 7c3a711833d..92edc9f090a 100644 --- a/packages/console/src/pages/ApplicationDetails/ApplicationDetailsContent/Permissions/index.tsx +++ b/packages/console/src/pages/ApplicationDetails/ApplicationDetailsContent/Permissions/index.tsx @@ -1,7 +1,5 @@ import { type Application } from '@logto/schemas'; -import { isDevFeaturesEnabled } from '@/consts/env'; - import PermissionsCard from './PermissionsCard'; import { ScopeLevel } from './PermissionsCard/ApplicationScopesAssignmentModal/type'; import * as styles from './index.module.scss'; @@ -11,13 +9,9 @@ type Props = { }; function Permissions({ application }: Props) { - const displayScopeLevels = isDevFeaturesEnabled - ? [ScopeLevel.User, ScopeLevel.Organization] - : [ScopeLevel.All]; - return (
- {displayScopeLevels.map((scopeLevel) => ( + {[ScopeLevel.User, ScopeLevel.Organization].map((scopeLevel) => ( ))}
diff --git a/packages/console/src/pages/OrganizationDetails/index.tsx b/packages/console/src/pages/OrganizationDetails/index.tsx index df01f929bea..22d3d58e5e5 100644 --- a/packages/console/src/pages/OrganizationDetails/index.tsx +++ b/packages/console/src/pages/OrganizationDetails/index.tsx @@ -19,7 +19,7 @@ import TabNav, { TabNavItem } from '@/ds-components/TabNav'; import useApi, { type RequestError } from '@/hooks/use-api'; import useTenantPathname from '@/hooks/use-tenant-pathname'; -import Introduction from '../Organizations/Guide/Introduction'; +import Introduction from '../Organizations/Introduction'; import * as styles from './index.module.scss'; import { OrganizationDetailsTabs, type OrganizationDetailsOutletContext } from './types'; @@ -91,7 +91,7 @@ function OrganizationDetails() { setIsGuideDrawerOpen(false); }} > - + - +
{isOrganizationsDisabled && ( diff --git a/packages/console/src/pages/Organizations/Guide/DynamicFormFields/index.module.scss b/packages/console/src/pages/Organizations/Guide/DynamicFormFields/index.module.scss deleted file mode 100644 index 6a5f0ee70a2..00000000000 --- a/packages/console/src/pages/Organizations/Guide/DynamicFormFields/index.module.scss +++ /dev/null @@ -1,55 +0,0 @@ -@use '@/scss/underscore' as _; - -.formContainer { - display: flex; - flex-direction: column; - align-items: flex-start; - width: 100%; - gap: _.unit(3); -} - -.title { - font: var(--font-label-2); -} - -.item { - width: 100%; - display: flex; - align-items: center; - gap: _.unit(2); - - .fieldWrapper { - flex: 1; - background: var(--color-layer-light); - padding: _.unit(4); - border-radius: 12px; - } -} - -.skeleton { - width: 100%; - padding: _.unit(1) 0; - - .group { - display: flex; - flex-direction: column; - gap: _.unit(3); - width: 100%; - - + .group { - margin-top: _.unit(6); - } - } - - .title { - width: 200px; - height: 20px; - @include _.shimmering-animation; - } - - .field { - width: 100%; - height: 36px; - @include _.shimmering-animation; - } -} diff --git a/packages/console/src/pages/Organizations/Guide/DynamicFormFields/index.tsx b/packages/console/src/pages/Organizations/Guide/DynamicFormFields/index.tsx deleted file mode 100644 index d63b6c8d223..00000000000 --- a/packages/console/src/pages/Organizations/Guide/DynamicFormFields/index.tsx +++ /dev/null @@ -1,83 +0,0 @@ -import { type AdminConsoleKey } from '@logto/phrases'; -import classNames from 'classnames'; -import { type ReactNode } from 'react'; - -import CirclePlus from '@/assets/icons/circle-plus.svg'; -import Minus from '@/assets/icons/minus.svg'; -import Button from '@/ds-components/Button'; -import DynamicT from '@/ds-components/DynamicT'; -import IconButton from '@/ds-components/IconButton'; - -import * as styles from './index.module.scss'; - -type Props = { - readonly className?: string; - readonly title?: AdminConsoleKey; - readonly fields: Array>; - readonly isLoading?: boolean; - readonly onAdd: () => void; - readonly onRemove: (index: number) => void; - readonly render: (index: number) => ReactNode; -}; - -function Skeleton() { - return ( -
- {Array.from({ length: 2 }).map((_, index) => ( - // eslint-disable-next-line react/no-array-index-key -
-
-
-
- ))} -
- ); -} - -function DynamicFormFields({ - className, - title, - fields, - isLoading, - onAdd, - onRemove, - render, -}: Props) { - return ( -
- {title && ( -
- -
- )} - {fields.map((field, index) => ( -
- {isLoading ? :
{render(index)}
} - {fields.length > 1 && ( - { - onRemove(index); - }} - > - - - )} -
- ))} - {!isLoading && ( -
- ); -} - -export default DynamicFormFields; diff --git a/packages/console/src/pages/Organizations/Guide/Introduction/index.module.scss b/packages/console/src/pages/Organizations/Guide/Introduction/index.module.scss deleted file mode 100644 index cee1680b851..00000000000 --- a/packages/console/src/pages/Organizations/Guide/Introduction/index.module.scss +++ /dev/null @@ -1,23 +0,0 @@ -@use '@/scss/underscore' as _; - -.container { - .title { - font: var(--font-title-1); - } - - .sectionTitle { - font: var(--font-title-2); - } - - .description { - font: var(--font-body-2); - } - - .panel { - flex: 1; - } - - .compact { - padding: _.unit(6); - } -} diff --git a/packages/console/src/pages/Organizations/Guide/Introduction/index.tsx b/packages/console/src/pages/Organizations/Guide/Introduction/index.tsx deleted file mode 100644 index 91b57a76c6b..00000000000 --- a/packages/console/src/pages/Organizations/Guide/Introduction/index.tsx +++ /dev/null @@ -1,146 +0,0 @@ -import { Theme } from '@logto/schemas'; -import classNames from 'classnames'; -import { useTranslation } from 'react-i18next'; - -import OrganizationFeatureDark from '@/assets/icons/organization-feature-dark.svg'; -import OrganizationFeature from '@/assets/icons/organization-feature.svg'; -import ActionBar from '@/components/ActionBar'; -import { isDevFeaturesEnabled } from '@/consts/env'; -import Button from '@/ds-components/Button'; -import Card from '@/ds-components/Card'; -import OverlayScrollbar from '@/ds-components/OverlayScrollbar'; -import useTenantPathname from '@/hooks/use-tenant-pathname'; -import useTheme from '@/hooks/use-theme'; - -import { steps, totalStepCount } from '../const'; -import * as parentStyles from '../index.module.scss'; - -import FlexBox from './components/FlexBox'; -import InteractiveDiagram from './components/InteractiveDiagram'; -import Panel from './components/Panel'; -import Permission from './components/Permission'; -import Role from './components/Role'; -import Section from './components/Section'; -import User from './components/User'; -import * as styles from './index.module.scss'; - -const icons = { - [Theme.Light]: { OrganizationIcon: OrganizationFeature }, - [Theme.Dark]: { OrganizationIcon: OrganizationFeatureDark }, -}; - -type Props = { - /* True if the guide is in the "Check guide" drawer of organization details page */ - readonly isReadonly?: boolean; -}; - -function Introduction({ isReadonly }: Props) { - const { t } = useTranslation(undefined, { keyPrefix: 'admin_console.organizations' }); - const { navigate } = useTenantPathname(); - const theme = useTheme(); - const { OrganizationIcon } = icons[theme]; - - return ( - <> - -
- - - -
{t('guide.introduction.title')}
- -
{t('guide.introduction.section_1.title')}
-
- - - {Array.from({ length: 5 }).map((_, index) => ( - // eslint-disable-next-line react/no-array-index-key - - ))} - - - -
-
- -
{t('guide.introduction.section_2.title')}
-
- {t('guide.introduction.section_2.description')} -
-
- - - - - - -
-
- - - - - - -
-
- {isDevFeaturesEnabled && ( - -
- {t('guide.introduction.section_3.title')} -
-
- {t('guide.introduction.section_3.description')} -
-
- )} - -
{t('guide.introduction.section_4.title')}
-
- {t('guide.introduction.section_4.description')} -
- -
-
-
-
-
- {!isReadonly && ( - -
- {isInitialSetup && !isDevFeaturesEnabled && ( - - - - )} - {!isInitialSetup && !isDevFeaturesEnabled && ( - <> - - - {t('organizations.title')} - - - {t('organizations.organization_template')} - - - {!tab && } - {tab === 'template' && } - - )} - {isDevFeaturesEnabled && isOrganizationsDisabled && ( + {isOrganizationsDisabled && ( )} - {isDevFeaturesEnabled && !isOrganizationsDisabled && ( - - )} + {!isOrganizationsDisabled && }
); } diff --git a/packages/experience/src/pages/Consent/OrganizationSelector/index.tsx b/packages/experience/src/pages/Consent/OrganizationSelector/index.tsx index b54f51953fd..e89ccd5d7be 100644 --- a/packages/experience/src/pages/Consent/OrganizationSelector/index.tsx +++ b/packages/experience/src/pages/Consent/OrganizationSelector/index.tsx @@ -4,7 +4,6 @@ import { useState, useRef } from 'react'; import { useTranslation } from 'react-i18next'; import ExpandableIcon from '@/assets/icons/expandable-icon.svg'; -import { isDevFeaturesEnabled } from '@/constants/env'; import ScopeGroup from '../ScopeGroup'; @@ -35,22 +34,11 @@ const OrganizationSelector = ({ return null; } - // Todo @xiaoyijun remove dev flag - const { missingResourceScopes: resourceScopes } = isDevFeaturesEnabled - ? selectedOrganization - : { - missingResourceScopes: [], - }; + const { missingResourceScopes: resourceScopes } = selectedOrganization; return (
-
- {t( - `description.${ - isDevFeaturesEnabled ? 'authorize_organization_access' : 'grant_organization_access' - }` - )} -
+
{t(`description.authorize_organization_access`)}
{resourceScopes && resourceScopes.length > 0 && (
{resourceScopes @@ -80,10 +68,7 @@ const OrganizationSelector = ({ ref={parentElementRef} className={classNames( styles.cardWrapper, - isDevFeaturesEnabled && // Todo @xiaoyijun remove dev feature flag - resourceScopes && - resourceScopes.length > 0 && - styles.withoutTopRadius + Boolean(resourceScopes?.length) && styles.withoutTopRadius )} data-active={showDropdown} > diff --git a/packages/experience/src/pages/Consent/ScopesListCard/index.tsx b/packages/experience/src/pages/Consent/ScopesListCard/index.tsx index 37929f119f6..8a562ea1026 100644 --- a/packages/experience/src/pages/Consent/ScopesListCard/index.tsx +++ b/packages/experience/src/pages/Consent/ScopesListCard/index.tsx @@ -1,10 +1,7 @@ -import { ReservedResource, UserScope } from '@logto/core-kit'; +import { UserScope } from '@logto/core-kit'; import { type ConsentInfoResponse } from '@logto/schemas'; import { useMemo } from 'react'; -import { Trans, useTranslation } from 'react-i18next'; - -import TermsLinks from '@/components/TermsLinks'; -import { isDevFeaturesEnabled } from '@/constants/env'; +import { useTranslation } from 'react-i18next'; import ScopeGroup from '../ScopeGroup'; @@ -18,18 +15,9 @@ type Props = { readonly resourceScopes: ConsentInfoResponse['missingResourceScopes']; readonly appName: string; readonly className?: string; - readonly termsUrl?: string; - readonly privacyUrl?: string; }; -const ScopesListCard = ({ - userScopes, - resourceScopes, - appName, - termsUrl, - privacyUrl, - className, -}: Props) => { +const ScopesListCard = ({ userScopes, resourceScopes, appName, className }: Props) => { const { t } = useTranslation(); const userScopesData = useMemo( @@ -45,34 +33,15 @@ const ScopesListCard = ({ [t, userScopes] ); - // Todo @xiaoyijun remove dev feature flag and authorization agreement from this component - const showTerms = !isDevFeaturesEnabled && Boolean(termsUrl ?? privacyUrl); - // If there is no user scopes and resource scopes, we don't need to show the scopes list. - // This is a fallback for the corner case that all the scopes are already granted. if (!userScopesData?.length && !resourceScopes?.length) { - return showTerms ? ( -
- , - }} - > - {t('description.authorize_agreement', { name: appName })} - -
- ) : null; + return null; } return (
- {t( - `description.${ - isDevFeaturesEnabled ? 'authorize_personal_data_usage' : 'request_permission' - }`, - { name: appName } - )} + {t(`description.authorize_personal_data_usage`, { name: appName })}
{userScopesData && userScopesData.length > 0 && ( @@ -86,31 +55,12 @@ const ScopesListCard = ({ {resourceScopes?.map(({ resource, scopes }) => ( ))} - {!isDevFeaturesEnabled && // Todo @xiaoyijun remove dev feature flag - showTerms && ( -
- - ), - }} - > - {t('description.authorize_agreement', { name: appName })} - -
- )}
); diff --git a/packages/experience/src/pages/Consent/index.tsx b/packages/experience/src/pages/Consent/index.tsx index 98028d0f814..e09bd73b9a8 100644 --- a/packages/experience/src/pages/Consent/index.tsx +++ b/packages/experience/src/pages/Consent/index.tsx @@ -8,7 +8,6 @@ import { consent, getConsentInfo } from '@/apis/consent'; import Button from '@/components/Button'; import TermsLinks from '@/components/TermsLinks'; import TextLink from '@/components/TextLink'; -import { isDevFeaturesEnabled } from '@/constants/env'; import useApi from '@/hooks/use-api'; import useErrorHandler from '@/hooks/use-error-handler'; @@ -89,15 +88,12 @@ const Consent = () => { userScopes={consentData.missingOIDCScope} /** * The org resources is included in the user scopes for compatibility. - * Todo @xiaoyijun remove dev feature flag. */ resourceScopes={consentData.missingResourceScopes?.filter( - ({ resource }) => !isDevFeaturesEnabled || resource.id !== ReservedResource.Organization + ({ resource }) => resource.id !== ReservedResource.Organization )} appName={applicationName} className={styles.scopesCard} - termsUrl={consentData.application.termsOfUseUrl ?? undefined} - privacyUrl={consentData.application.privacyPolicyUrl ?? undefined} /> {consentData.organizations && ( { />
- {(!isDevFeaturesEnabled || !showTerms) && ( + {!showTerms && (
{t('description.redirect_to', { name: getRedirectUriOrigin(consentData.redirectUri) })}
)} - {isDevFeaturesEnabled && showTerms && ( + {showTerms && (
{
)} -
{t('description.not_you')}{' '} diff --git a/packages/phrases/src/locales/de/translation/admin-console/organizations.ts b/packages/phrases/src/locales/de/translation/admin-console/organizations.ts index d4977c8e988..f3e5427f0c9 100644 --- a/packages/phrases/src/locales/de/translation/admin-console/organizations.ts +++ b/packages/phrases/src/locales/de/translation/admin-console/organizations.ts @@ -18,23 +18,13 @@ const organizations = { organization_description_placeholder: 'Eine kurze Beschreibung der Organisation', organization_permission: 'Organisationsberechtigung', organization_permission_other: 'Organisationsberechtigungen', - organization_permission_description: - 'Eine Organisationsberechtigung bezieht sich auf die Autorisierung zum Zugriff auf eine Ressource im Kontext der Organisation. Eine Organisationsberechtigung sollte als aussagekräftiger String repräsentiert werden, der auch als Name und eindeutiger Bezeichner dient.', - organization_permission_delete_confirm: - 'Wenn diese Berechtigung gelöscht wird, verlieren alle Organisationsrollen, einschließlich dieser Berechtigung, diese Berechtigung. Benutzer, die diese Berechtigung hatten, verlieren den Zugriff, der durch sie gewährt wurde.', create_permission_placeholder: 'Terminkalenderverlauf lesen', - permission: 'Berechtigung', - permission_other: 'Berechtigungen', organization_role: 'Organisationsrolle', organization_role_other: 'Organisationsrollen', organization_role_description: 'Eine Organisationsrolle ist eine Gruppierung von Berechtigungen, die Benutzern zugewiesen werden können. Die Berechtigungen müssen aus den vordefinierten Organisationsberechtigungen stammen.', - organization_role_delete_confirm: - 'Dadurch werden die mit dieser Rolle verbundenen Berechtigungen von den betroffenen Benutzern entfernt und die Beziehungen zwischen Organisationsrollen, Mitgliedern in der Organisation und Organisationsberechtigungen gelöscht.', role: 'Rolle', - create_role_placeholder: 'Benutzer mit nur Lesezugriff', search_placeholder: 'Nach Organisation suchen', - search_permission_placeholder: 'Geben Sie zum Suchen und Auswählen von Berechtigungen ein', search_role_placeholder: 'Geben Sie zum Suchen und Auswählen von Rollen ein', empty_placeholder: '🤔 Sie haben noch keine {{entity}} eingerichtet.', organization_and_member: 'Organisation und Mitglied', @@ -70,21 +60,8 @@ const organizations = { 'Nehmen wir ein Beispiel. John, Sarah sind in verschiedenen Organisationen mit unterschiedlichen Rollen im Kontext verschiedener Organisationen. Fahren Sie mit der Maus über die verschiedenen Module und sehen Sie, was passiert.', }, }, - step_1: 'Schritt 1: Organisationsberechtigungen definieren', - step_2: 'Schritt 2: Organisationsrollen definieren', - step_3: 'Schritt 3: Erstellen Sie Ihre erste Organisation', - step_3_description: - 'Erstellen Sie Ihre erste Organisation. Sie erhält eine eindeutige ID und dient als Container für die Bearbeitung verschiedener geschäftsbezogener Identitäten.', - more_next_steps: 'Weitere Schritte', - add_members: 'Fügen Sie Mitglieder zu Ihrer Organisation hinzu', - /** UNTRANSLATED */ - config_organization: 'Configure organization', organization_permissions: 'Organisationsberechtigungen', - permission_name: 'Berechtigungsname', - permissions: 'Berechtigungen', organization_roles: 'Organisationsrollen', - role_name: 'Rollenname', - organization_name: 'Organisationsname', admin: 'Admin', member: 'Mitglied', guest: 'Gast', diff --git a/packages/phrases/src/locales/en/translation/admin-console/organizations.ts b/packages/phrases/src/locales/en/translation/admin-console/organizations.ts index 7baa1f115e8..47d9cd035b2 100644 --- a/packages/phrases/src/locales/en/translation/admin-console/organizations.ts +++ b/packages/phrases/src/locales/en/translation/admin-console/organizations.ts @@ -16,23 +16,13 @@ const organizations = { organization_description_placeholder: 'A brief description of the organization', organization_permission: 'Organization permission', organization_permission_other: 'Organization permissions', - organization_permission_description: - 'Organization permission refers to the authorization to access a resource in the context of organization. An organization permission should be represented as a meaningful string, also serving as the name and unique identifier.', - organization_permission_delete_confirm: - 'If this permission is deleted, all organization roles including this permission will lose this permission, and users who had this permission will lose the access granted by it.', create_permission_placeholder: 'Read appointment history', - permission: 'Permission', - permission_other: 'Permissions', organization_role: 'Organization role', organization_role_other: 'Organization roles', organization_role_description: 'Organization role is a grouping of permissions that can be assigned to users. The permissions must come from the predefined organization permissions.', - organization_role_delete_confirm: - 'Doing so will remove the permissions associated with this role from the affected users and delete the relations among organization roles, members in the organization, and organization permissions.', role: 'Role', - create_role_placeholder: 'Users with view-only permissions', search_placeholder: 'Search by organization name or ID', - search_permission_placeholder: 'Type to search and select permissions', search_role_placeholder: 'Type to search and select roles', empty_placeholder: '🤔 You don’t have any {{entity}} set up yet.', organization_and_member: 'Organization and member', @@ -68,20 +58,8 @@ const organizations = { "Let's take an example. John, Sarah are in different organizations with different roles in the context of different organizations. Hover over the different modules and see what happens.", }, }, - step_1: 'Step 1: Define organization permissions', - step_2: 'Step 2: Define organization roles', - step_3: 'Step 3: Create your first organization', - step_3_description: - "Let's create your first organization. It comes with a unique ID and serves as a container for handling various more business-toward identities.", - more_next_steps: 'More next steps', - add_members: 'Add members to your organization', - config_organization: 'Configure organization', organization_permissions: 'Organization permissions', - permission_name: 'Permission name', - permissions: 'Permissions', organization_roles: 'Organization roles', - role_name: 'Role name', - organization_name: 'Organization name', admin: 'Admin', member: 'Member', guest: 'Guest', diff --git a/packages/phrases/src/locales/es/translation/admin-console/organizations.ts b/packages/phrases/src/locales/es/translation/admin-console/organizations.ts index 6c65e5339cb..b00b556f6de 100644 --- a/packages/phrases/src/locales/es/translation/admin-console/organizations.ts +++ b/packages/phrases/src/locales/es/translation/admin-console/organizations.ts @@ -18,23 +18,13 @@ const organizations = { organization_description_placeholder: 'Una breve descripción de la organización', organization_permission: 'Permiso de la organización', organization_permission_other: 'Permisos de la organización', - organization_permission_description: - 'El permiso de la organización se refiere a la autorización para acceder a un recurso en el contexto de la organización. Un permiso de organización debe representarse como una cadena significativa, que también sirve como el nombre y el identificador único.', - organization_permission_delete_confirm: - 'Si se elimina este permiso, todos los roles de la organización, incluido este permiso, perderán este permiso, y los usuarios que tenían este permiso perderán el acceso otorgado por él.', create_permission_placeholder: 'Leer historial de citas', - permission: 'Permiso', - permission_other: 'Permisos', organization_role: 'Rol de la organización', organization_role_other: 'Roles de la organización', organization_role_description: 'El rol de la organización es un agrupamiento de permisos que se pueden asignar a los usuarios. Los permisos deben provenir de los permisos de organización predefinidos.', - organization_role_delete_confirm: - 'Hacer esto eliminará los permisos asociados con este rol de los usuarios afectados y eliminará las relaciones entre roles de organización, miembros de la organización y permisos de organización.', role: 'Rol', - create_role_placeholder: 'Usuarios con permisos de solo lectura', search_placeholder: 'Buscar por nombre de organización o ID', - search_permission_placeholder: 'Escribe para buscar y seleccionar permisos', search_role_placeholder: 'Escribe para buscar y seleccionar roles', empty_placeholder: '🤔 No has configurado ningún {{entity}} todavía.', organization_and_member: 'Organización y miembro', @@ -71,21 +61,8 @@ const organizations = { 'Tomemos un ejemplo. John y Sarah están en diferentes organizaciones con diferentes roles en el contexto de diferentes organizaciones. Desplácese sobre los diferentes módulos y vea qué sucede.', }, }, - step_1: 'Paso 1: Definir permisos de organización', - step_2: 'Paso 2: Definir roles de organización', - step_3: 'Paso 3: Cree su primera organización', - step_3_description: - 'Creemos su primera organización. Viene con un ID único y sirve como contenedor para manejar varias identidades dirigidas hacia empresas.', - more_next_steps: 'Más pasos siguientes', - add_members: 'Agregar miembros a su organización', - /** UNTRANSLATED */ - config_organization: 'Configure organization', organization_permissions: 'Permisos de la organización', - permission_name: 'Nombre del permiso', - permissions: 'Permisos', organization_roles: 'Roles de la organización', - role_name: 'Nombre del rol', - organization_name: 'Nombre de la organización', admin: 'Admin', member: 'Miembro', guest: 'Invitado', diff --git a/packages/phrases/src/locales/fr/translation/admin-console/organizations.ts b/packages/phrases/src/locales/fr/translation/admin-console/organizations.ts index 88464d9d852..a84e83d03ae 100644 --- a/packages/phrases/src/locales/fr/translation/admin-console/organizations.ts +++ b/packages/phrases/src/locales/fr/translation/admin-console/organizations.ts @@ -18,23 +18,13 @@ const organizations = { organization_description_placeholder: "Une brève description de l'organisation", organization_permission: "Autorisation de l'organisation", organization_permission_other: "Autorisations de l'organisation", - organization_permission_description: - "L'autorisation d'organisation se réfère à l'autorisation d'accéder à une ressource dans le contexte de l'organisation. Une autorisation d'organisation doit être représentée par une chaîne significative, servant également de nom et d'identifiant unique.", - organization_permission_delete_confirm: - "Si cette autorisation est supprimée, tous les rôles d'organisation incluant cette autorisation perdront cette autorisation, et les utilisateurs ayant cette autorisation perdront l'accès qui en découle.", create_permission_placeholder: "Lire l'historique des rendez-vous", - permission: 'Autorisation', - permission_other: 'Autorisations', organization_role: "Rôle de l'organisation", organization_role_other: "Rôles de l'organisation", organization_role_description: "Le rôle d'organisation est un regroupement d'autorisations pouvant être attribuées aux utilisateurs. Les autorisations doivent provenir des autorisations d'organisation prédéfinies.", - organization_role_delete_confirm: - "Si cette autorisation est supprimée, tous les rôles d'organisation incluant cette autorisation perdront cette autorisation, et les utilisateurs ayant cette autorisation perdront l'accès qui en découle.", role: 'Rôle', - create_role_placeholder: 'Utilisateurs avec des autorisations en lecture seule', search_placeholder: "Rechercher par nom ou ID de l'organisation", - search_permission_placeholder: 'Tapez pour rechercher et sélectionner des autorisations', search_role_placeholder: 'Tapez pour rechercher et sélectionner des rôles', empty_placeholder: "🤔 Vous n'avez pas encore configuré {{entity}}.", organization_and_member: 'Organisation et membre', @@ -71,21 +61,8 @@ const organizations = { 'Prenons un exemple : John, Sarah appartiennent à différentes organisations avec des rôles différents dans le contexte de différentes organisations. Passez la souris sur les différents modules et voyez ce qui se passe.', }, }, - step_1: "Étape 1 : Définir les autorisations d'organisation", - step_2: "Étape 2 : Définir les rôles d'organisation", - step_3: 'Étape 3 : Créer votre première organisation', - step_3_description: - 'Créez votre première organisation. Elle possède un identifiant unique et sert de conteneur pour gérer diverses identités orientées vers les entreprises.', - more_next_steps: 'Autres étapes suivantes', - add_members: 'Ajouter des membres à votre organisation', - /** UNTRANSLATED */ - config_organization: 'Configure organization', organization_permissions: "Autorisations de l'organisation", - permission_name: "Nom de l'autorisation", - permissions: 'Autorisations', organization_roles: "Rôles de l'organisation", - role_name: 'Nom du rôle', - organization_name: "Nom de l'organisation", admin: 'Admin', member: 'Membre', guest: 'Invité', diff --git a/packages/phrases/src/locales/it/translation/admin-console/organizations.ts b/packages/phrases/src/locales/it/translation/admin-console/organizations.ts index 3e7656ff33d..34c82282132 100644 --- a/packages/phrases/src/locales/it/translation/admin-console/organizations.ts +++ b/packages/phrases/src/locales/it/translation/admin-console/organizations.ts @@ -18,23 +18,13 @@ const organizations = { organization_description_placeholder: "Una breve descrizione dell'organizzazione", organization_permission: 'Permessi organizzazione', organization_permission_other: 'Permessi organizzazione', - organization_permission_description: - "Il permesso organizzativo si riferisce all'autorizzazione per accedere a una risorsa nel contesto dell'organizzazione. Un permesso organizzativo dovrebbe essere rappresentato come una stringa significativa, servendo anche come nome e identificatore univoco.", - organization_permission_delete_confirm: - "Se questo permesso viene eliminato, tutti i ruoli dell'organizzazione che includono questo permesso perderanno tale permesso, e gli utenti che avevano questo permesso perderanno l'accesso garantito da esso.", create_permission_placeholder: 'Leggi la cronologia degli appuntamenti', - permission: 'Permesso', - permission_other: 'Permessi', organization_role: 'Ruolo organizzazione', organization_role_other: 'Ruoli organizzazione', organization_role_description: 'Il ruolo organizzativo è un raggruppamento di permessi che possono essere assegnati agli utenti. I permessi devono provenire dai permessi organizzativi predefiniti.', - organization_role_delete_confirm: - "Fare ciò rimuoverà i permessi associati a questo ruolo dagli utenti interessati ed eliminerà le relazioni tra i ruoli dell'organizzazione, i membri dell'organizzazione e i permessi dell'organizzazione.", role: 'Ruolo', - create_role_placeholder: 'Utenti con solo permessi di visualizzazione', search_placeholder: "Cerca per nome o ID dell'organizzazione", - search_permission_placeholder: 'Digita per cercare e selezionare i permessi', search_role_placeholder: 'Digita per cercare e selezionare i ruoli', empty_placeholder: '🤔 Non hai ancora impostato nessun {{entity}}.', organization_and_member: 'Organizzazione e membri', @@ -71,21 +61,8 @@ const organizations = { 'Prendiamo un esempio. John, Sarah sono in diverse organizzazioni con ruoli diversi nel contesto di organizzazioni diverse. Passa il mouse sui diversi moduli e guarda cosa succede.', }, }, - step_1: "Passo 1: Definire i permessi dell'organizzazione", - step_2: "Passo 2: Definire i ruoli dell'organizzazione", - step_3: 'Passo 3: Crea la tua prima organizzazione', - step_3_description: - 'Creiamo la tua prima organizzazione. Ha un ID univoco e serve come contenitore per gestire varie entità più orientate al business.', - more_next_steps: 'Altri passaggi successivi', - add_members: 'Aggiungi membri alla tua organizzazione', - /** UNTRANSLATED */ - config_organization: 'Configure organization', organization_permissions: 'Permessi organizzazione', - permission_name: 'Nome del permesso', - permissions: 'Permessi', organization_roles: 'Ruoli organizzazione', - role_name: 'Nome del ruolo', - organization_name: "Nome dell'organizzazione", admin: 'Amministratore', member: 'Membro', guest: 'Ospite', diff --git a/packages/phrases/src/locales/ja/translation/admin-console/organizations.ts b/packages/phrases/src/locales/ja/translation/admin-console/organizations.ts index 038473d2cc3..cca20d6b267 100644 --- a/packages/phrases/src/locales/ja/translation/admin-console/organizations.ts +++ b/packages/phrases/src/locales/ja/translation/admin-console/organizations.ts @@ -18,23 +18,13 @@ const organizations = { organization_description_placeholder: '組織の簡単な説明', organization_permission: '組織権限', organization_permission_other: '組織権限', - organization_permission_description: - '組織権限とは、組織のコンテキストでリソースにアクセスするための承認を指します。組織権限は、意味のある文字列として表され、また名前および一意の識別子としても機能します。', - organization_permission_delete_confirm: - 'この権限を削除すると、この権限を含むすべての組織ロールがこの権限を失い、この権限を持っていたユーザーはそのアクセスを失います。', create_permission_placeholder: '任命履歴を読む', - permission: '権限', - permission_other: '権限', organization_role: '組織役割', organization_role_other: '組織役割', organization_role_description: '組織役割は、ユーザーに割り当てることができる権限のグループ化です。権限は事前に定義された組織権限から取得する必要があります。', - organization_role_delete_confirm: - 'これを行うと、影響を受けるユーザーからこの役割に関連する権限が削除され、組織ロール、組織のメンバー、および組織権限の関係が削除されます。', role: '役割', - create_role_placeholder: '閲覧のみの権限を持つユーザー', search_placeholder: '組織名またはIDで検索', - search_permission_placeholder: '検索して権限を選択', search_role_placeholder: '検索して役割を選択', empty_placeholder: '🤔 You don’t have any {{entity}} set up yet.', organization_and_member: '組織とメンバー', @@ -70,21 +60,8 @@ const organizations = { '例として、John、Sarahは異なる組織に所属し、それぞれ異なる組織のコンテキストで異なる役割を担っています。異なるモジュールにカーソルを合わせて、それぞれの動作を確認しましょう。', }, }, - step_1: 'ステップ1:組織権限を定義する', - step_2: 'ステップ2:組織役割を定義する', - step_3: 'ステップ3:最初の組織を作成する', - step_3_description: - '最初の組織を作成しましょう。これにはユニークなIDが付いており、さまざまなビジネスに関連するエンティティを取り扱うコンテナとなります。', - more_next_steps: 'その他の次のステップ', - add_members: '組織にメンバーを追加', - /** UNTRANSLATED */ - config_organization: 'Configure organization', organization_permissions: '組織権限', - permission_name: '権限名', - permissions: '権限', organization_roles: '組織役割', - role_name: '役割名', - organization_name: '組織名', admin: '管理者', member: 'メンバー', guest: 'ゲスト', diff --git a/packages/phrases/src/locales/ko/translation/admin-console/organizations.ts b/packages/phrases/src/locales/ko/translation/admin-console/organizations.ts index f5ebf9a2030..d830632dc40 100644 --- a/packages/phrases/src/locales/ko/translation/admin-console/organizations.ts +++ b/packages/phrases/src/locales/ko/translation/admin-console/organizations.ts @@ -18,23 +18,13 @@ const organizations = { organization_description_placeholder: '조직에 대한 간략한 설명', organization_permission: '조직 권한', organization_permission_other: '조직 권한', - organization_permission_description: - '조직 권한은 조직 컨텍스트에서 리소스에 액세스하기 위한 권한을 나타냅니다. 조직 권한은 의미 있는 문자열로 표현되어야 하며 이름 및 고유 식별자로도 작동해야 합니다.', - organization_permission_delete_confirm: - '이 권한이 삭제되면 이 권한을 포함하는 모든 조직 역할은 이 권한을 상실하고 이 권한이 부여한 액세스도 상실합니다.', create_permission_placeholder: '약속 내역 읽기', - permission: '권한', - permission_other: '권한', organization_role: '조직 역할', organization_role_other: '조직 역할', organization_role_description: '조직 역할은 사용자에 할당할 수 있는 권한의 그룹화입니다. 권한은 미리 정의된 조직 권한에서 가져와야 합니다.', - organization_role_delete_confirm: - '이렇게 하면 영향을 받는 사용자에서 이 역할과 관련된 권한이 제거되고 조직 역할, 조직 구성원 및 조직 권한 간의 관계가 삭제됩니다.', role: '역할', - create_role_placeholder: '보기 전용 권한을 가진 사용자', search_placeholder: '조직 이름 또는 ID로 검색', - search_permission_placeholder: '검색하여 권한 선택', search_role_placeholder: '검색하여 역할 선택', empty_placeholder: '🤔 You don’t have any {{entity}} set up yet.', organization_and_member: '조직 및 구성원', @@ -69,21 +59,8 @@ const organizations = { '예를 들어 존과 사라가 서로 다른 조직에서 서로 다른 역할을 가진 채로 있습니다. 각 모듈 위로 마우스를 올려보세요.', }, }, - step_1: '단계 1: 조직 권한 정의', - step_2: '단계 2: 조직 역할 정의', - step_3: '단계 3: 첫 번째 조직 생성하기', - step_3_description: - '첫 번째 조직을 만들어보세요. 고유 ID가 포함되어 다양한 비즈니스 관련 식별자를 처리하는 컨테이너 역할을 합니다.', - more_next_steps: '추가 다음 단계', - add_members: '조직에 구성원 추가', - /** UNTRANSLATED */ - config_organization: 'Configure organization', organization_permissions: '조직 권한', - permission_name: '권한 이름', - permissions: '권한', organization_roles: '조직 역할', - role_name: '역할 이름', - organization_name: '조직 이름', admin: '관리자', member: '구성원', guest: '손님', diff --git a/packages/phrases/src/locales/pl-pl/translation/admin-console/organizations.ts b/packages/phrases/src/locales/pl-pl/translation/admin-console/organizations.ts index 5062ed2f316..36b0d4ffab9 100644 --- a/packages/phrases/src/locales/pl-pl/translation/admin-console/organizations.ts +++ b/packages/phrases/src/locales/pl-pl/translation/admin-console/organizations.ts @@ -18,23 +18,13 @@ const organizations = { organization_description_placeholder: 'Krótki opis organizacji', organization_permission: 'Uprawnienie organizacji', organization_permission_other: 'Uprawnienia organizacji', - organization_permission_description: - 'Uprawnienie organizacji odnosi się do autoryzacji dostępu do zasobu w kontekście organizacji. Uprawnienie organizacji powinno być reprezentowane jako znaczący ciąg znaków, stanowiący także nazwę i unikalny identyfikator.', - organization_permission_delete_confirm: - 'Jeśli to uprawnienie zostanie usunięte, wszystkie role organizacji, w tym to uprawnienie, stracą to uprawnienie, a użytkownicy, którzy mieli to uprawnienie, stracą dostęp do niego.', create_permission_placeholder: 'Odczyt historii spotkań', - permission: 'Uprawnienie', - permission_other: 'Uprawnienia', organization_role: 'Rola organizacji', organization_role_other: 'Role organizacji', organization_role_description: 'Rola organizacji to grupowanie uprawnień, które można przypisać użytkownikom. Uprawnienia muszą pochodzić z wcześniej zdefiniowanych uprawnień organizacji.', - organization_role_delete_confirm: - 'Spowoduje to usunięcie uprawnień związanych z tą rolą od dotkniętych użytkowników oraz usunięcie relacji między rolami organizacji, członkami organizacji i uprawnieniami organizacji.', role: 'Rola', - create_role_placeholder: 'Użytkownicy z uprawnieniami tylko do odczytu', search_placeholder: 'Wyszukaj według nazwy lub ID organizacji', - search_permission_placeholder: 'Wpisz, aby wyszukać i wybrać uprawnienia', search_role_placeholder: 'Wpisz, aby wyszukać i wybrać role', empty_placeholder: '🤔 Nie masz jeszcze ustawionego żadnego {{entity}}.', organization_and_member: 'Organizacja i członek', @@ -71,21 +61,8 @@ const organizations = { 'Przyjmijmy przykład. John, Sarah należą do różnych organizacji z różnymi rolami w kontekście różnych organizacji. Najedź kursorem na różne moduły i zobacz co się stanie.', }, }, - step_1: 'Krok 1: Zdefiniuj uprawnienia organizacji', - step_2: 'Krok 2: Zdefiniuj role organizacji', - step_3: 'Krok 3: Utwórz swoją pierwszą organizację', - step_3_description: - 'Utwórz swoją pierwszą organizację. Posiada ona unikalny identyfikator i służy jako kontener do obsługi różnych identyfikacji skierowanych na biznes.', - more_next_steps: 'Więcej następnych kroków', - add_members: 'Dodaj członków do swojej organizacji', - /** UNTRANSLATED */ - config_organization: 'Configure organization', organization_permissions: 'Uprawnienia organizacji', - permission_name: 'Nazwa uprawnienia', - permissions: 'Uprawnienia', organization_roles: 'Role organizacji', - role_name: 'Nazwa roli', - organization_name: 'Nazwa organizacji', admin: 'Administrator', member: 'Członek', guest: 'Gość', diff --git a/packages/phrases/src/locales/pt-br/translation/admin-console/organizations.ts b/packages/phrases/src/locales/pt-br/translation/admin-console/organizations.ts index 248f7b314d8..41d43ea5e7f 100644 --- a/packages/phrases/src/locales/pt-br/translation/admin-console/organizations.ts +++ b/packages/phrases/src/locales/pt-br/translation/admin-console/organizations.ts @@ -18,23 +18,13 @@ const organizations = { organization_description_placeholder: 'Uma breve descrição da organização', organization_permission: 'Permissão da organização', organization_permission_other: 'Permissões da organização', - organization_permission_description: - 'A permissão da organização se refere à autorização para acessar um recurso no contexto da organização. Uma permissão de organização deve ser representada como uma string significativa, servindo também como nome e identificador exclusivo.', - organization_permission_delete_confirm: - 'Se esta permissão for excluída, todos os papéis de organização, incluindo esta permissão, perderão esta permissão, e os usuários que tinham esta permissão perderão o acesso concedido por ela.', create_permission_placeholder: 'Ler histórico de compromissos', - permission: 'Permissão', - permission_other: 'Permissões', organization_role: 'Papel da organização', organization_role_other: 'Papéis da organização', organization_role_description: 'O papel da organização é um agrupamento de permissões que podem ser atribuídas aos usuários. As permissões devem vir das permissões de organização predefinidas.', - organization_role_delete_confirm: - 'Fazê-lo removerá as permissões associadas a este papel dos usuários afetados e excluirá as relações entre os papéis da organização, os membros da organização e as permissões da organização.', role: 'Função', - create_role_placeholder: 'Usuários com permissões somente leitura', search_placeholder: 'Pesquisar por nome ou ID da organização', - search_permission_placeholder: 'Digite para pesquisar e selecionar permissões', search_role_placeholder: 'Digite para pesquisar e selecionar funções', empty_placeholder: '🤔 Você ainda não configurou nenhum {{entity}}.', organization_and_member: 'Organização e membro', @@ -71,21 +61,8 @@ const organizations = { 'Vamos dar um exemplo. John, Sarah estão em diferentes organizações com diferentes papéis no contexto de organizações diferentes. Passe o mouse sobre os diferentes módulos e veja o que acontece.', }, }, - step_1: 'Etapa 1: Definir permissões da organização', - step_2: 'Etapa 2: Definir papéis da organização', - step_3: 'Etapa 3: Criar sua primeira organização', - step_3_description: - 'Vamos criar a sua primeira organização. Ela vem com um ID único e serve como um contêiner para lidar com várias identidades direcionadas aos negócios.', - more_next_steps: 'Próximas etapas', - add_members: 'Adicionar membros à sua organização', - /** UNTRANSLATED */ - config_organization: 'Configure organization', organization_permissions: 'Permissões da organização', - permission_name: 'Nome da permissão', - permissions: 'Permissões', organization_roles: 'Papéis da organização', - role_name: 'Nome do papel', - organization_name: 'Nome da organização', admin: 'Administrador', member: 'Membro', guest: 'Convidado', diff --git a/packages/phrases/src/locales/pt-pt/translation/admin-console/organizations.ts b/packages/phrases/src/locales/pt-pt/translation/admin-console/organizations.ts index 18d1ab6b009..4bb54723c34 100644 --- a/packages/phrases/src/locales/pt-pt/translation/admin-console/organizations.ts +++ b/packages/phrases/src/locales/pt-pt/translation/admin-console/organizations.ts @@ -18,23 +18,13 @@ const organizations = { organization_description_placeholder: 'Uma breve descrição da organização', organization_permission: 'Permissão da organização', organization_permission_other: 'Permissões da organização', - organization_permission_description: - 'A permissão da organização refere-se à autorização para aceder a um recurso no contexto da organização. Uma permissão da organização deve ser representada como uma string significativa, servindo também como nome e identificador único.', - organization_permission_delete_confirm: - 'Se esta permissão for eliminada, todas as funções da organização que incluam esta permissão perderão esta permissão, e os utilizadores que tinham esta permissão perderão o acesso concedido por ela.', create_permission_placeholder: 'Ler histórico de compromissos', - permission: 'Permissão', - permission_other: 'Permissões', organization_role: 'Papel da organização', organization_role_other: 'Funções da organização', organization_role_description: 'O papel da organização é um agrupamento de permissões que podem ser atribuídas a utilizadores. As permissões devem provir das permissões de organização predefinidas.', - organization_role_delete_confirm: - 'Fazê-lo removerá as permissões associadas a este papel dos usuários afetados e excluirá as relações entre os papéis da organização, os membros da organização e as permissões da organização.', role: 'Função', - create_role_placeholder: 'Usuários com permissões somente leitura', search_placeholder: 'Pesquisar por nome ou ID da organização', - search_permission_placeholder: 'Digite para pesquisar e selecionar permissões', search_role_placeholder: 'Digite para pesquisar e selecionar funções', empty_placeholder: '🤔 Você ainda não configurou nenhum {{entity}}.', organization_and_member: 'Organização e membro', @@ -71,21 +61,8 @@ const organizations = { 'Vamos ver um exemplo. John, Sarah pertencem a diferentes organizações com funções diferentes no contexto das organizações diferentes. Passe o rato sobre os diferentes módulos e veja o que acontece.', }, }, - step_1: 'Passo 1: Definir as permissões da organização', - step_2: 'Passo 2: Definir as funções da organização', - step_3: 'Passo 3: Crie a sua primeira organização', - step_3_description: - 'Vamos criar a sua primeira organização. Ela possui um ID único e serve como contentor para lidar com várias entidades empresariais adicionais.', - more_next_steps: 'Mais passos seguintes', - add_members: 'Adicionar membros à sua organização', - /** UNTRANSLATED */ - config_organization: 'Configure organization', organization_permissions: 'Permissões da organização', - permission_name: 'Nome da permissão', - permissions: 'Permissões', organization_roles: 'Funções da organização', - role_name: 'Nome da função', - organization_name: 'Nome da organização', admin: 'Administrador', member: 'Membro', guest: 'Convidado', diff --git a/packages/phrases/src/locales/ru/translation/admin-console/organizations.ts b/packages/phrases/src/locales/ru/translation/admin-console/organizations.ts index 427440160b7..0d17b65cb4d 100644 --- a/packages/phrases/src/locales/ru/translation/admin-console/organizations.ts +++ b/packages/phrases/src/locales/ru/translation/admin-console/organizations.ts @@ -18,23 +18,13 @@ const organizations = { organization_description_placeholder: 'Краткое описание организации', organization_permission: 'Разрешение организации', organization_permission_other: 'Разрешения организации', - organization_permission_description: - 'Разрешение организации относится к разрешению доступа к ресурсу в контексте организации. Разрешение организации должно быть представлено в виде осмысленной строки и также служить именем и уникальным идентификатором.', - organization_permission_delete_confirm: - 'Если это разрешение будет удалено, все роли организации, включая это разрешение, потеряют это разрешение, и пользователи, у которых было это разрешение, потеряют предоставленный им доступ к нему.', create_permission_placeholder: 'Чтение истории назначений', - permission: 'Разрешение', - permission_other: 'Разрешения', organization_role: 'Роль организации', organization_role_other: 'Роли организации', organization_role_description: 'Роль организации - это группировка разрешений, которые могут быть назначены пользователям. Разрешения должны быть взяты из предопределенных разрешений организации.', - organization_role_delete_confirm: - 'При этом будут удалены разрешения, связанные с этой ролью, у затронутых пользователей, и будут удалены отношения между ролями организации, участниками в организации и разрешениями организации.', role: 'Роль', - create_role_placeholder: 'Пользователи с правами только для просмотра', search_placeholder: 'Поиск по названию организации или ID', - search_permission_placeholder: 'Начните вводить для поиска и выбора разрешений', search_role_placeholder: 'Начните вводить для поиска и выбора ролей', empty_placeholder: '🤔 У вас пока нет никаких {{entity}}.', organization_and_member: 'Организация и участник', @@ -70,21 +60,8 @@ const organizations = { 'Давайте рассмотрим пример. Джон и Сара находятся в разных организациях с разными ролями в контексте разных организаций. Наведите указатель на различные модули и посмотрите, что происходит.', }, }, - step_1: 'Шаг 1: Определите разрешения организаций', - step_2: 'Шаг 2: Определите роли организаций', - step_3: 'Шаг 3: Создайте свою первую организацию', - step_3_description: - 'Давайте создадим вашу первую организацию. Она имеет уникальный идентификатор и служит контейнером для обработки различных бизнес-ориентированных идентификаторов.', - more_next_steps: 'Дополнительные следующие шаги', - add_members: 'Добавьте участников в вашу организацию', - /** UNTRANSLATED */ - config_organization: 'Configure organization', organization_permissions: 'Разрешения организации', - permission_name: 'Название разрешения', - permissions: 'Разрешения', organization_roles: 'Роли организации', - role_name: 'Название роли', - organization_name: 'Название организации', admin: 'Администратор', member: 'Участник', guest: 'Гость', diff --git a/packages/phrases/src/locales/tr-tr/translation/admin-console/organizations.ts b/packages/phrases/src/locales/tr-tr/translation/admin-console/organizations.ts index e58ccb25eb8..92ebb01ee06 100644 --- a/packages/phrases/src/locales/tr-tr/translation/admin-console/organizations.ts +++ b/packages/phrases/src/locales/tr-tr/translation/admin-console/organizations.ts @@ -18,23 +18,13 @@ const organizations = { organization_description_placeholder: 'Kuruluşun kısa açıklaması', organization_permission: 'Kuruluş izni', organization_permission_other: 'Kuruluş izinleri', - organization_permission_description: - 'Kuruluş izni, kuruluş bağlamında bir kaynağa erişim izni anlamına gelir. Bir kuruluş izni anlamlı bir dize olarak temsil edilmeli ve aynı zamanda adı ve benzersiz tanımlayıcısı olarak hizmet etmelidir.', - organization_permission_delete_confirm: - 'Bu izin silinirse, bu izni içeren tüm kuruluş rolleri bu izni kaybedecek ve bu izne sahip olan kullanıcılar bu izinle sağlanan erişimi kaybedecek.', create_permission_placeholder: 'Randevu geçmişini oku', - permission: 'İzin', - permission_other: 'İzinler', organization_role: 'Kuruluş rolü', organization_role_other: 'Kuruluş rolleri', organization_role_description: 'Kuruluş rolü, kullanıcılara atanabilen izinlerin bir gruplamasıdır. İzinler önceden tanımlanmış kuruluş izinlerinden gelmelidir.', - organization_role_delete_confirm: - 'Bunu yapmak, etkilenen kullanıcılardan bu role ilişkilendirilmiş izinleri kaldıracak ve kuruluş rolleri arasındaki ilişkileri ve kuruluş izinleri arasındaki ilişkileri silecektir.', role: 'Rol', - create_role_placeholder: 'Yalnızca görünüm izinleri olan kullanıcılar', search_placeholder: 'Kuruluş adı veya kimliğine göre ara', - search_permission_placeholder: 'İzinleri arayın ve seçin', search_role_placeholder: 'Rolleri arayın ve seçin', empty_placeholder: '\uD83E\uDD14 Herhangi bir {{entity}} henüz ayarlanmamış.', organization_and_member: 'Kuruluş ve üye', @@ -70,21 +60,8 @@ const organizations = { 'Örnek alalım. John, Sarah farklı kuruluşlara farklı rollerle farklı kuruluş bağlamlarında bulunmaktadır. Farklı modüllerin üzerine gelerek neler olduğunu görebilirsiniz.', }, }, - step_1: 'Adım 1: Kuruluş izinlerini tanımlayın', - step_2: 'Adım 2: Kuruluş rollerini tanımlayın', - step_3: 'Adım 3: İlk kuruluşunuzu oluşturun', - step_3_description: - 'İlk kuruluşunuzu oluşturma zamanı geldi. Bu kuruluş benzersiz bir kimliğe sahip olacak ve çeşitli işe yönelik kimlikleri işleme koymak için bir kap olarak hizmet verecektir.', - more_next_steps: 'Daha fazla adım', - add_members: 'Kuruluşunuza üyeler ekleyin', - /** UNTRANSLATED */ - config_organization: 'Configure organization', organization_permissions: 'Kuruluş izinleri', - permission_name: 'İzin adı', - permissions: 'İzinler', organization_roles: 'Kuruluş rolleri', - role_name: 'Rol adı', - organization_name: 'Kuruluş adı', admin: 'Yönetici', member: 'Üye', guest: 'Misafir', diff --git a/packages/phrases/src/locales/zh-cn/translation/admin-console/organizations.ts b/packages/phrases/src/locales/zh-cn/translation/admin-console/organizations.ts index a649577450a..ccaeecfc4cc 100644 --- a/packages/phrases/src/locales/zh-cn/translation/admin-console/organizations.ts +++ b/packages/phrases/src/locales/zh-cn/translation/admin-console/organizations.ts @@ -18,23 +18,13 @@ const organizations = { organization_description_placeholder: '组织的简要描述', organization_permission: '组织权限', organization_permission_other: '组织权限', - organization_permission_description: - '组织权限是指在组织上下文中访问资源的授权。组织权限应该用有意义的字符串表示,同时也作为名称和唯一标识。', - organization_permission_delete_confirm: - '如果删除此权限,所有包含此权限的组织角色将失去此权限以及授予此权限的用户的访问权限。', create_permission_placeholder: '读取预约历史', - permission: '权限', - permission_other: '权限', organization_role: '组织角色', organization_role_other: '组织角色', organization_role_description: '组织角色是可以分配给用户的权限组。这些权限必须来自预定义的组织权限。', - organization_role_delete_confirm: - '这样做将从受影响的用户那里删除与此角色相关的权限,并删除组织角色、组织成员和组织权限之间的关系。', role: '角色', - create_role_placeholder: '仅查看权限的用户', search_placeholder: '按组织名称或ID搜索', - search_permission_placeholder: '输入以搜索和选择权限', search_role_placeholder: '输入以搜索和选择角色', empty_placeholder: '🤔 你还没有设置任何{{entity}}。', organization_and_member: '组织和成员', @@ -67,21 +57,8 @@ const organizations = { '让我们举个例子。约翰、莎拉位于不同的组织中,其在不同组织上下文中拥有不同的角色。将鼠标悬停在不同模块上,看看会发生什么。', }, }, - step_1: '步骤1:定义组织权限', - step_2: '步骤2:定义组织角色', - step_3: '步骤3:创建您的第一个组织', - step_3_description: - '让我们创建您的第一个组织。它具有唯一的ID,并且可以作为处理各种业务向身份的容器。', - more_next_steps: '更多下一步', - add_members: '向您的组织添加成员', - /** UNTRANSLATED */ - config_organization: 'Configure organization', organization_permissions: '组织权限', - permission_name: '权限名', - permissions: '权限', organization_roles: '组织角色', - role_name: '角色名', - organization_name: '组织名称', admin: '管理员', member: '成员', guest: '访客', diff --git a/packages/phrases/src/locales/zh-hk/translation/admin-console/organizations.ts b/packages/phrases/src/locales/zh-hk/translation/admin-console/organizations.ts index 8fd5e891fc0..4c0f7628785 100644 --- a/packages/phrases/src/locales/zh-hk/translation/admin-console/organizations.ts +++ b/packages/phrases/src/locales/zh-hk/translation/admin-console/organizations.ts @@ -18,23 +18,13 @@ const organizations = { organization_description_placeholder: '組織的簡要描述', organization_permission: '組織權限', organization_permission_other: '組織權限', - organization_permission_description: - '組織權限指授權在組織上下文中存取資源的許可。組織權限應該以有意義的字串形式表示,同時作為名稱和唯一標識。', - organization_permission_delete_confirm: - '如果刪除此權限,所有包含此權限的組織角色都將失去此權限,具有此權限的用戶將失去其授予的訪問權限。', create_permission_placeholder: '讀取預約歷史', - permission: '權限', - permission_other: '權限', organization_role: '組織角色', organization_role_other: '組織角色', organization_role_description: '組織角色是可以分配給用戶的權限的分組。權限必須來自預定義的組織權限。', - organization_role_delete_confirm: - '這樣將從受影響的用戶身上刪除與此角色關聯的權限,並刪除組織角色、組織成員和組織權限之間的關係。', role: '角色', - create_role_placeholder: '僅擁有檢視權限的用戶', search_placeholder: '按組織名稱或 ID 搜索', - search_permission_placeholder: '輸入並搜索選擇權限', search_role_placeholder: '輸入並搜索選擇角色', empty_placeholder: '🤔 你尚未設置任何 {{entity}}。', organization_and_member: '組織和成員', @@ -67,21 +57,8 @@ const organizations = { '讓我們舉個例子。John、Sarah 屬於不同的組織,在不同組織的上下文中具有不同的角色。懸停在不同的模塊上,看看會發生什麼。', }, }, - step_1: '第 1 步:定義組織權限', - step_2: '第 2 步:定義組織角色', - step_3: '第 3 步:創建您的第一個組織', - step_3_description: - '讓我們一起建立您的第一個組織。它具有唯一的 ID,可以作為處理各種面向業務的實體的容器。', - more_next_steps: '更多下一步', - add_members: '將成員添加到您的組織', - /** UNTRANSLATED */ - config_organization: 'Configure organization', organization_permissions: '組織權限', - permission_name: '權限名稱', - permissions: '權限列表', organization_roles: '組織角色', - role_name: '角色名稱', - organization_name: '組織名稱', admin: '管理員', member: '成員', guest: '訪客', diff --git a/packages/phrases/src/locales/zh-tw/translation/admin-console/organizations.ts b/packages/phrases/src/locales/zh-tw/translation/admin-console/organizations.ts index f8ad4cbc5e7..8befae5cfa2 100644 --- a/packages/phrases/src/locales/zh-tw/translation/admin-console/organizations.ts +++ b/packages/phrases/src/locales/zh-tw/translation/admin-console/organizations.ts @@ -18,23 +18,13 @@ const organizations = { organization_description_placeholder: '組繹的簡要描述', organization_permission: '組繹權限', organization_permission_other: '組繹權限', - organization_permission_description: - '組繹權限是指在組繹上下文中訪問資源的授權。組繹權限應該以有意義的字符串表示,同時作為名稱和唯一標識。', - organization_permission_delete_confirm: - '如果刪除此權限,所有包括此權限的組繹角色將失去此權限,擁有此權限的用戶將失去其授予的訪問。', create_permission_placeholder: '瀏覽預約歷史', - permission: '權限', - permission_other: '權限', organization_role: '組繹角色', organization_role_other: '組繹角色', organization_role_description: '組繹角色是一組可以分配給用戶的權限。這些權限必須來自預定義的組繹權限。', - organization_role_delete_confirm: - '這將從受影響的用戶中刪除與此角色相關的權限,並刪除組繹角色、組繹成員和組繹權限之間的關係。', role: '角色', - create_role_placeholder: '只擁有查看權限的用戶', search_placeholder: '按組繹名稱或 ID 搜索', - search_permission_placeholder: '輸入搜索並選擇權限', search_role_placeholder: '輸入搜索並選擇角色', empty_placeholder: '🤔 你目前尚未設置任何 {{entity}} 。', organization_and_member: '組織和成員', @@ -67,21 +57,8 @@ const organizations = { '讓我們舉個例子。約翰、莎拉屬於不同的組繫,並在不同組繫的上下文中擔任不同角色。 將滑鼠指針懸停在不同的模塊上並觀察會發生什麼。', }, }, - step_1: '步驟1:定義組繹權限', - step_2: '步驟2:定義組繹角色', - step_3: '步驟3:創建您的第一個組繹', - step_3_description: - '讓我們創建您的第一個組繹。它具有唯一的 ID,並用作處理各種面向商業的身分的容器。', - more_next_steps: '更多下一步', - add_members: '將成員加入您的組繹', - /** UNTRANSLATED */ - config_organization: 'Configure organization', organization_permissions: '組繹權限', - permission_name: '權限名稱', - permissions: '權限', organization_roles: '組繹角色', - role_name: '角色名稱', - organization_name: '組繹名稱', admin: '管理員', member: '成員', guest: '訪客', From e388c66a2e705f651585a435af7f9fb0d72e4531 Mon Sep 17 00:00:00 2001 From: wangsijie Date: Mon, 13 May 2024 14:26:34 +0800 Subject: [PATCH 374/687] chore(core,schemas): remove feature guard of organization api resource (#5743) --- packages/core/src/oidc/extra-token-claims.ts | 6 ---- .../core/src/oidc/grants/refresh-token.ts | 16 ++++------ packages/core/src/oidc/resource.ts | 8 ++--- .../application-user-consent-scope.ts | 31 ++++++------------- .../src/routes/interaction/consent/index.ts | 26 +++++----------- .../src/routes/interaction/consent/utils.ts | 5 --- .../core/src/routes/organization/roles.ts | 29 +++-------------- packages/schemas/src/types/organization.ts | 12 ------- 8 files changed, 29 insertions(+), 104 deletions(-) diff --git a/packages/core/src/oidc/extra-token-claims.ts b/packages/core/src/oidc/extra-token-claims.ts index 906e5134599..01c41b0a646 100644 --- a/packages/core/src/oidc/extra-token-claims.ts +++ b/packages/core/src/oidc/extra-token-claims.ts @@ -27,12 +27,6 @@ export const getExtraTokenClaimsForOrganizationApiResource = async ( ctx: KoaContextWithOIDC, token: unknown ): Promise => { - const { isDevFeaturesEnabled } = EnvSet.values; - - if (!isDevFeaturesEnabled) { - return; - } - const organizationId = ctx.oidc.params?.organization_id; const resource = ctx.oidc.params?.resource; diff --git a/packages/core/src/oidc/grants/refresh-token.ts b/packages/core/src/oidc/grants/refresh-token.ts index 26950a9ef27..b44eb80769e 100644 --- a/packages/core/src/oidc/grants/refresh-token.ts +++ b/packages/core/src/oidc/grants/refresh-token.ts @@ -35,7 +35,7 @@ import dpopValidate from 'oidc-provider/lib/helpers/validate_dpop.js'; import validatePresence from 'oidc-provider/lib/helpers/validate_presence.js'; import instance from 'oidc-provider/lib/helpers/weak_cache.js'; -import { EnvSet } from '#src/env-set/index.js'; +import { type EnvSet } from '#src/env-set/index.js'; import type Queries from '#src/tenants/Queries.js'; import assertThat from '#src/utils/assert-that.js'; @@ -140,15 +140,11 @@ export const buildHandler: ( // The value type is `unknown`, which will swallow other type inferences. So we have to cast it // to `Boolean` first. const organizationId = cond(Boolean(params.organization_id) && String(params.organization_id)); - if (organizationId) { - // Validate if the refresh token has the required scope from RFC 0001. - if (!refreshToken.scopes.has(UserScope.Organizations)) { - throw new InsufficientScope('refresh token missing required scope', UserScope.Organizations); - } - // Does not allow requesting resource token when requesting organization token (yet). - if (!EnvSet.values.isDevFeaturesEnabled && params.resource) { - throw new InvalidRequest('resource is not allowed when requesting organization token'); - } + if ( + organizationId && // Validate if the refresh token has the required scope from RFC 0001. + !refreshToken.scopes.has(UserScope.Organizations) + ) { + throw new InsufficientScope('refresh token missing required scope', UserScope.Organizations); } /* === End RFC 0001 === */ diff --git a/packages/core/src/oidc/resource.ts b/packages/core/src/oidc/resource.ts index 37c43cf73c5..48dd4086038 100644 --- a/packages/core/src/oidc/resource.ts +++ b/packages/core/src/oidc/resource.ts @@ -3,7 +3,7 @@ import { type Resource } from '@logto/schemas'; import { trySafe, type Nullable } from '@silverhand/essentials'; import { type ResourceServer } from 'oidc-provider'; -import { EnvSet } from '#src/env-set/index.js'; +import { type EnvSet } from '#src/env-set/index.js'; import type Libraries from '#src/tenants/Libraries.js'; import type Queries from '#src/tenants/Queries.js'; @@ -164,10 +164,8 @@ export const filterResourceScopesForTheThirdPartyApplication = async ( const userConsentResource = userConsentResources.find( ({ resource }) => resource.indicator === indicator ); - const userConsentOrganizationResources = EnvSet.values.isDevFeaturesEnabled - ? includeOrganizationResourceScopes - ? await getApplicationUserConsentOrganizationResourceScopes(applicationId) - : [] + const userConsentOrganizationResources = includeOrganizationResourceScopes + ? await getApplicationUserConsentOrganizationResourceScopes(applicationId) : []; const userConsentOrganizationResource = userConsentOrganizationResources.find( ({ resource }) => resource.indicator === indicator diff --git a/packages/core/src/routes/applications/application-user-consent-scope.ts b/packages/core/src/routes/applications/application-user-consent-scope.ts index 22ee94c5590..657e34998fa 100644 --- a/packages/core/src/routes/applications/application-user-consent-scope.ts +++ b/packages/core/src/routes/applications/application-user-consent-scope.ts @@ -5,7 +5,6 @@ import { } from '@logto/schemas'; import { object, string, nativeEnum } from 'zod'; -import { EnvSet } from '#src/env-set/index.js'; import koaGuard from '#src/middleware/koa-guard.js'; import type { ManagementApiRouter, RouterInitArgs } from '../types.js'; @@ -53,15 +52,11 @@ export default function applicationUserConsentScopeRoutes { @@ -94,18 +87,12 @@ export default function applicationUserConsentScopeRoutes( // Find the organizations granted by the user // The user may send consent request multiple times, so we need to find the organizations again - const [, organizations] = EnvSet.values.isDevFeaturesEnabled - ? await queries.applications.userConsentOrganizations.getEntities(Organizations, { - applicationId, - userId, - }) - : [0, []]; + const [, organizations] = await queries.applications.userConsentOrganizations.getEntities( + Organizations, + { + applicationId, + userId, + } + ); // The missingResourceScopes from the prompt details are from `getResourceServerInfo`, // which contains resource scopes and organization resource scopes. @@ -111,10 +111,6 @@ export default function consentRoutes( const organizationsWithMissingResourceScopes = await Promise.all( organizations.map(async ({ name, id }) => { - if (!EnvSet.values.isDevFeaturesEnabled) { - return { name, id }; - } - const missingResourceScopes = await filterAndParseMissingResourceScopes({ resourceScopes: allMissingResourceScopes, queries, @@ -136,10 +132,6 @@ export default function consentRoutes( const resourceScopesToGrant: Record = Object.fromEntries( organizationsWithMissingResourceScopes.reduce>( (entries, { missingResourceScopes }) => { - if (!missingResourceScopes) { - return entries; - } - const organizationEntries: Array<[string, string[]]> = missingResourceScopes.map( ({ resource, scopes }) => [resource.indicator, scopes.map(({ name }) => name)] ); @@ -261,10 +253,6 @@ export default function consentRoutes( const organizationsWithMissingResourceScopes = await Promise.all( organizations.map(async ({ name, id }) => { - if (!EnvSet.values.isDevFeaturesEnabled) { - return { name, id }; - } - const missingResourceScopes = await filterAndParseMissingResourceScopes({ resourceScopes: allMissingResourceScopes, queries, diff --git a/packages/core/src/routes/interaction/consent/utils.ts b/packages/core/src/routes/interaction/consent/utils.ts index d438bb43233..f8f258681cd 100644 --- a/packages/core/src/routes/interaction/consent/utils.ts +++ b/packages/core/src/routes/interaction/consent/utils.ts @@ -2,7 +2,6 @@ import { ReservedResource } from '@logto/core-kit'; import { type MissingResourceScopes, type Scope, missingResourceScopesGuard } from '@logto/schemas'; import { errors } from 'oidc-provider'; -import { EnvSet } from '#src/env-set/index.js'; import { filterResourceScopesForTheThirdPartyApplication, findResourceScopes, @@ -108,10 +107,6 @@ export const filterAndParseMissingResourceScopes = async ({ await Promise.all( Object.entries(resourceScopes).map( async ([resourceIndicator, missingScopes]): Promise<[string, string[]]> => { - if (!EnvSet.values.isDevFeaturesEnabled) { - return [resourceIndicator, missingScopes]; - } - // Fetch the list of scopes, `findFromOrganizations` is set to false, // so it will only search the user resource scopes. const scopes = await findResourceScopes({ diff --git a/packages/core/src/routes/organization/roles.ts b/packages/core/src/routes/organization/roles.ts index 39b90e59207..5e706abdc2f 100644 --- a/packages/core/src/routes/organization/roles.ts +++ b/packages/core/src/routes/organization/roles.ts @@ -2,12 +2,10 @@ import { type CreateOrganizationRole, OrganizationRoles, organizationRoleWithScopesGuard, - organizationRoleWithScopesGuardDeprecated, } from '@logto/schemas'; import { generateStandardId } from '@logto/shared'; import { z } from 'zod'; -import { EnvSet } from '#src/env-set/index.js'; import koaGuard from '#src/middleware/koa-guard.js'; import koaPagination from '#src/middleware/koa-pagination.js'; import koaQuotaGuard from '#src/middleware/koa-quota-guard.js'; @@ -45,10 +43,7 @@ export default function organizationRoleRoutes( koaPagination(), koaGuard({ query: z.object({ q: z.string().optional() }), - // TODO @wangsijie - Remove this once the feature is ready - response: EnvSet.values.isDevFeaturesEnabled - ? organizationRoleWithScopesGuard.array() - : organizationRoleWithScopesGuardDeprecated.array(), + response: organizationRoleWithScopesGuard.array(), status: [200], }), async (ctx, next) => { @@ -70,19 +65,6 @@ export default function organizationRoleRoutes( resourceScopeIds: string[]; }; - // TODO @wangsijie - Remove this once the feature is ready - const originalCreateCard: z.ZodType< - Omit & { resourceScopeIds?: string[] }, - z.ZodTypeDef, - unknown - > = OrganizationRoles.createGuard - .omit({ - id: true, - }) - .extend({ - organizationScopeIds: z.array(z.string()).default([]), - }); - const createGuard: z.ZodType = OrganizationRoles.createGuard .omit({ @@ -96,7 +78,7 @@ export default function organizationRoleRoutes( router.post( '/', koaGuard({ - body: EnvSet.values.isDevFeaturesEnabled ? createGuard : originalCreateCard, + body: createGuard, response: OrganizationRoles.guard, status: [201, 422], }), @@ -110,8 +92,7 @@ export default function organizationRoleRoutes( ); } - // TODO @wangsijie - Remove this once the feature is ready - if (EnvSet.values.isDevFeaturesEnabled && resourceScopeIds && resourceScopeIds.length > 0) { + if (resourceScopeIds.length > 0) { await rolesResourceScopes.insert( ...resourceScopeIds.map<[string, string]>((id) => [role.id, id]) ); @@ -124,9 +105,7 @@ export default function organizationRoleRoutes( ); router.addRelationRoutes(rolesScopes, 'scopes'); - if (EnvSet.values.isDevFeaturesEnabled) { - router.addRelationRoutes(rolesResourceScopes, 'resource-scopes'); - } + router.addRelationRoutes(rolesResourceScopes, 'resource-scopes'); originalRouter.use(router.routes()); } diff --git a/packages/schemas/src/types/organization.ts b/packages/schemas/src/types/organization.ts index 27a8201932f..51407c45a50 100644 --- a/packages/schemas/src/types/organization.ts +++ b/packages/schemas/src/types/organization.ts @@ -37,18 +37,6 @@ export type OrganizationRoleWithScopes = OrganizationRole & { resourceScopes: ResourceScopeEntity[]; }; -// TODO @wangsijie - Remove this once the feature is ready -export const organizationRoleWithScopesGuardDeprecated: ToZodObject< - Omit -> = OrganizationRoles.guard.extend({ - scopes: z - .object({ - id: z.string(), - name: z.string(), - }) - .array(), -}); - export const organizationRoleWithScopesGuard: ToZodObject = OrganizationRoles.guard.extend({ scopes: z From cad032a22adc65a43f16503d9f4db26284ba1cb4 Mon Sep 17 00:00:00 2001 From: Charles Zhao Date: Mon, 13 May 2024 15:02:05 +0800 Subject: [PATCH 375/687] chore(console): update jwt claims status in plan comparison table (#5854) --- .../TenantSettings/Subscription/PlanComparisonTable/index.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/console/src/pages/TenantSettings/Subscription/PlanComparisonTable/index.tsx b/packages/console/src/pages/TenantSettings/Subscription/PlanComparisonTable/index.tsx index 550b30cb3ad..69256dbc0d7 100644 --- a/packages/console/src/pages/TenantSettings/Subscription/PlanComparisonTable/index.tsx +++ b/packages/console/src/pages/TenantSettings/Subscription/PlanComparisonTable/index.tsx @@ -234,7 +234,7 @@ function PlanComparisonTable() { rows: [ { name: webhooks, data: ['1', '10', contact] }, { name: auditLogRetention, data: [freePlanLogRetention, paidPlanLogRetention, contact] }, - { name: jwtClaims, data: ['-', comingSoon, comingSoon] }, + { name: jwtClaims, data: ['-', '✓', contact] }, { name: tenantMembers, data: [ From e7a642028d0f962faacaa7ebc815830bf3bbff6b Mon Sep 17 00:00:00 2001 From: simeng-li Date: Mon, 13 May 2024 16:11:50 +0800 Subject: [PATCH 376/687] feat(schemas): define data hook events (#5828) * feat(schemas): define data hook events define data hook events * fix(schemas,core): fix the type error fix the type error * fix(core): fix unit test fix unit test * feat(test): add integration tests for DataHooks add integration tests for DataHooks * fix(test): fix ut of management api hook middleware fix ut of the management api hook middleware * refactor(test,core,schemas): refactor some DataHook definiations refactor some DataHook definitations * chore(test): remove upper scope describe wrap remove upper scope describe wrap * fix(test): fix tests fix tests * refactor(schemas): rename the info.update events rename the info.update events * refactor(schemas): rename rename * refactor(core,schemas): refactor DataHook code refactor DataHook code to address some code review comments * fix(test): fix ut fix ut * fix(schemas): update DataHookEventPayload type update DataHookEventPayload type * chore(schemas): update comments update comments --- .../koa-management-api-hooks.test.ts | 19 +- .../middleware/koa-management-api-hooks.ts | 19 +- packages/core/src/utils/test-utils.ts | 4 +- packages/integration-tests/package.json | 3 +- .../src/tests/api/hook/WebhookMockServer.ts | 64 ++++ .../tests/api/hook/hook.trigger.data.test.ts | 342 ++++++++++++++++++ ...st.ts => hook.trigger.interaction.test.ts} | 0 .../src/tests/api/hook/test-cases.ts | 195 ++++++++++ .../src/foundations/jsonb-types/hooks.ts | 77 +++- packages/schemas/src/types/hook.ts | 12 +- pnpm-lock.yaml | 3 + 11 files changed, 720 insertions(+), 18 deletions(-) create mode 100644 packages/integration-tests/src/tests/api/hook/WebhookMockServer.ts create mode 100644 packages/integration-tests/src/tests/api/hook/hook.trigger.data.test.ts rename packages/integration-tests/src/tests/api/hook/{hook.trigger.test.ts => hook.trigger.interaction.test.ts} (100%) create mode 100644 packages/integration-tests/src/tests/api/hook/test-cases.ts diff --git a/packages/core/src/middleware/koa-management-api-hooks.test.ts b/packages/core/src/middleware/koa-management-api-hooks.test.ts index eba7130c592..2703d88e048 100644 --- a/packages/core/src/middleware/koa-management-api-hooks.test.ts +++ b/packages/core/src/middleware/koa-management-api-hooks.test.ts @@ -65,15 +65,19 @@ describe('koaManagementApiHooks', () => { it.each(events)('should append hook context for %s', async (key, event) => { const [method, route] = key.split(' ') as [string, string]; + const ctxParams = createContextWithRouteParameters(); const ctx: ParameterizedContext = { - ...createContextWithRouteParameters(), + ...ctxParams, header: {}, appendDataHookContext: notToBeCalled, method, _matchedRoute: route, path: route, - body: { key }, + response: { + ...ctxParams.response, + body: { key }, + }, status: 200, }; @@ -85,7 +89,16 @@ describe('koaManagementApiHooks', () => { contextArray: [ { event, - data: { path: route, method, body: { key }, status: 200 }, + data: { + path: route, + method, + response: { + body: { key }, + }, + params: ctxParams.params, + matchedRoute: route, + status: 200, + }, }, ], }) diff --git a/packages/core/src/middleware/koa-management-api-hooks.ts b/packages/core/src/middleware/koa-management-api-hooks.ts index f941d8f40bb..c1a949afda4 100644 --- a/packages/core/src/middleware/koa-management-api-hooks.ts +++ b/packages/core/src/middleware/koa-management-api-hooks.ts @@ -49,13 +49,24 @@ export const koaManagementApiHooks = 0) { diff --git a/packages/core/src/utils/test-utils.ts b/packages/core/src/utils/test-utils.ts index fa98c5e481e..98ea31c5ace 100644 --- a/packages/core/src/utils/test-utils.ts +++ b/packages/core/src/utils/test-utils.ts @@ -4,13 +4,13 @@ import type { PrimitiveValueExpression, TaggedTemplateLiteralInvocation, } from '@silverhand/slonik/dist/src/types.js'; -import type { MiddlewareType, Context, Middleware } from 'koa'; +import type { Context, Middleware, MiddlewareType } from 'koa'; import Koa from 'koa'; import type { IRouterParamContext } from 'koa-router'; import Router from 'koa-router'; import request from 'supertest'; -import type { ManagementApiRouter, AnonymousRouter } from '#src/routes/types.js'; +import type { AnonymousRouter, ManagementApiRouter } from '#src/routes/types.js'; import type TenantContext from '#src/tenants/TenantContext.js'; import type { Options } from '#src/test-utils/jest-koa-mocks/create-mock-context.js'; import createMockContext from '#src/test-utils/jest-koa-mocks/create-mock-context.js'; diff --git a/packages/integration-tests/package.json b/packages/integration-tests/package.json index a674bbb4882..b336684a136 100644 --- a/packages/integration-tests/package.json +++ b/packages/integration-tests/package.json @@ -48,7 +48,8 @@ "prettier": "^3.0.0", "puppeteer": "^22.6.5", "text-encoder": "^0.0.4", - "typescript": "^5.3.3" + "typescript": "^5.3.3", + "zod": "^3.22.4" }, "engines": { "node": "^20.9.0" diff --git a/packages/integration-tests/src/tests/api/hook/WebhookMockServer.ts b/packages/integration-tests/src/tests/api/hook/WebhookMockServer.ts new file mode 100644 index 00000000000..952b8f95542 --- /dev/null +++ b/packages/integration-tests/src/tests/api/hook/WebhookMockServer.ts @@ -0,0 +1,64 @@ +import { createServer, type RequestListener, type Server } from 'node:http'; + +/** + * A mock server that listens for incoming requests and responds with the request body. + * + * @example + * const server = new WebhookMockServer(3000); + * await server.listen(); + */ +class WebhookMockServer { + public readonly endpoint = `http://localhost:${this.port}`; + private readonly server: Server; + + constructor( + /** The port number to listen on. */ + private readonly port: number, + /** A callback that is called with the request body when a request is received. */ + requestCallback?: (body: string) => void + ) { + const requestListener: RequestListener = (request, response) => { + const data: Uint8Array[] = []; + + request.on('data', (chunk: Uint8Array) => { + // eslint-disable-next-line @silverhand/fp/no-mutating-methods + data.push(chunk); + }); + + request.on('end', () => { + response.writeHead(200, { 'Content-Type': 'application/json' }); + + const payload: unknown = JSON.parse(Buffer.concat(data).toString()); + + const body = JSON.stringify({ + signature: request.headers['logto-signature-sha-256'], + payload, + }); + + requestCallback?.(body); + + response.end(body); + }); + }; + + this.server = createServer(requestListener); + } + + public async listen() { + return new Promise((resolve) => { + this.server.listen(this.port, () => { + resolve(true); + }); + }); + } + + public async close() { + return new Promise((resolve) => { + this.server.close(() => { + resolve(true); + }); + }); + } +} + +export default WebhookMockServer; diff --git a/packages/integration-tests/src/tests/api/hook/hook.trigger.data.test.ts b/packages/integration-tests/src/tests/api/hook/hook.trigger.data.test.ts new file mode 100644 index 00000000000..37981329046 --- /dev/null +++ b/packages/integration-tests/src/tests/api/hook/hook.trigger.data.test.ts @@ -0,0 +1,342 @@ +import { + RoleType, + hookEventGuard, + hookEvents, + jsonGuard, + managementApiHooksRegistration, + type Hook, + type Role, +} from '@logto/schemas'; +import { z } from 'zod'; + +import { authedAdminApi } from '#src/api/api.js'; +import { createResource } from '#src/api/resource.js'; +import { createScope } from '#src/api/scope.js'; +import { + OrganizationApiTest, + OrganizationRoleApiTest, + OrganizationScopeApiTest, +} from '#src/helpers/organization.js'; +import { UserApiTest, generateNewUser } from '#src/helpers/user.js'; +import { generateName, waitFor } from '#src/utils.js'; + +import WebhookMockServer from './WebhookMockServer.js'; +import { + organizationDataHookTestCases, + organizationRoleDataHookTestCases, + organizationScopeDataHookTestCases, + roleDataHookTestCases, + scopesDataHookTestCases, + userDataHookTestCases, +} from './test-cases.js'; + +const mockHookResponseGuard = z.object({ + signature: z.string(), + payload: z.object({ + event: hookEventGuard, + createdAt: z.string(), + hookId: z.string(), + body: jsonGuard.optional(), + method: z + .string() + .optional() + .transform((value) => value?.toUpperCase()), + matchedRoute: z.string().optional(), + }), +}); + +type MockHookResponse = z.infer; + +const hookName = 'management-api-hook'; +const webhooks = new Map(); +const webhookResults = new Map(); + +// Record the hook response to the webhookResults map. +// Compare the webhookResults map with the managementApiHooksRegistration to verify all hook is triggered. +const webhookResponseHandler = (response: string) => { + const result = mockHookResponseGuard.parse(JSON.parse(response)); + const { payload } = result; + + // Use matchedRoute as the key + if (payload.matchedRoute) { + webhookResults.set(`${payload.method} ${payload.matchedRoute}`, result); + } +}; + +/** + * Get the webhook result by the key. + * + * @remark Since the webhook request is async, we need to wait for a while + * to ensure the webhook response is received. + */ +const getWebhookResult = async (key: string) => { + await waitFor(100); + + return webhookResults.get(key); +}; + +const webhookServer = new WebhookMockServer(9999, webhookResponseHandler); + +beforeAll(async () => { + await webhookServer.listen(); + + const webhookInstance = await authedAdminApi + .post('hooks', { + json: { + name: hookName, + events: [...hookEvents], + config: { + url: webhookServer.endpoint, + headers: { foo: 'bar' }, + }, + }, + }) + .json(); + + webhooks.set(hookName, webhookInstance); +}); + +afterAll(async () => { + await Promise.all( + Array.from(webhooks.values()).map(async (hook) => authedAdminApi.delete(`hooks/${hook.id}`)) + ); + + await webhookServer.close(); +}); + +describe('user data hook events', () => { + // eslint-disable-next-line @silverhand/fp/no-let + let userId: string; + + beforeAll(async () => { + // Create a user to trigger the User.Created event. + const { user } = await generateNewUser({ username: true, password: true }); + // eslint-disable-next-line @silverhand/fp/no-mutation + userId = user.id; + const userCreateHook = await getWebhookResult('POST /users'); + expect(userCreateHook?.payload.event).toBe('User.Created'); + }); + + it.each(userDataHookTestCases)( + 'test case %#: %p', + async ({ route, event, method, endpoint, payload }) => { + await authedAdminApi[method](endpoint.replace('{userId}', userId), { json: payload }); + const hook = await getWebhookResult(route); + expect(hook?.payload.event).toBe(event); + } + ); +}); + +describe('role data hook events', () => { + /* eslint-disable @silverhand/fp/no-let */ + let roleId: string; + let scopeId: string; + let resourceId: string; + /* eslint-enable @silverhand/fp/no-let */ + + beforeAll(async () => { + // Create a role to trigger the Role.Created event. + const role = await authedAdminApi + .post('roles', { + json: { name: generateName(), description: 'data-hook-role', type: RoleType.User }, + }) + .json(); + + const roleCreateHook = await getWebhookResult('POST /roles'); + expect(roleCreateHook?.payload.event).toBe('Role.Created'); + + // Prepare the role and scope id for the Role.Scopes.Updated event. + /* eslint-disable @silverhand/fp/no-mutation */ + roleId = role.id; + const resource = await createResource(); + const scope = await createScope(resource.id); + + scopeId = scope.id; + resourceId = resource.id; + /* eslint-enable @silverhand/fp/no-mutation */ + }); + + afterAll(async () => { + await authedAdminApi.delete(`resources/${resourceId}`); + }); + + it.each(roleDataHookTestCases)( + 'test case %#: %p', + async ({ route, event, method, endpoint, payload }) => { + await authedAdminApi[method]( + endpoint.replace('{roleId}', roleId).replace('{scopeId}', scopeId), + // Replace all the scopeId placeholder in the payload + { json: JSON.parse(JSON.stringify(payload).replace('{scopeId}', scopeId)) } + ); + const hook = await getWebhookResult(route); + expect(hook?.payload.event).toBe(event); + } + ); +}); + +describe('scope data hook events', () => { + /* eslint-disable @silverhand/fp/no-let */ + let resourceId: string; + let scopeId: string; + /* eslint-enable @silverhand/fp/no-let */ + + beforeAll(async () => { + const resource = await createResource(); + const scope = await createScope(resource.id); + + /* eslint-disable @silverhand/fp/no-mutation */ + resourceId = resource.id; + scopeId = scope.id; + /* eslint-enable @silverhand/fp/no-mutation */ + + const scopesCreateHook = await getWebhookResult('POST /resources/:resourceId/scopes'); + expect(scopesCreateHook?.payload.event).toBe('Scope.Created'); + }); + + afterAll(async () => { + await authedAdminApi.delete(`resources/${resourceId}`); + }); + + it.each(scopesDataHookTestCases)( + 'test case %#: %p', + async ({ route, event, method, endpoint, payload }) => { + await authedAdminApi[method]( + endpoint.replace('{resourceId}', resourceId).replace('{scopeId}', scopeId), + { json: payload } + ); + const hook = await getWebhookResult(route); + expect(hook?.payload.event).toBe(event); + } + ); +}); + +describe('organization data hook events', () => { + /* eslint-disable @silverhand/fp/no-let */ + let organizationId: string; + let userId: string; + /* eslint-enable @silverhand/fp/no-let */ + + const organizationApi = new OrganizationApiTest(); + const userApi = new UserApiTest(); + + beforeAll(async () => { + const organization = await organizationApi.create({ + name: generateName(), + description: 'organization data hook test organization.', + }); + + const user = await userApi.create({ name: generateName() }); + + /* eslint-disable @silverhand/fp/no-mutation */ + organizationId = organization.id; + userId = user.id; + /* eslint-enable @silverhand/fp/no-mutation */ + + const organizationCreateHook = await getWebhookResult('POST /organizations'); + expect(organizationCreateHook?.payload.event).toBe('Organization.Created'); + }); + + afterAll(async () => { + await userApi.cleanUp(); + }); + + it.each(organizationDataHookTestCases)( + 'test case %#: %p', + async ({ route, event, method, endpoint, payload }) => { + await authedAdminApi[method]( + endpoint.replace('{organizationId}', organizationId).replace('{userId}', userId), + { json: JSON.parse(JSON.stringify(payload).replace('{userId}', userId)) } + ); + const hook = await getWebhookResult(route); + expect(hook?.payload.event).toBe(event); + } + ); +}); + +describe('organization scope data hook events', () => { + /* eslint-disable @silverhand/fp/no-let */ + let scopeId: string; + /* eslint-enable @silverhand/fp/no-let */ + + const organizationScopeApi = new OrganizationScopeApiTest(); + + beforeAll(async () => { + const scope = await organizationScopeApi.create({ + name: generateName(), + description: 'organization scope data hook test scope.', + }); + + /* eslint-disable @silverhand/fp/no-mutation */ + scopeId = scope.id; + /* eslint-enable @silverhand/fp/no-mutation */ + + const organizationScopeCreateHook = await getWebhookResult('POST /organization-scopes'); + expect(organizationScopeCreateHook?.payload.event).toBe('OrganizationScope.Created'); + }); + + it.each(organizationScopeDataHookTestCases)( + 'test case %#: %p', + async ({ route, event, method, endpoint, payload }) => { + await authedAdminApi[method](endpoint.replace('{organizationScopeId}', scopeId), { + json: payload, + }); + const hook = await getWebhookResult(route); + expect(hook?.payload.event).toBe(event); + } + ); +}); + +describe('organization role data hook events', () => { + /* eslint-disable @silverhand/fp/no-let */ + let roleId: string; + let scopeId: string; + /* eslint-enable @silverhand/fp/no-let */ + + const organizationScopeApi = new OrganizationScopeApiTest(); + const roleApi = new OrganizationRoleApiTest(); + + beforeAll(async () => { + const role = await roleApi.create({ + name: generateName(), + description: 'organization role data hook test role.', + }); + + const scope = await organizationScopeApi.create({ + name: generateName(), + description: 'organization role data hook test scope.', + }); + + /* eslint-disable @silverhand/fp/no-mutation */ + roleId = role.id; + scopeId = scope.id; + /* eslint-enable @silverhand/fp/no-mutation */ + + const organizationRoleCreateHook = await getWebhookResult('POST /organization-roles'); + expect(organizationRoleCreateHook?.payload.event).toBe('OrganizationRole.Created'); + }); + + afterAll(async () => { + await organizationScopeApi.cleanUp(); + }); + + it.each(organizationRoleDataHookTestCases)( + 'test case %#: %p', + async ({ route, event, method, endpoint, payload }) => { + await authedAdminApi[method]( + endpoint.replace('{organizationRoleId}', roleId).replace('{scopeId}', scopeId), + { json: JSON.parse(JSON.stringify(payload).replace('{scopeId}', scopeId)) } + ); + const hook = await getWebhookResult(route); + expect(hook?.payload.event).toBe(event); + } + ); +}); + +describe('data hook events coverage', () => { + const keys = Object.keys(managementApiHooksRegistration); + it.each(keys)('should have test case for %s', async (key) => { + const webhookResult = await getWebhookResult(key); + expect(webhookResult).toBeDefined(); + expect(webhookResult?.signature).toBeDefined(); + }); +}); diff --git a/packages/integration-tests/src/tests/api/hook/hook.trigger.test.ts b/packages/integration-tests/src/tests/api/hook/hook.trigger.interaction.test.ts similarity index 100% rename from packages/integration-tests/src/tests/api/hook/hook.trigger.test.ts rename to packages/integration-tests/src/tests/api/hook/hook.trigger.interaction.test.ts diff --git a/packages/integration-tests/src/tests/api/hook/test-cases.ts b/packages/integration-tests/src/tests/api/hook/test-cases.ts new file mode 100644 index 00000000000..4acdc1377ea --- /dev/null +++ b/packages/integration-tests/src/tests/api/hook/test-cases.ts @@ -0,0 +1,195 @@ +import { generateName } from '#src/utils.js'; + +type TestCase = { + route: string; + event: string; + method: 'patch' | 'post' | 'delete' | 'put'; + endpoint: string; + payload: Record; +}; + +export const userDataHookTestCases: TestCase[] = [ + { + route: 'PATCH /users/:userId', + event: 'User.Updated', + method: 'patch', + endpoint: `users/{userId}`, + payload: { name: 'new name' }, + }, + { + route: 'PATCH /users/:userId/custom-data', + event: 'User.Updated', + method: 'patch', + endpoint: `users/{userId}/custom-data`, + payload: { customData: { foo: 'bar' } }, + }, + { + route: 'PATCH /users/:userId/profile', + event: 'User.Updated', + method: 'patch', + endpoint: `users/{userId}/profile`, + payload: { profile: { nickname: 'darcy' } }, + }, + { + route: 'PATCH /users/:userId/password', + event: 'User.Updated', + method: 'patch', + endpoint: `users/{userId}/password`, + payload: { password: 'new-password' }, + }, + { + route: 'PATCH /users/:userId/is-suspended', + event: 'User.SuspensionStatus.Updated', + method: 'patch', + endpoint: `users/{userId}/is-suspended`, + payload: { isSuspended: true }, + }, + { + route: 'DELETE /users/:userId', + event: 'User.Deleted', + method: 'delete', + endpoint: `users/{userId}`, + payload: {}, + }, +]; + +export const roleDataHookTestCases: TestCase[] = [ + { + route: 'PATCH /roles/:id', + event: 'Role.Updated', + method: 'patch', + endpoint: `roles/{roleId}`, + payload: { name: 'new name' }, + }, + { + route: 'POST /roles/:id/scopes', + event: 'Role.Scopes.Updated', + method: 'post', + endpoint: `roles/{roleId}/scopes`, + payload: { scopeIds: ['{scopeId}'] }, + }, + { + route: 'DELETE /roles/:id/scopes/:scopeId', + event: 'Role.Scopes.Updated', + method: 'delete', + endpoint: `roles/{roleId}/scopes/{scopeId}`, + payload: {}, + }, + { + route: 'DELETE /roles/:id', + event: 'Role.Deleted', + method: 'delete', + endpoint: `roles/{roleId}`, + payload: {}, + }, +]; + +export const scopesDataHookTestCases: TestCase[] = [ + { + route: 'PATCH /resources/:resourceId/scopes/:scopeId', + event: 'Scope.Updated', + method: 'patch', + endpoint: `resources/{resourceId}/scopes/{scopeId}`, + payload: { name: generateName() }, + }, + { + route: 'DELETE /resources/:resourceId/scopes/:scopeId', + event: 'Scope.Deleted', + method: 'delete', + endpoint: `resources/{resourceId}/scopes/{scopeId}`, + payload: {}, + }, +]; + +export const organizationDataHookTestCases: TestCase[] = [ + { + route: 'PATCH /organizations/:id', + event: 'Organization.Updated', + method: 'patch', + endpoint: `organizations/{organizationId}`, + payload: { description: 'new org description' }, + }, + { + route: 'POST /organizations/:id/users', + event: 'Organization.Membership.Updated', + method: 'post', + endpoint: `organizations/{organizationId}/users`, + payload: { userIds: ['{userId}'] }, + }, + { + route: 'PUT /organizations/:id/users', + event: 'Organization.Membership.Updated', + method: 'put', + endpoint: `organizations/{organizationId}/users`, + payload: { userIds: ['{userId}'] }, + }, + { + route: 'DELETE /organizations/:id/users/:userId', + event: 'Organization.Membership.Updated', + method: 'delete', + endpoint: `organizations/{organizationId}/users/{userId}`, + payload: {}, + }, + { + route: 'DELETE /organizations/:id', + event: 'Organization.Deleted', + method: 'delete', + endpoint: `organizations/{organizationId}`, + payload: {}, + }, +]; + +export const organizationScopeDataHookTestCases: TestCase[] = [ + { + route: 'PATCH /organization-scopes/:id', + event: 'OrganizationScope.Updated', + method: 'patch', + endpoint: `organization-scopes/{organizationScopeId}`, + payload: { description: 'new org scope description' }, + }, + { + route: 'DELETE /organization-scopes/:id', + event: 'OrganizationScope.Deleted', + method: 'delete', + endpoint: `organization-scopes/{organizationScopeId}`, + payload: {}, + }, +]; + +export const organizationRoleDataHookTestCases: TestCase[] = [ + { + route: 'PATCH /organization-roles/:id', + event: 'OrganizationRole.Updated', + method: 'patch', + endpoint: `organization-roles/{organizationRoleId}`, + payload: { name: generateName() }, + }, + { + route: 'POST /organization-roles/:id/scopes', + event: 'OrganizationRole.Scopes.Updated', + method: 'post', + endpoint: `organization-roles/{organizationRoleId}/scopes`, + payload: { organizationScopeIds: ['{scopeId}'] }, + }, + { + route: 'PUT /organization-roles/:id/scopes', + event: 'OrganizationRole.Scopes.Updated', + method: 'put', + endpoint: `organization-roles/{organizationRoleId}/scopes`, + payload: { organizationScopeIds: ['{scopeId}'] }, + }, + { + route: 'DELETE /organization-roles/:id/scopes/:organizationScopeId', + event: 'OrganizationRole.Scopes.Updated', + method: 'delete', + endpoint: `organization-roles/{organizationRoleId}/scopes/{scopeId}`, + payload: {}, + }, + { + route: 'DELETE /organization-roles/:id', + event: 'OrganizationRole.Deleted', + method: 'delete', + endpoint: `organization-roles/{organizationRoleId}`, + payload: {}, + }, +]; diff --git a/packages/schemas/src/foundations/jsonb-types/hooks.ts b/packages/schemas/src/foundations/jsonb-types/hooks.ts index 502f5e20718..6c014b23dc0 100644 --- a/packages/schemas/src/foundations/jsonb-types/hooks.ts +++ b/packages/schemas/src/foundations/jsonb-types/hooks.ts @@ -15,26 +15,62 @@ export enum InteractionHookEvent { } // DataHookEvent -// TODO: @simeng-li implement more data hook events -enum DataHookMutableSchema { +enum DataHookSchema { + User = 'User', Role = 'Role', + Scope = 'Scope', + Organization = 'Organization', + OrganizationRole = 'OrganizationRole', + OrganizationScope = 'OrganizationScope', } -enum DataHookMutationType { +enum DataHookBasicMutationType { Created = 'Created', - Updated = 'Updated', Deleted = 'Deleted', + Updated = 'Updated', } -export type DataHookEvent = `${DataHookMutableSchema}.${DataHookMutationType}`; + +type BasicDataHookEvent = `${DataHookSchema}.${DataHookBasicMutationType}`; + +// Custom DataHook mutable schemas +type CustomDataHookMutableSchema = + | `${DataHookSchema.User}.SuspensionStatus` + | `${DataHookSchema.Role}.Scopes` + | `${DataHookSchema.Organization}.Membership` + | `${DataHookSchema.OrganizationRole}.Scopes`; + +type DataHookPropertyUpdateEvent = + `${CustomDataHookMutableSchema}.${DataHookBasicMutationType.Updated}`; + +export type DataHookEvent = BasicDataHookEvent | DataHookPropertyUpdateEvent; /** The hook event values that can be registered. */ export const hookEvents = Object.freeze([ InteractionHookEvent.PostRegister, InteractionHookEvent.PostSignIn, InteractionHookEvent.PostResetPassword, + 'User.Created', + 'User.Deleted', + 'User.Updated', + 'User.SuspensionStatus.Updated', 'Role.Created', - 'Role.Updated', 'Role.Deleted', + 'Role.Updated', + 'Role.Scopes.Updated', + 'Scope.Created', + 'Scope.Deleted', + 'Scope.Updated', + 'Organization.Created', + 'Organization.Deleted', + 'Organization.Updated', + 'Organization.Membership.Updated', + 'OrganizationRole.Created', + 'OrganizationRole.Deleted', + 'OrganizationRole.Updated', + 'OrganizationRole.Scopes.Updated', + 'OrganizationScope.Created', + 'OrganizationScope.Deleted', + 'OrganizationScope.Updated', ] as const satisfies Array); /** The type of hook event values that can be registered. */ @@ -74,7 +110,34 @@ type ApiMethod = 'GET' | 'POST' | 'PUT' | 'DELETE' | 'PATCH'; * Define the hook event that should be triggered when the management API is called. */ export const managementApiHooksRegistration = Object.freeze({ + 'POST /users': 'User.Created', + 'DELETE /users/:userId': 'User.Deleted', + 'PATCH /users/:userId': 'User.Updated', + 'PATCH /users/:userId/custom-data': 'User.Updated', + 'PATCH /users/:userId/profile': 'User.Updated', + 'PATCH /users/:userId/password': 'User.Updated', + 'PATCH /users/:userId/is-suspended': 'User.SuspensionStatus.Updated', 'POST /roles': 'Role.Created', - 'PATCH /roles/:id': 'Role.Updated', 'DELETE /roles/:id': 'Role.Deleted', + 'PATCH /roles/:id': 'Role.Updated', + 'POST /roles/:id/scopes': 'Role.Scopes.Updated', + 'DELETE /roles/:id/scopes/:scopeId': 'Role.Scopes.Updated', + 'POST /resources/:resourceId/scopes': 'Scope.Created', + 'DELETE /resources/:resourceId/scopes/:scopeId': 'Scope.Deleted', + 'PATCH /resources/:resourceId/scopes/:scopeId': 'Scope.Updated', + 'POST /organizations': 'Organization.Created', + 'DELETE /organizations/:id': 'Organization.Deleted', + 'PATCH /organizations/:id': 'Organization.Updated', + 'PUT /organizations/:id/users': 'Organization.Membership.Updated', + 'POST /organizations/:id/users': 'Organization.Membership.Updated', + 'DELETE /organizations/:id/users/:userId': 'Organization.Membership.Updated', + 'POST /organization-roles': 'OrganizationRole.Created', + 'DELETE /organization-roles/:id': 'OrganizationRole.Deleted', + 'PATCH /organization-roles/:id': 'OrganizationRole.Updated', + 'POST /organization-scopes': 'OrganizationScope.Created', + 'DELETE /organization-scopes/:id': 'OrganizationScope.Deleted', + 'PATCH /organization-scopes/:id': 'OrganizationScope.Updated', + 'PUT /organization-roles/:id/scopes': 'OrganizationRole.Scopes.Updated', + 'POST /organization-roles/:id/scopes': 'OrganizationRole.Scopes.Updated', + 'DELETE /organization-roles/:id/scopes/:organizationScopeId': 'OrganizationRole.Scopes.Updated', } satisfies Record<`${ApiMethod} ${string}`, DataHookEvent>); diff --git a/packages/schemas/src/types/hook.ts b/packages/schemas/src/types/hook.ts index b61aaf53f7b..8c81792406a 100644 --- a/packages/schemas/src/types/hook.ts +++ b/packages/schemas/src/types/hook.ts @@ -23,9 +23,19 @@ export type DataHookEventPayload = { hookId: string; ip?: string; userAgent?: string; - body?: Record; + /** An object that contains response data. */ + response?: { + body?: Record; + }; + /** Request route params. */ + params?: Record; + /** Request route path. */ path?: string; + /** Matched route used as the identifier to trigger the hook. */ + matchedRoute?: string; + /** Response status code. */ status?: number; + /** Request method. */ method?: string; } & Record; diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 852646696d1..f87002d9833 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -3767,6 +3767,9 @@ importers: typescript: specifier: ^5.3.3 version: 5.3.3 + zod: + specifier: ^3.22.4 + version: 3.22.4 packages/phrases: dependencies: From 697ac693a60867010f0438485ed0ef23193da2ea Mon Sep 17 00:00:00 2001 From: wangsijie Date: Mon, 13 May 2024 16:14:40 +0800 Subject: [PATCH 377/687] feat(console): add wordpress integration guide (#5844) --- .../console/src/assets/docs/guides/index.ts | 8 +++ .../docs/guides/web-wordpress/README.mdx | 69 +++++++++++++++++++ .../docs/guides/web-wordpress/config.json | 3 + .../assets/docs/guides/web-wordpress/index.ts | 15 ++++ .../assets/docs/guides/web-wordpress/logo.svg | 1 + 5 files changed, 96 insertions(+) create mode 100644 packages/console/src/assets/docs/guides/web-wordpress/README.mdx create mode 100644 packages/console/src/assets/docs/guides/web-wordpress/config.json create mode 100644 packages/console/src/assets/docs/guides/web-wordpress/index.ts create mode 100644 packages/console/src/assets/docs/guides/web-wordpress/logo.svg diff --git a/packages/console/src/assets/docs/guides/index.ts b/packages/console/src/assets/docs/guides/index.ts index c7202c0c373..667fb903298 100644 --- a/packages/console/src/assets/docs/guides/index.ts +++ b/packages/console/src/assets/docs/guides/index.ts @@ -35,6 +35,7 @@ import webPhp from './web-php/index'; import webPython from './web-python/index'; import webRemix from './web-remix/index'; import webSveltekit from './web-sveltekit/index'; +import webWordpress from './web-wordpress/index'; const guides: Readonly = Object.freeze([ { @@ -170,6 +171,13 @@ const guides: Readonly = Object.freeze([ Component: lazy(async () => import('./spa-webflow/README.mdx')), metadata: spaWebflow, }, + { + order: 2.2, + id: 'web-wordpress', + Logo: lazy(async () => import('./web-wordpress/logo.svg')), + Component: lazy(async () => import('./web-wordpress/README.mdx')), + metadata: webWordpress, + }, { order: 3, id: 'web-python', diff --git a/packages/console/src/assets/docs/guides/web-wordpress/README.mdx b/packages/console/src/assets/docs/guides/web-wordpress/README.mdx new file mode 100644 index 00000000000..192947c2553 --- /dev/null +++ b/packages/console/src/assets/docs/guides/web-wordpress/README.mdx @@ -0,0 +1,69 @@ +import UriInputField from '@/mdx-components/UriInputField'; +import Tabs from '@mdx/components/Tabs'; +import TabItem from '@mdx/components/TabItem'; +import InlineNotification from '@/ds-components/InlineNotification'; +import Steps from '@/mdx-components/Steps'; +import Step from '@/mdx-components/Step'; + + + + + +This tutorial will show you how to integrate Logto into your [Wordpress](https://wordpress.org) website. + +Follow the official [Wordpress installation guide](https://wordpress.org/support/article/how-to-install-wordpress/) to set up your Wordpress website before proceeding. + + + + + +We will use the [OpenID Connect Generic](https://wordpress.org/plugins/generic-openid-connect/) plugin to integrate Logto via OIDC protocal into your Wordpress website. + +1. Log in to your WordPress site. +2. Navigate to "Plugins" and click "Add New". +3. Search for "OpenID Connect Generic" and install the plugin by daggerhart. +4. Activate the plugin. + + + + + +First, let’s enter your redirect URI. You can find it in the plugin settings, scroll down to the "Notes" section, and copy the "Redirect URI" value. + + + +Don't forget to click the **Save** button. + + + + + +Refer to the following table for the necessary configuration details: + +| Plugin Field | Description | +| ----------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| Client ID | The app ID of your Logto application | +| Client Secret | The app secret of your Logto application | +| OpenID Scope | Enter `email profile openid offline_access` | +| Login Endpoint URL | The authorization endpoint URL of your Logto application, which is https://[tenant-id].logto.app/oidc/auth, you can click "show endpoint details" in the Logto application page to get the URL. | +| Userinfo Endpoint URL | The userinfo endpoint URL of your Logto application, which is https://[tenant-id].logto.app/oidc/me. | +| Token Validation Endpoint URL | The token validation endpoint URL of your Logto application, which is https://[tenant-id].logto.app/oidc/token. | +| End Session Endpoint URL | The end session endpoint URL of your Logto application, which is https://[tenant-id].logto.app/oidc/session/end. | +| Identity Key | The unique key in the ID token that contains the user's identity, it can be email or sub, depending on your configuration. | +| Nickname Key | The key in the ID token that contains the user's nickname, you can set it to sub and change it later. | + + + + + +Now, you can test your application: + +1. Log out of your WordPress site. +2. Visit the WordPress login page and click the "Sign in with Logto" button. +3. You will be redirected to the Logto sign-in page. +4. Sign in with your Logto account. +5. You will be redirected back to the WordPress site and logged in automatically. + + + + diff --git a/packages/console/src/assets/docs/guides/web-wordpress/config.json b/packages/console/src/assets/docs/guides/web-wordpress/config.json new file mode 100644 index 00000000000..4fa4d6a2ae9 --- /dev/null +++ b/packages/console/src/assets/docs/guides/web-wordpress/config.json @@ -0,0 +1,3 @@ +{ + "order": 2.2 +} diff --git a/packages/console/src/assets/docs/guides/web-wordpress/index.ts b/packages/console/src/assets/docs/guides/web-wordpress/index.ts new file mode 100644 index 00000000000..53ca03b1780 --- /dev/null +++ b/packages/console/src/assets/docs/guides/web-wordpress/index.ts @@ -0,0 +1,15 @@ +import { ApplicationType } from '@logto/schemas'; + +import { type GuideMetadata } from '../types'; + +const metadata: Readonly = Object.freeze({ + name: 'WordPress', + description: 'Integrate Logto into your WordPress app.', + target: ApplicationType.Traditional, + fullGuide: { + title: 'Authorization and role mapping in WordPress', + url: 'https://blog.logto.io/integrate-with-wordpress-authorization/', + }, +}); + +export default metadata; diff --git a/packages/console/src/assets/docs/guides/web-wordpress/logo.svg b/packages/console/src/assets/docs/guides/web-wordpress/logo.svg new file mode 100644 index 00000000000..72183e90424 --- /dev/null +++ b/packages/console/src/assets/docs/guides/web-wordpress/logo.svg @@ -0,0 +1 @@ + \ No newline at end of file From 8b74832f740ec09249235d530ec5a1b1b597ce20 Mon Sep 17 00:00:00 2001 From: Gao Sun Date: Mon, 13 May 2024 16:24:28 +0800 Subject: [PATCH 378/687] ci: use default runner (#5848) --- .github/workflows/alteration-compatibility-integration-test.yml | 2 +- .github/workflows/integration-test.yml | 2 +- .github/workflows/main.yml | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/alteration-compatibility-integration-test.yml b/.github/workflows/alteration-compatibility-integration-test.yml index f245b8c5c5e..2b06b877c93 100644 --- a/.github/workflows/alteration-compatibility-integration-test.yml +++ b/.github/workflows/alteration-compatibility-integration-test.yml @@ -46,7 +46,7 @@ jobs: package: needs: check-alteration-changes - runs-on: buildjet-4vcpu-ubuntu-2204 + runs-on: ubuntu-latest if: ${{needs.check-alteration-changes.outputs.has-alteration-changes == 'true'}} env: INTEGRATION_TEST: true diff --git a/.github/workflows/integration-test.yml b/.github/workflows/integration-test.yml index db27f49c963..0fd1557dbd8 100644 --- a/.github/workflows/integration-test.yml +++ b/.github/workflows/integration-test.yml @@ -13,7 +13,7 @@ concurrency: jobs: package: - runs-on: buildjet-4vcpu-ubuntu-2204 + runs-on: ubuntu-latest env: INTEGRATION_TEST: true diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index be545c5bfa3..dc43d495dcc 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -51,7 +51,7 @@ jobs: run: pnpm ci:stylelint main-test: - runs-on: buildjet-4vcpu-ubuntu-2204 + runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 From 5acd7ef8cb70d68a9f36e48be47209c505d592f2 Mon Sep 17 00:00:00 2001 From: simeng-li Date: Mon, 13 May 2024 16:49:09 +0800 Subject: [PATCH 379/687] refactor(core, schemas): update interaction webhook middleware using contextManager (#5834) * feat(core): update interaction webhook middleware using contextManager updaet interaction webhook middleware using contextManager * fix(test): fix ut fix ut * refactor(core, schemas): refactor DataHook context structure refactor DataHook context structure * fix(core): fix demo-app application not found error fix demo-app application not found error * chore(core): update comments update comments --- .../src/libraries/hook/context-manager.ts | 59 ++++++++++++--- .../core/src/libraries/hook/index.test.ts | 71 +++++++++++++++--- packages/core/src/libraries/hook/index.ts | 47 +++++++----- packages/core/src/libraries/hook/type.ts | 74 +++++++++++++++++++ packages/core/src/libraries/hook/types.ts | 28 ------- packages/core/src/libraries/hook/utils.ts | 3 +- .../koa-management-api-hooks.test.ts | 17 ++--- .../middleware/koa-management-api-hooks.ts | 29 +++++--- .../middleware/koa-interaction-hooks.ts | 45 ++++------- .../tests/api/hook/hook.trigger.data.test.ts | 2 +- packages/schemas/src/types/hook.ts | 41 +--------- 11 files changed, 257 insertions(+), 159 deletions(-) create mode 100644 packages/core/src/libraries/hook/type.ts delete mode 100644 packages/core/src/libraries/hook/types.ts diff --git a/packages/core/src/libraries/hook/context-manager.ts b/packages/core/src/libraries/hook/context-manager.ts index cb38a83e93d..b4ac5f6f7cf 100644 --- a/packages/core/src/libraries/hook/context-manager.ts +++ b/packages/core/src/libraries/hook/context-manager.ts @@ -1,24 +1,65 @@ -import { type DataHookEvent } from '@logto/schemas'; +import { InteractionEvent, InteractionHookEvent, type DataHookEvent } from '@logto/schemas'; +import { type Optional } from '@silverhand/essentials'; -type DataHookContext = { - event: DataHookEvent; - data?: Record; -}; +import type { InteractionApiMetadata, ManagementApiContext } from './type.js'; type DataHookMetadata = { userAgent?: string; ip: string; -}; +} & Partial; + +type DataHookContext = { + event: DataHookEvent; + /** Data details */ + data?: unknown; +} & Partial; export class DataHookContextManager { contextArray: DataHookContext[] = []; constructor(public metadata: DataHookMetadata) {} - appendContext({ event, data }: DataHookContext) { + appendContext(context: DataHookContext) { // eslint-disable-next-line @silverhand/fp/no-mutating-methods - this.contextArray.push({ event, data }); + this.contextArray.push(context); } } -// TODO: @simeng-li migrate the current interaction hook context using hook context manager +type InteractionHookMetadata = { + userAgent?: string; + userIp?: string; +} & InteractionApiMetadata; + +/** + * The interaction hook result for triggering interaction hooks by `triggerInteractionHooks`. + * In the `koaInteractionHooks` middleware, + * if we get an interaction hook result after the interaction is processed, related hooks will be triggered. + */ +export type InteractionHookResult = { + userId: string; +}; + +const interactionEventToHookEvent: Record = { + [InteractionEvent.Register]: InteractionHookEvent.PostRegister, + [InteractionEvent.SignIn]: InteractionHookEvent.PostSignIn, + [InteractionEvent.ForgotPassword]: InteractionHookEvent.PostResetPassword, +}; + +export class InteractionHookContextManager { + public interactionHookResult: Optional; + + constructor(public metadata: InteractionHookMetadata) {} + + get hookEvent() { + return interactionEventToHookEvent[this.metadata.interactionEvent]; + } + + /** + * Assign an interaction hook result to trigger webhook. + * Calling it multiple times will overwrite the original result, but only one webhook will be triggered. + * @param result The result to assign. + */ + assignInteractionHookResult(result: InteractionHookResult) { + this.interactionHookResult = result; + } +} diff --git a/packages/core/src/libraries/hook/index.test.ts b/packages/core/src/libraries/hook/index.test.ts index 66a82f539ef..1bf104dd84f 100644 --- a/packages/core/src/libraries/hook/index.test.ts +++ b/packages/core/src/libraries/hook/index.test.ts @@ -6,7 +6,6 @@ import { createMockUtils } from '@logto/shared/esm'; import RequestError from '#src/errors/RequestError/index.js'; import { mockId, mockIdGenerators } from '#src/test-utils/nanoid.js'; -import { DataHookContextManager } from './context-manager.js'; import { generateHookTestPayload, parseResponse } from './utils.js'; const { jest } = import.meta; @@ -60,6 +59,7 @@ const mockHookState = { requestCount: 100, successCount: 10 }; const getHookExecutionStatsByHookId = jest.fn().mockResolvedValue(mockHookState); const findAllHooks = jest.fn().mockResolvedValue([hook, dataHook]); const findHookById = jest.fn().mockResolvedValue(hook); +const findApplicationById = jest.fn().mockResolvedValue({ id: 'app_id', extraField: 'not_ok' }); const { createHookLibrary } = await import('./index.js'); const { triggerInteractionHooks, triggerTestHook, triggerDataHooks } = createHookLibrary( @@ -72,13 +72,17 @@ const { triggerInteractionHooks, triggerTestHook, triggerDataHooks } = createHoo }), }, applications: { - findApplicationById: jest.fn().mockResolvedValue({ id: 'app_id', extraField: 'not_ok' }), + findApplicationById, }, logs: { insertLog, getHookExecutionStatsByHookId }, hooks: { findAllHooks, findHookById }, }) ); +const { DataHookContextManager, InteractionHookContextManager } = await import( + './context-manager.js' +); + describe('triggerInteractionHooks()', () => { afterEach(() => { jest.clearAllMocks(); @@ -87,20 +91,27 @@ describe('triggerInteractionHooks()', () => { it('should set correct payload when hook triggered', async () => { jest.useFakeTimers().setSystemTime(100_000); - await triggerInteractionHooks( - new ConsoleLog(), - { event: InteractionEvent.SignIn, sessionId: 'some_jti', applicationId: 'some_client' }, - { userId: '123' } - ); + const interactionHookContext = new InteractionHookContextManager({ + interactionEvent: InteractionEvent.SignIn, + applicationId: 'some_client', + sessionId: 'some_jti', + }); + + interactionHookContext.assignInteractionHookResult({ + userId: '123', + }); + + await triggerInteractionHooks(new ConsoleLog(), interactionHookContext); expect(findAllHooks).toHaveBeenCalled(); + expect(findApplicationById).toHaveBeenCalledWith('some_client'); expect(sendWebhookRequest).toHaveBeenCalledWith({ hookConfig: hook.config, payload: { hookId: 'foo', event: 'PostSignIn', interactionEvent: 'SignIn', - sessionId: 'some_jti', + sessionId: interactionHookContext.metadata.sessionId, userId: '123', user: { id: 'user_id', username: 'user' }, application: { id: 'app_id' }, @@ -180,22 +191,22 @@ describe('triggerDataHooks()', () => { jest.clearAllMocks(); }); - it('should set correct payload when hook triggered', async () => { + it('should set correct payload when hook triggered by management API', async () => { jest.useFakeTimers().setSystemTime(100_000); const metadata = { userAgent: 'ua', ip: 'ip' }; - const hookData = { path: '/test', method: 'POST', body: { success: true } }; + const hookData = { path: '/test', method: 'POST', data: { success: true } }; const hooksManager = new DataHookContextManager(metadata); hooksManager.appendContext({ event: 'Role.Created', - data: hookData, + ...hookData, }); await triggerDataHooks(new ConsoleLog(), hooksManager); expect(findAllHooks).toHaveBeenCalled(); - + expect(findApplicationById).not.toHaveBeenCalled(); expect(sendWebhookRequest).toHaveBeenCalledWith({ hookConfig: dataHook.config, payload: { @@ -232,4 +243,40 @@ describe('triggerDataHooks()', () => { jest.useRealTimers(); }); + + it('should set correct payload when hook triggered by interaction API', async () => { + jest.useFakeTimers().setSystemTime(100_000); + + const metadata = { + userAgent: 'ua', + ip: 'ip', + interactionEvent: InteractionEvent.Register, + applicationId: 'some_client', + sessionId: 'some_jti', + }; + + const hooksManager = new DataHookContextManager(metadata); + + hooksManager.appendContext({ + event: 'Role.Created', + data: { id: 'user_id', username: 'user' }, + }); + + await triggerDataHooks(new ConsoleLog(), hooksManager); + + expect(findAllHooks).toHaveBeenCalled(); + expect(findApplicationById).toHaveBeenCalledWith('some_client'); + expect(sendWebhookRequest).toHaveBeenCalledWith({ + hookConfig: dataHook.config, + payload: { + hookId: 'foo', + event: 'Role.Created', + createdAt: new Date(100_000).toISOString(), + data: { id: 'user_id', username: 'user' }, + ...metadata, + application: { id: 'app_id' }, + }, + signingKey: dataHook.signingKey, + }); + }); }); diff --git a/packages/core/src/libraries/hook/index.ts b/packages/core/src/libraries/hook/index.ts index b7634e72af6..c76f4eb1883 100644 --- a/packages/core/src/libraries/hook/index.ts +++ b/packages/core/src/libraries/hook/index.ts @@ -1,13 +1,10 @@ import { LogResult, userInfoSelectFields, - type DataHookEventPayload, type Hook, type HookConfig, type HookEvent, - type HookEventPayload, type HookTestErrorResponseData, - type InteractionHookEventPayload, } from '@logto/schemas'; import { generateStandardId, normalizeError, type ConsoleLog } from '@logto/shared'; import { conditional, pick, trySafe } from '@silverhand/essentials'; @@ -18,12 +15,15 @@ import RequestError from '#src/errors/RequestError/index.js'; import { LogEntry } from '#src/middleware/koa-audit-log.js'; import type Queries from '#src/tenants/Queries.js'; -import { type DataHookContextManager } from './context-manager.js'; import { - interactionEventToHookEvent, - type InteractionHookContext, - type InteractionHookResult, -} from './types.js'; + type DataHookContextManager, + type InteractionHookContextManager, +} from './context-manager.js'; +import type { + DataHookEventPayload, + HookEventPayload, + InteractionHookEventPayload, +} from './type.js'; import { generateHookTestPayload, parseResponse, sendWebhookRequest } from './utils.js'; type BetterOmit = { @@ -103,15 +103,19 @@ export const createHookLibrary = (queries: Queries) => { */ const triggerInteractionHooks = async ( consoleLog: ConsoleLog, - interactionContext: InteractionHookContext, - interactionResult: InteractionHookResult, - userAgent?: string + contextManager: InteractionHookContextManager ) => { - const { userId } = interactionResult; - const { event, sessionId, applicationId, userIp } = interactionContext; + if (!contextManager.interactionHookResult) { + return; + } + + const { interactionEvent, sessionId, applicationId, userIp, userAgent } = + contextManager.metadata; + const { userId } = contextManager.interactionHookResult; + const { hookEvent } = contextManager; - const hookEvent = interactionEventToHookEvent[event]; const found = await findAllHooks(); + const hooks = found.filter( ({ event, events, enabled }) => enabled && (events.length > 0 ? events.includes(hookEvent) : event === hookEvent) // For backward compatibility @@ -128,7 +132,7 @@ export const createHookLibrary = (queries: Queries) => { const payload = { event: hookEvent, - interactionEvent: event, + interactionEvent, createdAt: new Date().toISOString(), sessionId, userAgent, @@ -157,8 +161,14 @@ export const createHookLibrary = (queries: Queries) => { const found = await findAllHooks(); + // Fetch application detail if available + const { applicationId } = contextManager.metadata; + const application = applicationId + ? await trySafe(async () => findApplicationById(applicationId)) + : undefined; + // Filter hooks that match each events - const webhooks = contextManager.contextArray.flatMap(({ event, data }) => { + const webhooks = contextManager.contextArray.flatMap(({ event, ...rest }) => { const hooks = found.filter( ({ event: hookEvent, events, enabled }) => enabled && (events.length > 0 ? events.includes(event) : event === hookEvent) @@ -168,7 +178,10 @@ export const createHookLibrary = (queries: Queries) => { event, createdAt: new Date().toISOString(), ...contextManager.metadata, - ...data, + ...conditional( + application && { application: pick(application, 'id', 'type', 'name', 'description') } + ), + ...rest, } satisfies BetterOmit; return hooks.map((hook) => ({ hook, payload })); diff --git a/packages/core/src/libraries/hook/type.ts b/packages/core/src/libraries/hook/type.ts new file mode 100644 index 00000000000..a8c494c4ced --- /dev/null +++ b/packages/core/src/libraries/hook/type.ts @@ -0,0 +1,74 @@ +import { + type Application, + type DataHookEvent, + type InteractionEvent, + type InteractionHookEvent, + type User, + type userInfoSelectFields, +} from '@logto/schemas'; + +/** + * The interaction API context for triggering InteractionHook and DataHook events. + * In the `koaInteractionHooks` middleware, + * we will store the context before processing the interaction and consume it after the interaction is processed if needed. + */ +export type InteractionApiMetadata = { + /** The application ID if the hook is triggered by interaction API. */ + applicationId?: string; + /** The session ID if the hook is triggered by interaction API. */ + sessionId?: string; + /** The InteractionEvent if the hook is triggered by interaction API. */ + interactionEvent: InteractionEvent; +}; + +type InteractionApiContextPayload = { + /** Fetch application detail by application ID before sending the hook event */ + application?: Pick; + sessionId?: string; + interactionEvent?: InteractionEvent; +}; + +export type InteractionHookEventPayload = { + event: InteractionHookEvent; + createdAt: string; + hookId: string; + userAgent?: string; + userIp?: string; + /** InteractionHook result */ + userId?: string; + /** Fetch user detail by user ID before sending the hook event */ + user?: Pick; +} & InteractionApiContextPayload & + Record; + +/** + * The API context for management API triggered data hooks. + * In the `koaManagementApiHooks` middleware, + * we will store the context of management API requests that triggers the DataHook events. + * Can't put it in the DataHookMetadata because the matched API context is only available after the request is processed. + */ +export type ManagementApiContext = { + /** Request route params. */ + params?: Record; + /** Request route path. */ + path: string; + /** Matched route used as the identifier to trigger the hook. */ + matchedRoute?: string; + /** Request method. */ + method: string; + /** Response status code. */ + status: number; +}; + +export type DataHookEventPayload = { + event: DataHookEvent; + createdAt: string; + hookId: string; + ip?: string; + userAgent?: string; + data?: unknown; +} & Partial & + Partial & + Record; + +export type HookEventPayload = InteractionHookEventPayload | DataHookEventPayload; diff --git a/packages/core/src/libraries/hook/types.ts b/packages/core/src/libraries/hook/types.ts deleted file mode 100644 index f7721de0d26..00000000000 --- a/packages/core/src/libraries/hook/types.ts +++ /dev/null @@ -1,28 +0,0 @@ -import { InteractionEvent, InteractionHookEvent } from '@logto/schemas'; - -/** - * The context for triggering interaction hooks by `triggerInteractionHooks`. - * In the `koaInteractionHooks` middleware, - * we will store the context before processing the interaction and consume it after the interaction is processed if needed. - */ -export type InteractionHookContext = { - event: InteractionEvent; - sessionId?: string; - applicationId?: string; - userIp?: string; -}; - -/** - * The interaction hook result for triggering interaction hooks by `triggerInteractionHooks`. - * In the `koaInteractionHooks` middleware, - * if we get an interaction hook result after the interaction is processed, related hooks will be triggered. - */ -export type InteractionHookResult = { - userId: string; -}; - -export const interactionEventToHookEvent: Record = { - [InteractionEvent.Register]: InteractionHookEvent.PostRegister, - [InteractionEvent.SignIn]: InteractionHookEvent.PostSignIn, - [InteractionEvent.ForgotPassword]: InteractionHookEvent.PostResetPassword, -}; diff --git a/packages/core/src/libraries/hook/utils.ts b/packages/core/src/libraries/hook/utils.ts index e28732f1a2f..225527f6aae 100644 --- a/packages/core/src/libraries/hook/utils.ts +++ b/packages/core/src/libraries/hook/utils.ts @@ -3,7 +3,6 @@ import { managementApiHooksRegistration, type HookConfig, type HookEvent, - type HookEventPayload, } from '@logto/schemas'; import { conditional, trySafe } from '@silverhand/essentials'; import { type IRouterParamContext } from 'koa-router'; @@ -11,6 +10,8 @@ import ky, { type KyResponse } from 'ky'; import { sign } from '#src/utils/sign.js'; +import { type HookEventPayload } from './type.js'; + export const parseResponse = async (response: KyResponse) => { const body = await response.text(); return { diff --git a/packages/core/src/middleware/koa-management-api-hooks.test.ts b/packages/core/src/middleware/koa-management-api-hooks.test.ts index 2703d88e048..73f316aa137 100644 --- a/packages/core/src/middleware/koa-management-api-hooks.test.ts +++ b/packages/core/src/middleware/koa-management-api-hooks.test.ts @@ -46,6 +46,7 @@ describe('koaManagementApiHooks', () => { expect(triggerDataHooks).toBeCalledWith( expect.any(ConsoleLog), expect.objectContaining({ + metadata: { userAgent: ctx.header['user-agent'], ip: ctx.ip }, contextArray: [ { event: 'Role.Created', @@ -89,16 +90,12 @@ describe('koaManagementApiHooks', () => { contextArray: [ { event, - data: { - path: route, - method, - response: { - body: { key }, - }, - params: ctxParams.params, - matchedRoute: route, - status: 200, - }, + data: { key }, + path: route, + method, + params: ctxParams.params, + matchedRoute: route, + status: 200, }, ], }) diff --git a/packages/core/src/middleware/koa-management-api-hooks.ts b/packages/core/src/middleware/koa-management-api-hooks.ts index c1a949afda4..b58737991f0 100644 --- a/packages/core/src/middleware/koa-management-api-hooks.ts +++ b/packages/core/src/middleware/koa-management-api-hooks.ts @@ -38,17 +38,16 @@ export const koaManagementApiHooks = 0) { + // Trigger data hooks + if (dataHooksContextManager.contextArray.length > 0) { // Hooks should not crash the app - void trySafe(hooks.triggerDataHooks(getConsoleLogFromContext(ctx), dataHooks)); + void trySafe(hooks.triggerDataHooks(getConsoleLogFromContext(ctx), dataHooksContextManager)); } }; }; diff --git a/packages/core/src/routes/interaction/middleware/koa-interaction-hooks.ts b/packages/core/src/routes/interaction/middleware/koa-interaction-hooks.ts index 2f0a5d96dd1..d9518c03486 100644 --- a/packages/core/src/routes/interaction/middleware/koa-interaction-hooks.ts +++ b/packages/core/src/routes/interaction/middleware/koa-interaction-hooks.ts @@ -1,11 +1,11 @@ -import { conditionalString, trySafe, type Optional } from '@silverhand/essentials'; +import { conditionalString, trySafe } from '@silverhand/essentials'; import type { MiddlewareType } from 'koa'; import type { IRouterParamContext } from 'koa-router'; import { - type InteractionHookContext, + InteractionHookContextManager, type InteractionHookResult, -} from '#src/libraries/hook/types.js'; +} from '#src/libraries/hook/context-manager.js'; import type Libraries from '#src/tenants/Libraries.js'; import { getConsoleLogFromContext } from '#src/utils/console.js'; @@ -32,7 +32,7 @@ export default function koaInteractionHooks< hooks: { triggerInteractionHooks }, }: Libraries): MiddlewareType, ResponseT> { return async (ctx, next) => { - const { event } = getInteractionStorage(ctx.interactionDetails.result); + const { event: interactionEvent } = getInteractionStorage(ctx.interactionDetails.result); const { interactionDetails, @@ -40,41 +40,24 @@ export default function koaInteractionHooks< ip, } = ctx; - // Predefined interaction hook context - const interactionHookContext: InteractionHookContext = { - event, - sessionId: interactionDetails.jti, - applicationId: conditionalString(interactionDetails.params.client_id), + const interactionHookContext = new InteractionHookContextManager({ + interactionEvent, + userAgent, userIp: ip, - }; - - // eslint-disable-next-line @silverhand/fp/no-let - let interactionHookResult: Optional; + applicationId: conditionalString(interactionDetails.params.client_id), + sessionId: interactionDetails.jti, + }); - /** - * Assign an interaction hook result to trigger webhook. - * Calling it multiple times will overwrite the original result, but only one webhook will be triggered. - * @param result The result to assign. - */ - ctx.assignInteractionHookResult = (result) => { - // eslint-disable-next-line @silverhand/fp/no-mutation - interactionHookResult = result; - }; + ctx.assignInteractionHookResult = + interactionHookContext.assignInteractionHookResult.bind(interactionHookContext); // TODO: @simeng-li Add DataHookContext to the interaction hook middleware as well await next(); - if (interactionHookResult) { + if (interactionHookContext.interactionHookResult) { // Hooks should not crash the app - void trySafe( - triggerInteractionHooks( - getConsoleLogFromContext(ctx), - interactionHookContext, - interactionHookResult, - userAgent - ) - ); + void trySafe(triggerInteractionHooks(getConsoleLogFromContext(ctx), interactionHookContext)); } }; } diff --git a/packages/integration-tests/src/tests/api/hook/hook.trigger.data.test.ts b/packages/integration-tests/src/tests/api/hook/hook.trigger.data.test.ts index 37981329046..d744c0e44ed 100644 --- a/packages/integration-tests/src/tests/api/hook/hook.trigger.data.test.ts +++ b/packages/integration-tests/src/tests/api/hook/hook.trigger.data.test.ts @@ -36,7 +36,7 @@ const mockHookResponseGuard = z.object({ event: hookEventGuard, createdAt: z.string(), hookId: z.string(), - body: jsonGuard.optional(), + data: jsonGuard.optional(), method: z .string() .optional() diff --git a/packages/schemas/src/types/hook.ts b/packages/schemas/src/types/hook.ts index 8c81792406a..42c0851de0f 100644 --- a/packages/schemas/src/types/hook.ts +++ b/packages/schemas/src/types/hook.ts @@ -1,45 +1,6 @@ import { z } from 'zod'; -import { Hooks, type Application, type User } from '../db-entries/index.js'; -import { type DataHookEvent, type InteractionHookEvent } from '../foundations/index.js'; - -import type { userInfoSelectFields } from './user.js'; - -export type InteractionHookEventPayload = { - event: InteractionHookEvent; - createdAt: string; - hookId: string; - sessionId?: string; - userAgent?: string; - userId?: string; - userIp?: string; - user?: Pick; - application?: Pick; -} & Record; - -export type DataHookEventPayload = { - event: DataHookEvent; - createdAt: string; - hookId: string; - ip?: string; - userAgent?: string; - /** An object that contains response data. */ - response?: { - body?: Record; - }; - /** Request route params. */ - params?: Record; - /** Request route path. */ - path?: string; - /** Matched route used as the identifier to trigger the hook. */ - matchedRoute?: string; - /** Response status code. */ - status?: number; - /** Request method. */ - method?: string; -} & Record; - -export type HookEventPayload = InteractionHookEventPayload | DataHookEventPayload; +import { Hooks } from '../db-entries/index.js'; const hookExecutionStatsGuard = z.object({ successCount: z.number(), From 1fdd28b2b31e5ca4f57467905551a3063cd6d9b2 Mon Sep 17 00:00:00 2001 From: Xiao Yijun Date: Mon, 13 May 2024 17:06:04 +0800 Subject: [PATCH 380/687] chore: build oauth2 connector on prepack (#5855) --- .github/workflows/main.yml | 4 ---- .github/workflows/upload-annotations.yml | 4 ---- .scripts/publish.js | 4 ---- packages/connectors/connector-oauth2/package.json | 3 ++- packages/connectors/templates/sync-preset.js | 4 +++- 5 files changed, 5 insertions(+), 14 deletions(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index dc43d495dcc..2bd1a72767d 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -40,10 +40,6 @@ jobs: - name: Prepack run: pnpm prepack - # Build connectors before running lint since some connectors rely on the generated types - - name: Build connectors - run: pnpm connectors build - - name: Lint run: pnpm ci:lint diff --git a/.github/workflows/upload-annotations.yml b/.github/workflows/upload-annotations.yml index eba88c96325..835c8fd07ba 100644 --- a/.github/workflows/upload-annotations.yml +++ b/.github/workflows/upload-annotations.yml @@ -29,10 +29,6 @@ jobs: - name: Prepack run: pnpm prepack - # Build connectors before running lint since some connectors rely on the generated types - - name: Build connectors - run: pnpm connectors build - - name: Lint with Report run: pnpm -r --parallel lint:report && node .scripts/merge-eslint-reports.js diff --git a/.scripts/publish.js b/.scripts/publish.js index 77dec0d57ad..e47612dc4f3 100644 --- a/.scripts/publish.js +++ b/.scripts/publish.js @@ -52,10 +52,6 @@ if (taggedPackages.length === 0) { try { execSync('pnpm prepack'); - /** - * Build connectors before publish since some connectors rely on the generated types from oauth2 connector package. - */ - execSync('pnpm connectors build'); execSync('pnpm -r publish'); execSync('git push --follow-tags'); } catch (error) { diff --git a/packages/connectors/connector-oauth2/package.json b/packages/connectors/connector-oauth2/package.json index f360e9382ec..d05c0b6a969 100644 --- a/packages/connectors/connector-oauth2/package.json +++ b/packages/connectors/connector-oauth2/package.json @@ -33,7 +33,8 @@ "lint:report": "pnpm lint --format json --output-file report.json", "test": "vitest src", "test:ci": "pnpm run test --silent --coverage", - "prepublishOnly": "pnpm build" + "prepublishOnly": "pnpm build", + "prepack": "pnpm build" }, "engines": { "node": "^20.9.0" diff --git a/packages/connectors/templates/sync-preset.js b/packages/connectors/templates/sync-preset.js index 65225ca181d..32460417652 100644 --- a/packages/connectors/templates/sync-preset.js +++ b/packages/connectors/templates/sync-preset.js @@ -17,8 +17,10 @@ const templateKeys = Object.keys(templateJson); /** * An object that contains exceptions for scripts that are allowed to be different from the template. + * Value format: `{ "": [""] }` + * Example: `{ "connector-oauth2": ["prepack"] }` */ -const scriptExceptions = {}; +const scriptExceptions = { 'connector-oauth2': ['prepack'] }; const sync = async () => { const packagesDirectory = './'; From 062d21764c9db33247528fd034f3befd0a4b182f Mon Sep 17 00:00:00 2001 From: wangsijie Date: Mon, 13 May 2024 21:04:18 +0800 Subject: [PATCH 381/687] chore(core): add custom domain host to app insights (#5852) --- packages/core/src/utils/request.ts | 20 ++++++++++++++++---- packages/core/src/utils/test-utils.ts | 1 + 2 files changed, 17 insertions(+), 4 deletions(-) diff --git a/packages/core/src/utils/request.ts b/packages/core/src/utils/request.ts index 73c27ed8c13..86215a76f10 100644 --- a/packages/core/src/utils/request.ts +++ b/packages/core/src/utils/request.ts @@ -1,21 +1,33 @@ import { type ExceptionTelemetry } from '@logto/app-insights/node'; +import { type Context } from 'koa'; // eslint-disable-next-line @typescript-eslint/ban-types const getRequestIdFromContext = (context: object): string | undefined => { if ('requestId' in context && typeof context.requestId === 'string') { return context.requestId; } +}; - return undefined; +const getHostFromContext = (context: Context): string | undefined => { + if ('host' in context.headers && typeof context.headers.host === 'string') { + return context.headers.host; + } }; // eslint-disable-next-line @typescript-eslint/ban-types export const buildAppInsightsTelemetry = (context: object): Partial => { const requestId = getRequestIdFromContext(context); + // eslint-disable-next-line no-restricted-syntax + const host = getHostFromContext(context as Context); - if (requestId) { - return { properties: { requestId } }; + if (!requestId && !host) { + return {}; } - return {}; + return { + properties: { + ...(requestId ? { requestId } : {}), + ...(host ? { host } : {}), + }, + }; }; diff --git a/packages/core/src/utils/test-utils.ts b/packages/core/src/utils/test-utils.ts index 98ea31c5ace..6a0a1be408d 100644 --- a/packages/core/src/utils/test-utils.ts +++ b/packages/core/src/utils/test-utils.ts @@ -97,6 +97,7 @@ export const createContextWithRouteParameters = ( path: ctx.path, URL: ctx.URL, params: {}, + headers: {}, router: new Router(), _matchedRoute: undefined, _matchedRouteName: undefined, From f020c5984ca2b1aeb5a42f51e4aeb1c440515836 Mon Sep 17 00:00:00 2001 From: simeng-li Date: Tue, 14 May 2024 14:05:52 +0800 Subject: [PATCH 382/687] fix(core): add devFeature guard for DataHooks (#5861) fix(core): add devFeature guard add devFeature guard --- .../core/src/middleware/koa-management-api-hooks.ts | 2 +- packages/core/src/routes/hook.ts | 12 +++++++++++- .../schemas/src/foundations/jsonb-types/hooks.ts | 2 ++ 3 files changed, 14 insertions(+), 2 deletions(-) diff --git a/packages/core/src/middleware/koa-management-api-hooks.ts b/packages/core/src/middleware/koa-management-api-hooks.ts index b58737991f0..adc55c207b8 100644 --- a/packages/core/src/middleware/koa-management-api-hooks.ts +++ b/packages/core/src/middleware/koa-management-api-hooks.ts @@ -30,7 +30,7 @@ export const koaManagementApiHooks = deduplicate(events)); @@ -159,6 +167,8 @@ export default function hookRoutes( koaQuotaGuard({ key: 'hooksLimit', quota }), koaGuard({ body: Hooks.createGuard.omit({ id: true, signingKey: true }).extend({ + // TODO: remove dev features guard + event: (isDevFeaturesEnabled ? hookEventGuard : interactionHookEventGuard).optional(), events: nonemptyUniqueHookEventsGuard.optional(), }), response: Hooks.guard, diff --git a/packages/schemas/src/foundations/jsonb-types/hooks.ts b/packages/schemas/src/foundations/jsonb-types/hooks.ts index 6c014b23dc0..87746a3bff4 100644 --- a/packages/schemas/src/foundations/jsonb-types/hooks.ts +++ b/packages/schemas/src/foundations/jsonb-types/hooks.ts @@ -82,6 +82,8 @@ export const hookEventsGuard = hookEventGuard.array(); export type HookEvents = z.infer; +export const interactionHookEventGuard = z.nativeEnum(InteractionHookEvent); + /** * Hook configuration for web hook. */ From 304d948511f689bce1d13304ebed3153e05d5042 Mon Sep 17 00:00:00 2001 From: Gao Sun Date: Tue, 14 May 2024 14:12:07 +0800 Subject: [PATCH 383/687] refactor(core): update first admin user preconditions (#5858) --- .../routes/interaction/actions/submit-interaction.ts | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/packages/core/src/routes/interaction/actions/submit-interaction.ts b/packages/core/src/routes/interaction/actions/submit-interaction.ts index 0abf8690c14..a16cea0275a 100644 --- a/packages/core/src/routes/interaction/actions/submit-interaction.ts +++ b/packages/core/src/routes/interaction/actions/submit-interaction.ts @@ -86,6 +86,7 @@ const getInitialUserRoles = ( isCreatingFirstAdminUser && !isCloud && defaultManagementApiAdminName // OSS uses the legacy Management API user role ); +// eslint-disable-next-line complexity -- @simeng refactor me async function handleSubmitRegister( interaction: VerifiedRegisterInteractionResult, ctx: WithLogContext & WithInteractionDetailsContext & WithInteractionHooksContext, @@ -113,8 +114,15 @@ async function handleSubmitRegister( const { isCloud } = EnvSet.values; const [currentTenantId] = await getTenantId(ctx.URL); const isInAdminTenant = currentTenantId === adminTenantId; + /** + * Only allow creating the first admin user when it's in OSS or integration tests to avoid + * security issues. + */ const isCreatingFirstAdminUser = - isInAdminTenant && String(client_id) === adminConsoleApplicationId && !(await hasActiveUsers()); + (!EnvSet.values.isCloud || EnvSet.values.isIntegrationTest) && + isInAdminTenant && + String(client_id) === adminConsoleApplicationId && + !(await hasActiveUsers()); // If it's Logto Cloud, Check if the new user has any pending invitations, if yes, skip onboarding flow. const invitations = From 1c414f18899f32da709f515a862cd542faddf42f Mon Sep 17 00:00:00 2001 From: wangsijie Date: Tue, 14 May 2024 15:24:49 +0800 Subject: [PATCH 384/687] fix(core): fix consent scopes filter rule for non-3rd-party app (#5859) --- .../src/routes/interaction/consent/utils.ts | 25 +++++---- .../happy-path.test.ts | 53 +++++++++++++++++++ 2 files changed, 68 insertions(+), 10 deletions(-) rename packages/integration-tests/src/tests/api/interaction/{third-party-sign-in => consent}/happy-path.test.ts (87%) diff --git a/packages/core/src/routes/interaction/consent/utils.ts b/packages/core/src/routes/interaction/consent/utils.ts index f8f258681cd..166be829a19 100644 --- a/packages/core/src/routes/interaction/consent/utils.ts +++ b/packages/core/src/routes/interaction/consent/utils.ts @@ -5,6 +5,7 @@ import { errors } from 'oidc-provider'; import { filterResourceScopesForTheThirdPartyApplication, findResourceScopes, + isThirdPartyApplication, } from '#src/oidc/resource.js'; import type Libraries from '#src/tenants/Libraries.js'; import type Queries from '#src/tenants/Queries.js'; @@ -118,19 +119,23 @@ export const filterAndParseMissingResourceScopes = async ({ organizationId, }); + const isThirdPartyApp = await isThirdPartyApplication(queries, applicationId); + // Filter the scopes for the third-party application. // Although the "missingResourceScopes" from the prompt details are already filtered, // there may be duplicated scopes from either resources or organization resources. - const filteredScopes = await filterResourceScopesForTheThirdPartyApplication( - libraries, - applicationId, - resourceIndicator, - scopes, - { - includeOrganizationResourceScopes: Boolean(organizationId), - includeResourceScopes: !organizationId, - } - ); + const filteredScopes = isThirdPartyApp + ? await filterResourceScopesForTheThirdPartyApplication( + libraries, + applicationId, + resourceIndicator, + scopes, + { + includeOrganizationResourceScopes: Boolean(organizationId), + includeResourceScopes: !organizationId, + } + ) + : scopes; return [ resourceIndicator, diff --git a/packages/integration-tests/src/tests/api/interaction/third-party-sign-in/happy-path.test.ts b/packages/integration-tests/src/tests/api/interaction/consent/happy-path.test.ts similarity index 87% rename from packages/integration-tests/src/tests/api/interaction/third-party-sign-in/happy-path.test.ts rename to packages/integration-tests/src/tests/api/interaction/consent/happy-path.test.ts index 1d9ebea3121..fc51bcb6bf9 100644 --- a/packages/integration-tests/src/tests/api/interaction/third-party-sign-in/happy-path.test.ts +++ b/packages/integration-tests/src/tests/api/interaction/consent/happy-path.test.ts @@ -8,6 +8,7 @@ import { createApplication, deleteApplication } from '#src/api/application.js'; import { consent, getConsentInfo, putInteraction } from '#src/api/interaction.js'; import { OrganizationScopeApi } from '#src/api/organization-scope.js'; import { createResource, deleteResource } from '#src/api/resource.js'; +import { assignUsersToRole, createRole, deleteRole } from '#src/api/role.js'; import { createScope } from '#src/api/scope.js'; import { initClient } from '#src/helpers/client.js'; import { OrganizationApiTest, OrganizationRoleApiTest } from '#src/helpers/organization.js'; @@ -24,6 +25,7 @@ import { describe('consent api', () => { const applications = new Map(); const thirdPartyApplicationName = 'consent-third-party-app'; + const firstPartyApplicationName = 'consent-first-party-app'; const redirectUri = 'http://example.com'; const bootStrapApplication = async () => { @@ -39,7 +41,20 @@ describe('consent api', () => { } ); + const firstPartyApplication = await createApplication( + firstPartyApplicationName, + ApplicationType.Traditional, + { + isThirdParty: false, + oidcClientMetadata: { + redirectUris: [redirectUri], + postLogoutRedirectUris: [], + }, + } + ); + applications.set(thirdPartyApplicationName, thirdPartyApplication); + applications.set(firstPartyApplicationName, firstPartyApplication); await assignUserConsentScopes(thirdPartyApplication.id, { userScopes: [UserScope.Profile], @@ -253,6 +268,44 @@ describe('consent api', () => { }); describe('submit consent info', () => { + it('should not affect first party app', async () => { + const application = applications.get(firstPartyApplicationName); + assert(application, new Error('application.not_found')); + + const { userProfile, user } = await generateNewUser({ username: true, password: true }); + const resource = await createResource(generateResourceName(), generateResourceIndicator()); + const scope = await createScope(resource.id, generateScopeName()); + const role = await createRole({ name: generateRoleName(), scopeIds: [scope.id] }); + await assignUsersToRole([user.id], role.id); + + const client = await initClient( + { + appId: application.id, + appSecret: application.secret, + // First party app should block the scope, even though it is not assigned to the app + scopes: [UserScope.Profile, scope.name], + resources: [resource.indicator], + }, + redirectUri + ); + + await client.successSend(putInteraction, { + event: InteractionEvent.SignIn, + identifier: { + username: userProfile.username, + password: userProfile.password, + }, + }); + + const { redirectTo } = await client.submitInteraction(); + + await client.processSession(redirectTo); + + await deleteResource(resource.id); + await deleteUser(user.id); + await deleteRole(role.id); + }); + it('should perform manual consent successfully', async () => { const application = applications.get(thirdPartyApplicationName); assert(application, new Error('application.not_found')); From bec2720c7b2a0c4bd1c89d866f4abe38ad8961cd Mon Sep 17 00:00:00 2001 From: Gao Sun Date: Tue, 14 May 2024 15:27:07 +0800 Subject: [PATCH 385/687] refactor(console): do not parameterize guide id (#5863) --- packages/console/src/utils/route.ts | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/packages/console/src/utils/route.ts b/packages/console/src/utils/route.ts index 1afaa57a9ef..04e536ab7af 100644 --- a/packages/console/src/utils/route.ts +++ b/packages/console/src/utils/route.ts @@ -18,7 +18,11 @@ export const getRoutePattern = (pathname: string, routes: RouteObject[]) => { } // If the path is not a parameter, or it's an ID parameter, use the path as is. - if (!segment.startsWith(':') || segment.endsWith('Id') || segment.endsWith('id')) { + // Exception: For `:guideId`, we want to use the parameter value for better analytics. + if ( + segment !== ':guideId' && + (!segment.startsWith(':') || segment.endsWith('Id') || segment.endsWith('id')) + ) { return segment; } From 1e24843a2870d2f3f41577fd8d07200d2545b599 Mon Sep 17 00:00:00 2001 From: Xiao Yijun Date: Tue, 14 May 2024 15:46:31 +0800 Subject: [PATCH 386/687] chore(phrases): update organization permission column name (#5864) --- .../integration-tests/src/ui-helpers/expect-organizations.ts | 2 +- .../de/translation/admin-console/organization-template.ts | 2 +- .../en/translation/admin-console/organization-template.ts | 2 +- .../es/translation/admin-console/organization-template.ts | 2 +- .../fr/translation/admin-console/organization-template.ts | 2 +- .../it/translation/admin-console/organization-template.ts | 2 +- .../ja/translation/admin-console/organization-template.ts | 2 +- .../ko/translation/admin-console/organization-template.ts | 2 +- .../pl-pl/translation/admin-console/organization-template.ts | 2 +- .../pt-br/translation/admin-console/organization-template.ts | 2 +- .../pt-pt/translation/admin-console/organization-template.ts | 2 +- .../ru/translation/admin-console/organization-template.ts | 2 +- .../tr-tr/translation/admin-console/organization-template.ts | 2 +- .../zh-cn/translation/admin-console/organization-template.ts | 2 +- .../zh-hk/translation/admin-console/organization-template.ts | 2 +- .../zh-tw/translation/admin-console/organization-template.ts | 2 +- 16 files changed, 16 insertions(+), 16 deletions(-) diff --git a/packages/integration-tests/src/ui-helpers/expect-organizations.ts b/packages/integration-tests/src/ui-helpers/expect-organizations.ts index 742f8df0bb5..53a97c7403f 100644 --- a/packages/integration-tests/src/ui-helpers/expect-organizations.ts +++ b/packages/integration-tests/src/ui-helpers/expect-organizations.ts @@ -153,7 +153,7 @@ export default class ExpectOrganizations extends ExpectConsole { // Click the action button from the permission row await expect(permissionRow).toClick('td:last-of-type button'); - await selectDropdownMenuItem(this.page, 'div[role=menuitem]', 'Delete permission'); + await selectDropdownMenuItem(this.page, 'div[role=menuitem]', 'Delete organization permission'); await this.toExpectModal('Reminder'); await this.toClick(['.ReactModalPortal', `button${cls('danger')}`].join(' '), 'Delete', false); diff --git a/packages/phrases/src/locales/de/translation/admin-console/organization-template.ts b/packages/phrases/src/locales/de/translation/admin-console/organization-template.ts index 3296efcfd0a..d3ced3deb26 100644 --- a/packages/phrases/src/locales/de/translation/admin-console/organization-template.ts +++ b/packages/phrases/src/locales/de/translation/admin-console/organization-template.ts @@ -23,7 +23,7 @@ const organization_template = { tab_name: 'Org Berechtigungen', search_placeholder: 'Nach Berechtigungsnamen suchen', create_org_permission: 'Org Berechtigung erstellen', - permission_column: 'Berechtigung', + permission_column: 'Organisationsberechtigung', description_column: 'Beschreibung', placeholder_title: 'Organisationsberechtigung', placeholder_description: diff --git a/packages/phrases/src/locales/en/translation/admin-console/organization-template.ts b/packages/phrases/src/locales/en/translation/admin-console/organization-template.ts index d89d41136ee..75b47061aa4 100644 --- a/packages/phrases/src/locales/en/translation/admin-console/organization-template.ts +++ b/packages/phrases/src/locales/en/translation/admin-console/organization-template.ts @@ -23,7 +23,7 @@ const organization_template = { tab_name: 'Organization permissions', search_placeholder: 'Search by permission name', create_org_permission: 'Create organization permission', - permission_column: 'Permission', + permission_column: 'Organization permission', description_column: 'Description', placeholder_title: 'Organization permission', placeholder_description: diff --git a/packages/phrases/src/locales/es/translation/admin-console/organization-template.ts b/packages/phrases/src/locales/es/translation/admin-console/organization-template.ts index 82d3ff3105d..4c005db72c5 100644 --- a/packages/phrases/src/locales/es/translation/admin-console/organization-template.ts +++ b/packages/phrases/src/locales/es/translation/admin-console/organization-template.ts @@ -23,7 +23,7 @@ const organization_template = { tab_name: 'Permisos de org', search_placeholder: 'Buscar por nombre de permiso', create_org_permission: 'Crear permiso de org', - permission_column: 'Permiso', + permission_column: 'Permiso de organización', description_column: 'Descripción', placeholder_title: 'Permiso de organización', placeholder_description: diff --git a/packages/phrases/src/locales/fr/translation/admin-console/organization-template.ts b/packages/phrases/src/locales/fr/translation/admin-console/organization-template.ts index 689cb2257e6..595cb5d8385 100644 --- a/packages/phrases/src/locales/fr/translation/admin-console/organization-template.ts +++ b/packages/phrases/src/locales/fr/translation/admin-console/organization-template.ts @@ -23,7 +23,7 @@ const organization_template = { tab_name: 'Permissions org', search_placeholder: 'Rechercher par nom de permission', create_org_permission: 'Créer une permission org', - permission_column: 'Permission', + permission_column: "Permission de l'organisation", description_column: 'Description', placeholder_title: 'Permission d’organisation', placeholder_description: diff --git a/packages/phrases/src/locales/it/translation/admin-console/organization-template.ts b/packages/phrases/src/locales/it/translation/admin-console/organization-template.ts index 2a4c6c88bfc..0458ae65ac9 100644 --- a/packages/phrases/src/locales/it/translation/admin-console/organization-template.ts +++ b/packages/phrases/src/locales/it/translation/admin-console/organization-template.ts @@ -23,7 +23,7 @@ const organization_template = { tab_name: 'Permessi org', search_placeholder: 'Cerca per nome del permesso', create_org_permission: 'Crea permesso org', - permission_column: 'Permesso', + permission_column: "Autorizzazione dell'organizzazione", description_column: 'Descrizione', placeholder_title: 'Permesso di organizzazione', placeholder_description: diff --git a/packages/phrases/src/locales/ja/translation/admin-console/organization-template.ts b/packages/phrases/src/locales/ja/translation/admin-console/organization-template.ts index 562a96eb40e..5a0e3e875d8 100644 --- a/packages/phrases/src/locales/ja/translation/admin-console/organization-template.ts +++ b/packages/phrases/src/locales/ja/translation/admin-console/organization-template.ts @@ -23,7 +23,7 @@ const organization_template = { tab_name: '組織の権限', search_placeholder: '権限名で検索', create_org_permission: '組織の権限を作成', - permission_column: '権限', + permission_column: '組織の許可', description_column: '説明', placeholder_title: '組織の権限', placeholder_description: diff --git a/packages/phrases/src/locales/ko/translation/admin-console/organization-template.ts b/packages/phrases/src/locales/ko/translation/admin-console/organization-template.ts index b5dbf642ccb..ce30d882a87 100644 --- a/packages/phrases/src/locales/ko/translation/admin-console/organization-template.ts +++ b/packages/phrases/src/locales/ko/translation/admin-console/organization-template.ts @@ -23,7 +23,7 @@ const organization_template = { tab_name: '조직 권한', search_placeholder: '권한 이름으로 검색', create_org_permission: '조직 권한 생성', - permission_column: '권한', + permission_column: '조직 권한', description_column: '설명', placeholder_title: '조직 권한', placeholder_description: '조직 권한은 조직의 맥락에서 자원에 접근할 수 있는 권한을 의미합니다.', diff --git a/packages/phrases/src/locales/pl-pl/translation/admin-console/organization-template.ts b/packages/phrases/src/locales/pl-pl/translation/admin-console/organization-template.ts index 9473c82b447..a25565b48ef 100644 --- a/packages/phrases/src/locales/pl-pl/translation/admin-console/organization-template.ts +++ b/packages/phrases/src/locales/pl-pl/translation/admin-console/organization-template.ts @@ -23,7 +23,7 @@ const organization_template = { tab_name: 'Uprawnienia org', search_placeholder: 'Szukaj po nazwie uprawnienia', create_org_permission: 'Utwórz uprawnienie org', - permission_column: 'Uprawnienie', + permission_column: 'Uprawnienie organizacji', description_column: 'Opis', placeholder_title: 'Uprawnienie organizacyjne', placeholder_description: diff --git a/packages/phrases/src/locales/pt-br/translation/admin-console/organization-template.ts b/packages/phrases/src/locales/pt-br/translation/admin-console/organization-template.ts index 6aebacd2618..46ee4a80197 100644 --- a/packages/phrases/src/locales/pt-br/translation/admin-console/organization-template.ts +++ b/packages/phrases/src/locales/pt-br/translation/admin-console/organization-template.ts @@ -23,7 +23,7 @@ const organization_template = { tab_name: 'Permissões da org', search_placeholder: 'Buscar por nome da permissão', create_org_permission: 'Criar permissão da org', - permission_column: 'Permissão', + permission_column: 'Permissão da organização', description_column: 'Descrição', placeholder_title: 'Permissão da organização', placeholder_description: diff --git a/packages/phrases/src/locales/pt-pt/translation/admin-console/organization-template.ts b/packages/phrases/src/locales/pt-pt/translation/admin-console/organization-template.ts index d5614f11a0a..20235c7f6d8 100644 --- a/packages/phrases/src/locales/pt-pt/translation/admin-console/organization-template.ts +++ b/packages/phrases/src/locales/pt-pt/translation/admin-console/organization-template.ts @@ -23,7 +23,7 @@ const organization_template = { tab_name: 'Permissões da org', search_placeholder: 'Procurar por nome da permissão', create_org_permission: 'Criar permissão da org', - permission_column: 'Permissão', + permission_column: 'Permissão da organização', description_column: 'Descrição', placeholder_title: 'Permissão da organização', placeholder_description: diff --git a/packages/phrases/src/locales/ru/translation/admin-console/organization-template.ts b/packages/phrases/src/locales/ru/translation/admin-console/organization-template.ts index ffca6ebb44a..8aada797d9d 100644 --- a/packages/phrases/src/locales/ru/translation/admin-console/organization-template.ts +++ b/packages/phrases/src/locales/ru/translation/admin-console/organization-template.ts @@ -23,7 +23,7 @@ const organization_template = { tab_name: 'Разрешения орг', search_placeholder: 'Поиск по названию разрешения', create_org_permission: 'Создать разрешение орг', - permission_column: 'Разрешение', + permission_column: 'Разрешение организации', description_column: 'Описание', placeholder_title: 'Разрешение организации', placeholder_description: diff --git a/packages/phrases/src/locales/tr-tr/translation/admin-console/organization-template.ts b/packages/phrases/src/locales/tr-tr/translation/admin-console/organization-template.ts index 8d1189935fc..1b56d73cfee 100644 --- a/packages/phrases/src/locales/tr-tr/translation/admin-console/organization-template.ts +++ b/packages/phrases/src/locales/tr-tr/translation/admin-console/organization-template.ts @@ -23,7 +23,7 @@ const organization_template = { tab_name: 'Org izinleri', search_placeholder: 'İzin adı ile ara', create_org_permission: 'Org izni oluştur', - permission_column: 'İzin', + permission_column: 'Разрешение организации', description_column: 'Açıklama', placeholder_title: 'Organizasyon izni', placeholder_description: diff --git a/packages/phrases/src/locales/zh-cn/translation/admin-console/organization-template.ts b/packages/phrases/src/locales/zh-cn/translation/admin-console/organization-template.ts index b8f887f8bdb..c1746fb9710 100644 --- a/packages/phrases/src/locales/zh-cn/translation/admin-console/organization-template.ts +++ b/packages/phrases/src/locales/zh-cn/translation/admin-console/organization-template.ts @@ -21,7 +21,7 @@ const organization_template = { tab_name: '组织权限', search_placeholder: '按权限名称搜索', create_org_permission: '创建组织权限', - permission_column: '权限', + permission_column: '组织权限', description_column: '描述', placeholder_title: '组织权限', placeholder_description: '组织权限指的是在组织上下文中访问资源的授权。', diff --git a/packages/phrases/src/locales/zh-hk/translation/admin-console/organization-template.ts b/packages/phrases/src/locales/zh-hk/translation/admin-console/organization-template.ts index 9b07a4ed8b5..59a5b298b8a 100644 --- a/packages/phrases/src/locales/zh-hk/translation/admin-console/organization-template.ts +++ b/packages/phrases/src/locales/zh-hk/translation/admin-console/organization-template.ts @@ -21,7 +21,7 @@ const organization_template = { tab_name: '組織權限', search_placeholder: '按權限名稱搜索', create_org_permission: '創建組織權限', - permission_column: '權限', + permission_column: '組織權限', description_column: '描述', placeholder_title: '組織權限', placeholder_description: '組織權限指的是在組織上下文中訪問資源的授權。', diff --git a/packages/phrases/src/locales/zh-tw/translation/admin-console/organization-template.ts b/packages/phrases/src/locales/zh-tw/translation/admin-console/organization-template.ts index 9f7f3b4cafd..e2573c05e8b 100644 --- a/packages/phrases/src/locales/zh-tw/translation/admin-console/organization-template.ts +++ b/packages/phrases/src/locales/zh-tw/translation/admin-console/organization-template.ts @@ -21,7 +21,7 @@ const organization_template = { tab_name: '組織權限', search_placeholder: '按權限名稱搜尋', create_org_permission: '創建組織權限', - permission_column: '權限', + permission_column: '組織權限', description_column: '描述', placeholder_title: '組織權限', placeholder_description: '組織權限指的是在組織上下文中訪問資源的授權。', From 5660c54cb563e2a9dae9e314976924aa60b5f69a Mon Sep 17 00:00:00 2001 From: wangsijie Date: Tue, 14 May 2024 16:10:31 +0800 Subject: [PATCH 387/687] fix(core): should sign out user after deletion or suspension (#5857) fixed #5572 --- .changeset/green-cougars-behave.md | 7 +++++++ packages/core/src/libraries/user.ts | 10 ++++++++++ .../core/src/routes/admin-user/basics.test.ts | 7 ++++--- packages/core/src/routes/admin-user/basics.ts | 15 +++++++++++---- .../src/tests/api/admin-user.test.ts | 14 ++++++++++++-- 5 files changed, 44 insertions(+), 9 deletions(-) create mode 100644 .changeset/green-cougars-behave.md diff --git a/.changeset/green-cougars-behave.md b/.changeset/green-cougars-behave.md new file mode 100644 index 00000000000..88646a69533 --- /dev/null +++ b/.changeset/green-cougars-behave.md @@ -0,0 +1,7 @@ +--- +"@logto/core": patch +--- + +Sign out user after deletion or suspension + +When a user is deleted or suspended through Management API, they should be signed out immediately, including sessions and refresh tokens. diff --git a/packages/core/src/libraries/user.ts b/packages/core/src/libraries/user.ts index 99070a8df7e..66a4560c603 100644 --- a/packages/core/src/libraries/user.ts +++ b/packages/core/src/libraries/user.ts @@ -89,6 +89,7 @@ export const createUserLibrary = (queries: Queries) => { rolesScopes: { findRolesScopesByRoleIds }, scopes: { findScopesByIdsAndResourceIndicator }, organizations, + oidcModelInstances: { revokeInstanceByUserId }, } = queries; const generateUserId = async (retries = 500) => @@ -270,6 +271,14 @@ export const createUserLibrary = (queries: Queries) => { return user; }; + const signOutUser = async (userId: string) => { + await Promise.all([ + revokeInstanceByUserId('AccessToken', userId), + revokeInstanceByUserId('RefreshToken', userId), + revokeInstanceByUserId('Session', userId), + ]); + }; + return { generateUserId, insertUser, @@ -279,5 +288,6 @@ export const createUserLibrary = (queries: Queries) => { findUserRoles, addUserMfaVerification, verifyUserPassword, + signOutUser, }; }; diff --git a/packages/core/src/routes/admin-user/basics.test.ts b/packages/core/src/routes/admin-user/basics.test.ts index 280502541fb..68f1d29e38c 100644 --- a/packages/core/src/routes/admin-user/basics.test.ts +++ b/packages/core/src/routes/admin-user/basics.test.ts @@ -14,7 +14,6 @@ const { jest } = import.meta; const { mockEsmWithActual } = createMockUtils(jest); const mockedQueries = { - oidcModelInstances: { revokeInstanceByUserId: jest.fn() }, signInExperiences: { findDefaultSignInExperience: jest.fn( async () => @@ -65,7 +64,6 @@ const mockHasUser = jest.fn(async () => false); const mockHasUserWithEmail = jest.fn(async () => false); const mockHasUserWithPhone = jest.fn(async () => false); -const { revokeInstanceByUserId } = mockedQueries.oidcModelInstances; const { hasUser, findUserById, updateUserById, deleteUserIdentity, deleteUserById } = mockedQueries.users; @@ -77,6 +75,7 @@ const { encryptUserPassword } = await mockEsmWithActual('#src/libraries/user.js' })); const verifyUserPassword = jest.fn(); +const signOutUser = jest.fn(); const usersLibraries = { generateUserId: jest.fn(async () => 'fooId'), insertUser: jest.fn( @@ -86,6 +85,7 @@ const usersLibraries = { }) ), verifyUserPassword, + signOutUser, } satisfies Partial; const adminUserRoutes = await pickDefault(import('./basics.js')); @@ -377,7 +377,7 @@ describe('adminUserRoutes', () => { .patch(`/users/${mockedUserId}/is-suspended`) .send({ isSuspended: true }); expect(updateUserById).toHaveBeenCalledWith(mockedUserId, { isSuspended: true }); - expect(revokeInstanceByUserId).toHaveBeenCalledWith('refreshToken', mockedUserId); + expect(signOutUser).toHaveBeenCalledWith(mockedUserId); expect(response.status).toEqual(200); expect(response.body).toEqual({ ...mockUserResponse, @@ -389,6 +389,7 @@ describe('adminUserRoutes', () => { const userId = 'fooUser'; const response = await userRequest.delete(`/users/${userId}`); expect(response.status).toEqual(204); + expect(signOutUser).toHaveBeenCalledWith(userId); }); it('DELETE /users/:userId should throw if user is deleting self', async () => { diff --git a/packages/core/src/routes/admin-user/basics.ts b/packages/core/src/routes/admin-user/basics.ts index 710bbfe149b..338648c3558 100644 --- a/packages/core/src/routes/admin-user/basics.ts +++ b/packages/core/src/routes/admin-user/basics.ts @@ -1,3 +1,4 @@ +/* eslint-disable max-lines */ import { emailRegEx, phoneRegEx, usernameRegEx } from '@logto/core-kit'; import { UsersPasswordEncryptionMethod, @@ -21,7 +22,6 @@ export default function adminUserBasicsRoutes( ) { const [router, { queries, libraries }] = args; const { - oidcModelInstances: { revokeInstanceByUserId }, users: { deleteUserById, findUserById, @@ -33,7 +33,13 @@ export default function adminUserBasicsRoutes( userSsoIdentities, } = queries; const { - users: { checkIdentifierCollision, generateUserId, insertUser, verifyUserPassword }, + users: { + checkIdentifierCollision, + generateUserId, + insertUser, + verifyUserPassword, + signOutUser, + }, } = libraries; router.get( @@ -343,12 +349,11 @@ export default function adminUserBasicsRoutes( }); if (isSuspended) { - await revokeInstanceByUserId('refreshToken', user.id); + await signOutUser(user.id); } ctx.body = pick(user, ...userInfoSelectFields); - // eslint-disable-next-line max-lines return next(); } ); @@ -368,6 +373,7 @@ export default function adminUserBasicsRoutes( throw new RequestError('user.cannot_delete_self'); } + await signOutUser(userId); await deleteUserById(userId); ctx.status = 204; @@ -376,3 +382,4 @@ export default function adminUserBasicsRoutes( } ); } +/* eslint-enable max-lines */ diff --git a/packages/integration-tests/src/tests/api/admin-user.test.ts b/packages/integration-tests/src/tests/api/admin-user.test.ts index 9662010b8c9..5c4a60c4a02 100644 --- a/packages/integration-tests/src/tests/api/admin-user.test.ts +++ b/packages/integration-tests/src/tests/api/admin-user.test.ts @@ -22,7 +22,11 @@ import { } from '#src/api/index.js'; import { clearConnectorsByTypes } from '#src/helpers/connector.js'; import { createUserByAdmin, expectRejects } from '#src/helpers/index.js'; -import { createNewSocialUserWithUsernameAndPassword } from '#src/helpers/interactions.js'; +import { + createNewSocialUserWithUsernameAndPassword, + signInWithPassword, +} from '#src/helpers/interactions.js'; +import { enableAllPasswordSignInMethods } from '#src/helpers/sign-in-experience.js'; import { generateUsername, generateEmail, @@ -177,7 +181,9 @@ describe('admin console user management', () => { }); it('should delete user successfully', async () => { - const user = await createUserByAdmin(); + const username = generateUsername(); + const password = 'password'; + const user = await createUserByAdmin({ username, password }); const userEntity = await getUser(user.id); expect(userEntity).toMatchObject(user); @@ -186,6 +192,10 @@ describe('admin console user management', () => { const response = await getUser(user.id).catch((error: unknown) => error); expect(response instanceof HTTPError && response.response.status === 404).toBe(true); + + await enableAllPasswordSignInMethods(); + // Sign in with deleted user should throw error + await expect(signInWithPassword({ username, password })).rejects.toThrowError(); }); it('should update user password successfully', async () => { From a6582b208cd1c5390fb5764fc06d5d5a39573abd Mon Sep 17 00:00:00 2001 From: Charles Zhao Date: Tue, 14 May 2024 18:00:27 +0800 Subject: [PATCH 388/687] chore(console): update sdk doc reference links (#5860) --- packages/console/src/assets/docs/guides/m2m-general/index.ts | 2 +- packages/console/src/assets/docs/guides/native-android/index.ts | 2 +- packages/console/src/assets/docs/guides/native-expo/index.ts | 2 +- packages/console/src/assets/docs/guides/spa-angular/index.ts | 2 +- packages/console/src/assets/docs/guides/spa-react/index.ts | 2 +- packages/console/src/assets/docs/guides/spa-vanilla/index.ts | 2 +- packages/console/src/assets/docs/guides/spa-vue/index.ts | 2 +- .../assets/docs/guides/web-dotnet-core-blazor-server/README.mdx | 2 +- .../assets/docs/guides/web-dotnet-core-blazor-server/index.ts | 2 +- .../assets/docs/guides/web-dotnet-core-blazor-wasm/README.mdx | 2 +- .../src/assets/docs/guides/web-dotnet-core-blazor-wasm/index.ts | 2 +- .../src/assets/docs/guides/web-dotnet-core-mvc/README.mdx | 2 +- .../console/src/assets/docs/guides/web-dotnet-core-mvc/index.ts | 2 +- .../console/src/assets/docs/guides/web-dotnet-core/README.mdx | 2 +- packages/console/src/assets/docs/guides/web-express/index.ts | 2 +- packages/console/src/assets/docs/guides/web-go/index.ts | 2 +- .../console/src/assets/docs/guides/web-next-app-router/index.ts | 2 +- packages/console/src/assets/docs/guides/web-next/index.ts | 2 +- packages/console/src/assets/docs/guides/web-nuxt/index.ts | 2 +- packages/console/src/assets/docs/guides/web-php/README.mdx | 2 +- packages/console/src/assets/docs/guides/web-php/index.ts | 2 +- packages/console/src/assets/docs/guides/web-python/README.mdx | 2 +- packages/console/src/assets/docs/guides/web-python/index.ts | 2 +- packages/console/src/assets/docs/guides/web-sveltekit/index.ts | 2 +- 24 files changed, 24 insertions(+), 24 deletions(-) diff --git a/packages/console/src/assets/docs/guides/m2m-general/index.ts b/packages/console/src/assets/docs/guides/m2m-general/index.ts index d9273f48075..00c1a10c629 100644 --- a/packages/console/src/assets/docs/guides/m2m-general/index.ts +++ b/packages/console/src/assets/docs/guides/m2m-general/index.ts @@ -9,7 +9,7 @@ const metadata: Readonly = Object.freeze({ isFeatured: true, fullGuide: { title: 'Full machine-to-machine integration tutorial', - url: 'https://docs.logto.io/sdk/m2m', + url: 'https://docs.logto.io/quick-starts/m2m', }, }); diff --git a/packages/console/src/assets/docs/guides/native-android/index.ts b/packages/console/src/assets/docs/guides/native-android/index.ts index 17b1d4674b1..de711ff81c1 100644 --- a/packages/console/src/assets/docs/guides/native-android/index.ts +++ b/packages/console/src/assets/docs/guides/native-android/index.ts @@ -12,7 +12,7 @@ const metadata: Readonly = Object.freeze({ }, fullGuide: { title: 'Full Android SDK tutorial', - url: 'https://docs.logto.io/sdk/android', + url: 'https://docs.logto.io/quick-starts/android', }, }); diff --git a/packages/console/src/assets/docs/guides/native-expo/index.ts b/packages/console/src/assets/docs/guides/native-expo/index.ts index 0ac4eff3cf1..2ea3ef2620c 100644 --- a/packages/console/src/assets/docs/guides/native-expo/index.ts +++ b/packages/console/src/assets/docs/guides/native-expo/index.ts @@ -12,7 +12,7 @@ const metadata: Readonly = Object.freeze({ }, fullGuide: { title: 'Full Expo (React Native) guide', - url: 'https://docs.logto.io/sdk/expo', + url: 'https://docs.logto.io/quick-starts/expo', }, }); diff --git a/packages/console/src/assets/docs/guides/spa-angular/index.ts b/packages/console/src/assets/docs/guides/spa-angular/index.ts index f344cdc6ddd..ef02c1ced7d 100644 --- a/packages/console/src/assets/docs/guides/spa-angular/index.ts +++ b/packages/console/src/assets/docs/guides/spa-angular/index.ts @@ -12,7 +12,7 @@ const metadata: Readonly = Object.freeze({ }, fullGuide: { title: 'Full Angular guide', - url: 'https://docs.logto.io/sdk/angular', + url: 'https://docs.logto.io/quick-starts/angular', }, }); diff --git a/packages/console/src/assets/docs/guides/spa-react/index.ts b/packages/console/src/assets/docs/guides/spa-react/index.ts index ca3722548cb..53fdeeff520 100644 --- a/packages/console/src/assets/docs/guides/spa-react/index.ts +++ b/packages/console/src/assets/docs/guides/spa-react/index.ts @@ -13,7 +13,7 @@ const metadata: Readonly = Object.freeze({ isFeatured: true, fullGuide: { title: 'Full React SDK tutorial', - url: 'https://docs.logto.io/sdk/react', + url: 'https://docs.logto.io/quick-starts/react', }, }); diff --git a/packages/console/src/assets/docs/guides/spa-vanilla/index.ts b/packages/console/src/assets/docs/guides/spa-vanilla/index.ts index 2cd99b933d0..48198f3cc2d 100644 --- a/packages/console/src/assets/docs/guides/spa-vanilla/index.ts +++ b/packages/console/src/assets/docs/guides/spa-vanilla/index.ts @@ -12,7 +12,7 @@ const metadata: Readonly = Object.freeze({ }, fullGuide: { title: 'Full vanilla JS SDK tutorial', - url: 'https://docs.logto.io/sdk/vanilla-js', + url: 'https://docs.logto.io/quick-starts/vanilla-js', }, }); diff --git a/packages/console/src/assets/docs/guides/spa-vue/index.ts b/packages/console/src/assets/docs/guides/spa-vue/index.ts index 91ab0f6045c..71f6553bcd8 100644 --- a/packages/console/src/assets/docs/guides/spa-vue/index.ts +++ b/packages/console/src/assets/docs/guides/spa-vue/index.ts @@ -14,7 +14,7 @@ const metadata: Readonly = Object.freeze({ isFeatured: true, fullGuide: { title: 'Full Vue SDK tutorial', - url: 'https://docs.logto.io/sdk/vue', + url: 'https://docs.logto.io/quick-starts/vue', }, }); diff --git a/packages/console/src/assets/docs/guides/web-dotnet-core-blazor-server/README.mdx b/packages/console/src/assets/docs/guides/web-dotnet-core-blazor-server/README.mdx index 0061655307d..1258ea8a865 100644 --- a/packages/console/src/assets/docs/guides/web-dotnet-core-blazor-server/README.mdx +++ b/packages/console/src/assets/docs/guides/web-dotnet-core-blazor-server/README.mdx @@ -184,7 +184,7 @@ var claims = User.Claims; var userId = claims.FirstOrDefault(c => c.Type == LogtoParameters.Claims.Subject)?.Value; ``` -See the [full tutorial](https://docs.logto.io/sdk/dotnet-core/blazor-server/) for more details. +See the [full tutorial](https://docs.logto.io/quick-starts/dotnet-core/blazor-server/) for more details. diff --git a/packages/console/src/assets/docs/guides/web-dotnet-core-blazor-server/index.ts b/packages/console/src/assets/docs/guides/web-dotnet-core-blazor-server/index.ts index 70f9efd1d98..9deb50ecb89 100644 --- a/packages/console/src/assets/docs/guides/web-dotnet-core-blazor-server/index.ts +++ b/packages/console/src/assets/docs/guides/web-dotnet-core-blazor-server/index.ts @@ -12,7 +12,7 @@ const metadata: Readonly = Object.freeze({ }, fullGuide: { title: 'Full .NET Core (Blazor Server) integration tutorial', - url: 'https://docs.logto.io/sdk/dotnet-core/blazor-server', + url: 'https://docs.logto.io/quick-starts/dotnet-core/blazor-server', }, }); diff --git a/packages/console/src/assets/docs/guides/web-dotnet-core-blazor-wasm/README.mdx b/packages/console/src/assets/docs/guides/web-dotnet-core-blazor-wasm/README.mdx index d54133189c3..75718996401 100644 --- a/packages/console/src/assets/docs/guides/web-dotnet-core-blazor-wasm/README.mdx +++ b/packages/console/src/assets/docs/guides/web-dotnet-core-blazor-wasm/README.mdx @@ -209,7 +209,7 @@ Now you can run the web application and try to sign in and sign out with Logto: To get the user profile, you can use the `User?.Profile` property; to fetch the access token, you can use the `User?.AccessToken` property or add it to your HTTP client using `.AddAccessToken()`. -See the [full tutorial](https://docs.logto.io/sdk/dotnet-core/blazor-wasm/) for more details. +See the [full tutorial](https://docs.logto.io/quick-starts/dotnet-core/blazor-wasm/) for more details. diff --git a/packages/console/src/assets/docs/guides/web-dotnet-core-blazor-wasm/index.ts b/packages/console/src/assets/docs/guides/web-dotnet-core-blazor-wasm/index.ts index 553eb1d8c79..55770849b8c 100644 --- a/packages/console/src/assets/docs/guides/web-dotnet-core-blazor-wasm/index.ts +++ b/packages/console/src/assets/docs/guides/web-dotnet-core-blazor-wasm/index.ts @@ -12,7 +12,7 @@ const metadata: Readonly = Object.freeze({ }, fullGuide: { title: 'Full .NET Core (Blazor WASM) integration tutorial', - url: 'https://docs.logto.io/sdk/dotnet-core/blazor-wasm', + url: 'https://docs.logto.io/quick-starts/dotnet-core/blazor-wasm', }, }); diff --git a/packages/console/src/assets/docs/guides/web-dotnet-core-mvc/README.mdx b/packages/console/src/assets/docs/guides/web-dotnet-core-mvc/README.mdx index 7dead35f25e..8fa99eea24c 100644 --- a/packages/console/src/assets/docs/guides/web-dotnet-core-mvc/README.mdx +++ b/packages/console/src/assets/docs/guides/web-dotnet-core-mvc/README.mdx @@ -173,7 +173,7 @@ var claims = User.Claims; var userId = claims.FirstOrDefault(c => c.Type == LogtoParameters.Claims.Subject)?.Value; ``` -See the [full tutorial](https://docs.logto.io/sdk/dotnet-core/mvc/) for more details. +See the [full tutorial](https://docs.logto.io/quick-starts/dotnet-core/mvc/) for more details. diff --git a/packages/console/src/assets/docs/guides/web-dotnet-core-mvc/index.ts b/packages/console/src/assets/docs/guides/web-dotnet-core-mvc/index.ts index e65708141df..315a8943e86 100644 --- a/packages/console/src/assets/docs/guides/web-dotnet-core-mvc/index.ts +++ b/packages/console/src/assets/docs/guides/web-dotnet-core-mvc/index.ts @@ -12,7 +12,7 @@ const metadata: Readonly = Object.freeze({ }, fullGuide: { title: 'Full .NET Core (MVC) integration tutorial', - url: 'https://docs.logto.io/sdk/dotnet-core/mvc', + url: 'https://docs.logto.io/quick-starts/dotnet-core/mvc', }, }); diff --git a/packages/console/src/assets/docs/guides/web-dotnet-core/README.mdx b/packages/console/src/assets/docs/guides/web-dotnet-core/README.mdx index bff61cdfc48..245a9fe3a51 100644 --- a/packages/console/src/assets/docs/guides/web-dotnet-core/README.mdx +++ b/packages/console/src/assets/docs/guides/web-dotnet-core/README.mdx @@ -183,7 +183,7 @@ var claims = User.Claims; var userId = claims.FirstOrDefault(c => c.Type == LogtoParameters.Claims.Subject)?.Value; ``` -See the [full tutorial](https://docs.logto.io/sdk/dotnet-core/razor/) for more details. +See the [full tutorial](https://docs.logto.io/quick-starts/dotnet-core/razor/) for more details. diff --git a/packages/console/src/assets/docs/guides/web-express/index.ts b/packages/console/src/assets/docs/guides/web-express/index.ts index e84b390c5ec..6c22e22b2e8 100644 --- a/packages/console/src/assets/docs/guides/web-express/index.ts +++ b/packages/console/src/assets/docs/guides/web-express/index.ts @@ -13,7 +13,7 @@ const metadata: Readonly = Object.freeze({ }, fullGuide: { title: 'Full Express SDK tutorial', - url: 'https://docs.logto.io/sdk/express', + url: 'https://docs.logto.io/quick-starts/express', }, }); diff --git a/packages/console/src/assets/docs/guides/web-go/index.ts b/packages/console/src/assets/docs/guides/web-go/index.ts index 811fca43544..6bd10eae34c 100644 --- a/packages/console/src/assets/docs/guides/web-go/index.ts +++ b/packages/console/src/assets/docs/guides/web-go/index.ts @@ -13,7 +13,7 @@ const metadata: Readonly = Object.freeze({ }, fullGuide: { title: 'Full Go SDK tutorial', - url: 'https://docs.logto.io/sdk/go', + url: 'https://docs.logto.io/quick-starts/go', }, }); diff --git a/packages/console/src/assets/docs/guides/web-next-app-router/index.ts b/packages/console/src/assets/docs/guides/web-next-app-router/index.ts index c4132c9b49d..692ecdf0f66 100644 --- a/packages/console/src/assets/docs/guides/web-next-app-router/index.ts +++ b/packages/console/src/assets/docs/guides/web-next-app-router/index.ts @@ -13,7 +13,7 @@ const metadata: Readonly = Object.freeze({ }, fullGuide: { title: 'Full Next.js App Router SDK tutorial', - url: 'https://docs.logto.io/sdk/next-app-router', + url: 'https://docs.logto.io/quick-starts/next-app-router', }, }); diff --git a/packages/console/src/assets/docs/guides/web-next/index.ts b/packages/console/src/assets/docs/guides/web-next/index.ts index 9691318a529..f8d5debac28 100644 --- a/packages/console/src/assets/docs/guides/web-next/index.ts +++ b/packages/console/src/assets/docs/guides/web-next/index.ts @@ -14,7 +14,7 @@ const metadata: Readonly = Object.freeze({ isFeatured: true, fullGuide: { title: 'Full Next.js SDK tutorial', - url: 'https://docs.logto.io/sdk/next', + url: 'https://docs.logto.io/quick-starts/next', }, }); diff --git a/packages/console/src/assets/docs/guides/web-nuxt/index.ts b/packages/console/src/assets/docs/guides/web-nuxt/index.ts index 9185cbf7486..00953f2e68a 100644 --- a/packages/console/src/assets/docs/guides/web-nuxt/index.ts +++ b/packages/console/src/assets/docs/guides/web-nuxt/index.ts @@ -13,7 +13,7 @@ const metadata: Readonly = Object.freeze({ }, fullGuide: { title: 'Full Nuxt guide', - url: 'https://docs.logto.io/sdk/nuxt', + url: 'https://docs.logto.io/quick-starts/nuxt', }, }); diff --git a/packages/console/src/assets/docs/guides/web-php/README.mdx b/packages/console/src/assets/docs/guides/web-php/README.mdx index 265c05ef0ba..08ad782494e 100644 --- a/packages/console/src/assets/docs/guides/web-php/README.mdx +++ b/packages/console/src/assets/docs/guides/web-php/README.mdx @@ -159,7 +159,7 @@ Note that a field (claim) with `null` value doesn't mean the field is set. The r For example, if we didn't request the `email` scope when signing in, and the `email` field will be `null`. However, if we requested the `email` scope, the `email` field will be the user's email address if available. -To learn more about scopes and claims, see [Get user information](https://docs.logto.io/sdk/php/#get-user-information). +To learn more about scopes and claims, see [Get user information](https://docs.logto.io/quick-starts/php/#get-user-information). diff --git a/packages/console/src/assets/docs/guides/web-php/index.ts b/packages/console/src/assets/docs/guides/web-php/index.ts index bbb7930bdbb..8d5cec8efa3 100644 --- a/packages/console/src/assets/docs/guides/web-php/index.ts +++ b/packages/console/src/assets/docs/guides/web-php/index.ts @@ -12,7 +12,7 @@ const metadata: Readonly = Object.freeze({ }, fullGuide: { title: 'Full PHP SDK tutorial', - url: 'https://docs.logto.io/sdk/php', + url: 'https://docs.logto.io/quick-starts/php', }, }); diff --git a/packages/console/src/assets/docs/guides/web-python/README.mdx b/packages/console/src/assets/docs/guides/web-python/README.mdx index 5f6ff9181e4..c29d61fafa4 100644 --- a/packages/console/src/assets/docs/guides/web-python/README.mdx +++ b/packages/console/src/assets/docs/guides/web-python/README.mdx @@ -177,7 +177,7 @@ Adding `exclude_unset=True` will exclude unset fields from the JSON output, whic For example, if we didn't request the `email` scope when signing in, and the `email` field will be excluded from the JSON output. However, if we requested the `email` scope, but the user doesn't have an email address, the `email` field will be included in the JSON output with a `null` value. -To learn more about scopes and claims, see [Get user information](https://docs.logto.io/sdk/python/#get-user-information). +To learn more about scopes and claims, see [Get user information](https://docs.logto.io/quick-starts/python/#get-user-information). diff --git a/packages/console/src/assets/docs/guides/web-python/index.ts b/packages/console/src/assets/docs/guides/web-python/index.ts index 60c5c918c35..8840be3d412 100644 --- a/packages/console/src/assets/docs/guides/web-python/index.ts +++ b/packages/console/src/assets/docs/guides/web-python/index.ts @@ -12,7 +12,7 @@ const metadata: Readonly = Object.freeze({ }, fullGuide: { title: 'Full Python SDK tutorial', - url: 'https://docs.logto.io/sdk/python', + url: 'https://docs.logto.io/quick-starts/python', }, }); diff --git a/packages/console/src/assets/docs/guides/web-sveltekit/index.ts b/packages/console/src/assets/docs/guides/web-sveltekit/index.ts index 9f945df2694..7b429bbbf0a 100644 --- a/packages/console/src/assets/docs/guides/web-sveltekit/index.ts +++ b/packages/console/src/assets/docs/guides/web-sveltekit/index.ts @@ -13,7 +13,7 @@ const metadata: Readonly = Object.freeze({ }, fullGuide: { title: 'Full SvelteKit guide', - url: 'https://docs.logto.io/sdk/sveltekit', + url: 'https://docs.logto.io/quick-starts/sveltekit', }, }); From 7b5a4e3fb49f1129ca0e2f40625d63d50cc777ef Mon Sep 17 00:00:00 2001 From: silverhand-bot <107667382+silverhand-bot@users.noreply.github.com> Date: Tue, 14 May 2024 20:27:55 +0800 Subject: [PATCH 389/687] release: version packages (#5684) --- .changeset/afraid-stingrays-perform.md | 5 - .changeset/chilled-pugs-notice.md | 6 - .changeset/cuddly-buses-obey.md | 5 - .changeset/dull-frogs-perform.md | 5 - .changeset/fluffy-steaks-flow.md | 10 -- .changeset/forty-grapes-relax.md | 7 -- .changeset/four-goats-rush.md | 9 -- .changeset/funny-books-sell.md | 9 -- .changeset/green-cougars-behave.md | 7 -- .changeset/green-phones-visit.md | 5 - .changeset/grumpy-cougars-perform.md | 8 -- .changeset/healthy-knives-draw.md | 11 -- .changeset/itchy-eels-remain.md | 8 -- .changeset/loud-mice-divide.md | 12 -- .changeset/metal-lions-swim.md | 7 -- .changeset/nasty-dots-lie.md | 5 - .changeset/nine-turtles-learn.md | 29 ----- .changeset/popular-chicken-share.md | 5 - .changeset/pretty-mirrors-peel.md | 8 -- .changeset/rare-lamps-worry.md | 9 -- .changeset/real-camels-cheat.md | 7 -- .changeset/smart-melons-shop.md | 10 -- .changeset/soft-stingrays-beam.md | 5 - .changeset/ten-steaks-melt.md | 5 - .changeset/thick-carrots-tickle.md | 7 -- .changeset/thirty-cameras-explain.md | 13 -- packages/app-insights/CHANGELOG.md | 10 ++ packages/app-insights/package.json | 2 +- packages/cli/CHANGELOG.md | 13 ++ packages/cli/package.json | 8 +- .../connectors/connector-github/CHANGELOG.md | 9 ++ .../connectors/connector-github/package.json | 2 +- .../connector-huggingface/CHANGELOG.md | 12 ++ .../connector-huggingface/package.json | 4 +- .../connectors/connector-oauth2/CHANGELOG.md | 11 ++ .../connectors/connector-oauth2/package.json | 4 +- .../connectors/connector-oidc/CHANGELOG.md | 13 ++ .../connectors/connector-oidc/package.json | 6 +- packages/console/CHANGELOG.md | 26 ++++ packages/console/package.json | 8 +- packages/core/CHANGELOG.md | 118 ++++++++++++++++++ packages/core/package.json | 12 +- packages/create/CHANGELOG.md | 6 + packages/create/package.json | 4 +- packages/experience/CHANGELOG.md | 35 ++++++ packages/experience/package.json | 6 +- packages/integration-tests/CHANGELOG.md | 8 ++ packages/integration-tests/package.json | 6 +- packages/phrases/CHANGELOG.md | 14 +++ packages/phrases/package.json | 2 +- packages/schemas/CHANGELOG.md | 24 ++++ ...delete-jwt-customier-with-empty-script.ts} | 0 ...713942039-add-organization-custom-data.ts} | 0 ...4270244-application-org-resource-scope.ts} | 0 packages/schemas/package.json | 6 +- packages/shared/CHANGELOG.md | 8 ++ packages/shared/package.json | 2 +- pnpm-lock.yaml | 44 +++---- 58 files changed, 365 insertions(+), 275 deletions(-) delete mode 100644 .changeset/afraid-stingrays-perform.md delete mode 100644 .changeset/chilled-pugs-notice.md delete mode 100644 .changeset/cuddly-buses-obey.md delete mode 100644 .changeset/dull-frogs-perform.md delete mode 100644 .changeset/fluffy-steaks-flow.md delete mode 100644 .changeset/forty-grapes-relax.md delete mode 100644 .changeset/four-goats-rush.md delete mode 100644 .changeset/funny-books-sell.md delete mode 100644 .changeset/green-cougars-behave.md delete mode 100644 .changeset/green-phones-visit.md delete mode 100644 .changeset/grumpy-cougars-perform.md delete mode 100644 .changeset/healthy-knives-draw.md delete mode 100644 .changeset/itchy-eels-remain.md delete mode 100644 .changeset/loud-mice-divide.md delete mode 100644 .changeset/metal-lions-swim.md delete mode 100644 .changeset/nasty-dots-lie.md delete mode 100644 .changeset/nine-turtles-learn.md delete mode 100644 .changeset/popular-chicken-share.md delete mode 100644 .changeset/pretty-mirrors-peel.md delete mode 100644 .changeset/rare-lamps-worry.md delete mode 100644 .changeset/real-camels-cheat.md delete mode 100644 .changeset/smart-melons-shop.md delete mode 100644 .changeset/soft-stingrays-beam.md delete mode 100644 .changeset/ten-steaks-melt.md delete mode 100644 .changeset/thick-carrots-tickle.md delete mode 100644 .changeset/thirty-cameras-explain.md create mode 100644 packages/connectors/connector-huggingface/CHANGELOG.md rename packages/schemas/alterations/{next-1712912361-delete-jwt-customier-with-empty-script.ts => 1.16.0-1712912361-delete-jwt-customier-with-empty-script.ts} (100%) rename packages/schemas/alterations/{next-1713942039-add-organization-custom-data.ts => 1.16.0-1713942039-add-organization-custom-data.ts} (100%) rename packages/schemas/alterations/{next-1714270244-application-org-resource-scope.ts => 1.16.0-1714270244-application-org-resource-scope.ts} (100%) diff --git a/.changeset/afraid-stingrays-perform.md b/.changeset/afraid-stingrays-perform.md deleted file mode 100644 index 2bfa7f2708e..00000000000 --- a/.changeset/afraid-stingrays-perform.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"@logto/core": patch ---- - -Bug fix: organization invitation APIs should handle invitee emails case insensitively diff --git a/.changeset/chilled-pugs-notice.md b/.changeset/chilled-pugs-notice.md deleted file mode 100644 index 06b33009b6f..00000000000 --- a/.changeset/chilled-pugs-notice.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -"@logto/connector-oauth": minor -"@logto/connector-oidc": minor ---- - -Support `client_secret_basic` and `client_secret_jwt` token endpoint auth method for oauth & oidc connectors diff --git a/.changeset/cuddly-buses-obey.md b/.changeset/cuddly-buses-obey.md deleted file mode 100644 index 01fddf2d651..00000000000 --- a/.changeset/cuddly-buses-obey.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"@logto/core": patch ---- - -Management API will not return 500 in production for status codes that are not listed in the OpenAPI spec diff --git a/.changeset/dull-frogs-perform.md b/.changeset/dull-frogs-perform.md deleted file mode 100644 index d470f00a640..00000000000 --- a/.changeset/dull-frogs-perform.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"@logto/core": minor ---- - -add support for Redis Cluster and extra TLS options for Redis connections diff --git a/.changeset/fluffy-steaks-flow.md b/.changeset/fluffy-steaks-flow.md deleted file mode 100644 index 998c2289937..00000000000 --- a/.changeset/fluffy-steaks-flow.md +++ /dev/null @@ -1,10 +0,0 @@ ---- -"@logto/schemas": minor -"@logto/core": minor -"@logto/console": minor ---- - -refactor the definition of hook event types - -- Add `DataHook` event types. `DataHook` are triggered by data changes. -- Add "interaction" prefix to existing hook event types. Interaction hook events are triggered by end user interactions, e.g. completing sign-in. diff --git a/.changeset/forty-grapes-relax.md b/.changeset/forty-grapes-relax.md deleted file mode 100644 index 1c0bdef0c67..00000000000 --- a/.changeset/forty-grapes-relax.md +++ /dev/null @@ -1,7 +0,0 @@ ---- -'@logto/core': patch ---- - -Fix OIDC AccessDenied error code to 403. - -This error may happen when you try to grant an access token to a user lacking the required permissions, especially when granting for orgnization related resources. The error code should be 403 instead of 400. diff --git a/.changeset/four-goats-rush.md b/.changeset/four-goats-rush.md deleted file mode 100644 index b26fe019008..00000000000 --- a/.changeset/four-goats-rush.md +++ /dev/null @@ -1,9 +0,0 @@ ---- -"@logto/integration-tests": patch -"@logto/phrases": patch -"@logto/core": patch ---- - -Not allow to modify management API resource through API. - -Previously, management API resource and its scopes are readonly in Console. But it was possible to modify through the API. This is not allowed anymore. diff --git a/.changeset/funny-books-sell.md b/.changeset/funny-books-sell.md deleted file mode 100644 index 8a3a3032397..00000000000 --- a/.changeset/funny-books-sell.md +++ /dev/null @@ -1,9 +0,0 @@ ---- -"@logto/experience": patch ---- - -fix native social sign-in callback - -In a native environment, the social sign-in callback that posts to the native container (e.g. WKWebView in iOS) was wrong. - -This was introduced by a refactor in #5536: It updated the callback path from `/sign-in/social/:connectorId` to `/callback/social/:connectorId`. However, the function to post the message to the native container was not updated accordingly. diff --git a/.changeset/green-cougars-behave.md b/.changeset/green-cougars-behave.md deleted file mode 100644 index 88646a69533..00000000000 --- a/.changeset/green-cougars-behave.md +++ /dev/null @@ -1,7 +0,0 @@ ---- -"@logto/core": patch ---- - -Sign out user after deletion or suspension - -When a user is deleted or suspended through Management API, they should be signed out immediately, including sessions and refresh tokens. diff --git a/.changeset/green-phones-visit.md b/.changeset/green-phones-visit.md deleted file mode 100644 index 2fc47bddbc2..00000000000 --- a/.changeset/green-phones-visit.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"@logto/app-insights": patch ---- - -allow additional telemetry for `trackException()` diff --git a/.changeset/grumpy-cougars-perform.md b/.changeset/grumpy-cougars-perform.md deleted file mode 100644 index acc72b4b63a..00000000000 --- a/.changeset/grumpy-cougars-perform.md +++ /dev/null @@ -1,8 +0,0 @@ ---- -"@logto/core": patch ---- - -implement request ID for API requests - -- All requests will now include a request ID in the headers (`Logto-Core-Request-Id`) -- Terminal logs will now include the request ID as the prefix diff --git a/.changeset/healthy-knives-draw.md b/.changeset/healthy-knives-draw.md deleted file mode 100644 index 6b807ff01a1..00000000000 --- a/.changeset/healthy-knives-draw.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -"@logto/schemas": minor -"@logto/core": minor ---- - -support organization custom data - -Now you can save additional data associated with the organization with the organization-level `customData` field by: - -- Edit in the Console organization details page. -- Specify `customData` field when using organization Management APIs. diff --git a/.changeset/itchy-eels-remain.md b/.changeset/itchy-eels-remain.md deleted file mode 100644 index 7bd5047ae22..00000000000 --- a/.changeset/itchy-eels-remain.md +++ /dev/null @@ -1,8 +0,0 @@ ---- -"@logto/console": minor -"@logto/core": minor ---- - -enable custom JWT feature for OSS version - -OSS version users can now use custom JWT feature to add custom claims to JWT access tokens payload (previously, this feature was only available to Logto Cloud). diff --git a/.changeset/loud-mice-divide.md b/.changeset/loud-mice-divide.md deleted file mode 100644 index a4071141e1d..00000000000 --- a/.changeset/loud-mice-divide.md +++ /dev/null @@ -1,12 +0,0 @@ ---- -"@logto/console": minor ---- - -support adding API resource permissions to organization roles and organization permissions in 3rd-party applications - -## Updates - -- Separated the "Organization template" from the "Organization" page, establishing it as a standalone page for clearer navigation and functionality. -- Enhanced the "Organization template" page by adding functionality that allows users to click on an organization role, which then navigates to the organization role details page where users can view its corresponding permissions and general settings. -- Enabled the assignment of API resource permissions directly from the organization role details page, improving role management and access control. -- Split the permission list for third-party apps into two separate lists: user permissions and organization permissions. Users can now add user profile permissions and API resource permissions for users under user permissions, and add organization permissions and API resource permissions for organizations under organization permissions. diff --git a/.changeset/metal-lions-swim.md b/.changeset/metal-lions-swim.md deleted file mode 100644 index aef92851d90..00000000000 --- a/.changeset/metal-lions-swim.md +++ /dev/null @@ -1,7 +0,0 @@ ---- -"@logto/shared": patch ---- - -add `normalizeError` method to `@logto/shared` package - -Use this method to normalize error objects for logging. This method is useful for logging errors in a consistent format. diff --git a/.changeset/nasty-dots-lie.md b/.changeset/nasty-dots-lie.md deleted file mode 100644 index dc7d517c3d3..00000000000 --- a/.changeset/nasty-dots-lie.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"@logto/connector-huggingface": minor ---- - -add Hugging Face social connector diff --git a/.changeset/nine-turtles-learn.md b/.changeset/nine-turtles-learn.md deleted file mode 100644 index fe141d1fa67..00000000000 --- a/.changeset/nine-turtles-learn.md +++ /dev/null @@ -1,29 +0,0 @@ ---- -"@logto/experience": patch -"@logto/core": patch ---- - -fix the new user from SSO register hook event not triggering bug - -### Issue - -When a new user registers via SSO, the `PostRegister` interaction hook event is not triggered. `PostSignIn` event is mistakenly triggered instead. - -### Root Cause - -In the SSO `post /api/interaction/sso/:connectionId/registration` API, we update the interaction event to `Register`. -However, the hook middleware reads the event from interaction session ahead of the API logic, and the event is not updated resulting in the wrong event being triggered. - -In the current interaction API design, we should mutate the interaction event by calling the `PUT /api/interaction/event` API, instead of updating the event directly in the submit interaction APIs. (Just like the no direct mutation rule for a react state). So we can ensure the correct side effect like logs and hooks are triggered properly. - -All the other sign-in methods are using the `PUT /api/interaction/event` API to update the event. But when implementing the SSO registration API, we were trying to reduce the API requests and directly updated the event in the registration API which will submit the interaction directly. - -### Solution - -Remove the event update logic in the SSO registration API and call the `PUT /api/interaction/event` API to update the event. -This will ensure the correct event is triggered in the hook middleware. - -### Action Items - -Align the current interaction API design for now. -Need to improve the session/interaction API logic to simplify the whole process. diff --git a/.changeset/popular-chicken-share.md b/.changeset/popular-chicken-share.md deleted file mode 100644 index 0a8968351be..00000000000 --- a/.changeset/popular-chicken-share.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"@logto/core": patch ---- - -fix a bug that prevents invitee from accepting the organization invitation if the email letter case is not matching diff --git a/.changeset/pretty-mirrors-peel.md b/.changeset/pretty-mirrors-peel.md deleted file mode 100644 index a50915c9dcb..00000000000 --- a/.changeset/pretty-mirrors-peel.md +++ /dev/null @@ -1,8 +0,0 @@ ---- -"@logto/connector-github": minor ---- - -fetch GitHub account's private email address list and pick the verified primary email as a fallback - -- Add `user:email` as part of default scope to fetch GitHub account's private email address list -- Pick the verified primary email among private email address list as a fallback if the user does not set a public email for GitHub account diff --git a/.changeset/rare-lamps-worry.md b/.changeset/rare-lamps-worry.md deleted file mode 100644 index 12d84219bb9..00000000000 --- a/.changeset/rare-lamps-worry.md +++ /dev/null @@ -1,9 +0,0 @@ ---- -"@logto/core": patch ---- - -Support comma separated resource parameter - -Some third-party libraries or plugins do not support array of resources, and can only specify `resource` through `additionalParameters` config, e.g. `flutter-appauth`. However, only one resource can be specified at a time in this way. This PR enables comma separated resource parameter support in Logto core service, so that multiple resources can be specified via a single string. - -For example: Auth URL like `/oidc/auth?resource=https://example.com/api1,https://example.com/api2` will be interpreted and parsed to Logto core service as `/ordc/auth?resource=https://example.com/api1&resource=https://example.com/api2`. diff --git a/.changeset/real-camels-cheat.md b/.changeset/real-camels-cheat.md deleted file mode 100644 index 28ea73331bb..00000000000 --- a/.changeset/real-camels-cheat.md +++ /dev/null @@ -1,7 +0,0 @@ ---- -"@logto/core": patch ---- - -Provide management API to fetch user organization scopes based on user organization roles - -- GET `organizations/:id/users/:userId/scopes` diff --git a/.changeset/smart-melons-shop.md b/.changeset/smart-melons-shop.md deleted file mode 100644 index e998cdef549..00000000000 --- a/.changeset/smart-melons-shop.md +++ /dev/null @@ -1,10 +0,0 @@ ---- -"@logto/phrases": patch -"@logto/core": patch ---- - -Fix file upload API. - -The `koa-body` has been upgraded to the latest version, which caused the file upload API to break. This change fixes the issue. - -The `ctx.request.files.file` in the new version is an array, so the code has been updated to pick the first one. diff --git a/.changeset/soft-stingrays-beam.md b/.changeset/soft-stingrays-beam.md deleted file mode 100644 index 8afcdf71d42..00000000000 --- a/.changeset/soft-stingrays-beam.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"@logto/console": patch ---- - -Add Java Spring Boot web integration guide to the application creation page diff --git a/.changeset/ten-steaks-melt.md b/.changeset/ten-steaks-melt.md deleted file mode 100644 index b4d58e3db4d..00000000000 --- a/.changeset/ten-steaks-melt.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"@logto/app-insights": major ---- - -remove application insights for react diff --git a/.changeset/thick-carrots-tickle.md b/.changeset/thick-carrots-tickle.md deleted file mode 100644 index a3811d8cfe7..00000000000 --- a/.changeset/thick-carrots-tickle.md +++ /dev/null @@ -1,7 +0,0 @@ ---- -"@logto/core": patch ---- - -fix a bug that API resource indicator does not work if the indicator is not followed by a trailing slash or a pathname - -- Bump `oidc-provider@8.4.6` to fix the above issue diff --git a/.changeset/thirty-cameras-explain.md b/.changeset/thirty-cameras-explain.md deleted file mode 100644 index d8cf79297b2..00000000000 --- a/.changeset/thirty-cameras-explain.md +++ /dev/null @@ -1,13 +0,0 @@ ---- -"@logto/core": minor ---- - -update token grant to support organization API resources - -Organization roles can be assigned with scopes (permissions) from the API resources, and the token grant now supports this. - -Once the user is consent to an application with "resources" assigned, the token grant will now include the scopes inherited from all assigned organization roles. - -Users can narrow down the scopes by passing `organization_id` when granting an access token, and the token will only include the scopes from the organization roles of the specified organization, the access token will contain an extra claim `organization_id` to indicate the organization the token is granted for. Then the resource server can use this claim to protect the resource with additional organization-level authorization. - -This change is backward compatible, and the existing token grant will continue to work as before. diff --git a/packages/app-insights/CHANGELOG.md b/packages/app-insights/CHANGELOG.md index 8fb362efabb..cb2d34140a2 100644 --- a/packages/app-insights/CHANGELOG.md +++ b/packages/app-insights/CHANGELOG.md @@ -1,5 +1,15 @@ # @logto/app-insights +## 2.0.0 + +### Major Changes + +- c1c746bca: remove application insights for react + +### Patch Changes + +- a9ccfc738: allow additional telemetry for `trackException()` + ## 1.4.0 ### Minor Changes diff --git a/packages/app-insights/package.json b/packages/app-insights/package.json index f304cc1a1aa..d229f4ae450 100644 --- a/packages/app-insights/package.json +++ b/packages/app-insights/package.json @@ -1,6 +1,6 @@ { "name": "@logto/app-insights", - "version": "1.4.0", + "version": "2.0.0", "main": "lib/index.js", "author": "Silverhand Inc. ", "license": "MPL-2.0", diff --git a/packages/cli/CHANGELOG.md b/packages/cli/CHANGELOG.md index 44a57e0f0c3..e84dc4e98b1 100644 --- a/packages/cli/CHANGELOG.md +++ b/packages/cli/CHANGELOG.md @@ -1,5 +1,18 @@ # Change Log +## 1.16.0 + +### Patch Changes + +- Updated dependencies [21bb35b12] +- Updated dependencies [5b03030de] +- Updated dependencies [e8c41b164] +- Updated dependencies [21bb35b12] +- Updated dependencies [3486b12e8] + - @logto/schemas@1.16.0 + - @logto/phrases@1.10.1 + - @logto/shared@3.1.1 + ## 1.15.0 ### Patch Changes diff --git a/packages/cli/package.json b/packages/cli/package.json index 21574b67b93..56a6ce293f5 100644 --- a/packages/cli/package.json +++ b/packages/cli/package.json @@ -1,6 +1,6 @@ { "name": "@logto/cli", - "version": "1.15.0", + "version": "1.16.0", "description": "Logto CLI.", "author": "Silverhand Inc. ", "homepage": "https://github.com/logto-io/logto#readme", @@ -45,10 +45,10 @@ "@logto/connector-kit": "workspace:^3.0.0", "@logto/core-kit": "workspace:^2.4.0", "@logto/language-kit": "workspace:^1.1.0", - "@logto/phrases": "workspace:^1.10.0", + "@logto/phrases": "workspace:^1.10.1", "@logto/phrases-experience": "workspace:^1.6.1", - "@logto/schemas": "workspace:1.15.0", - "@logto/shared": "workspace:^3.1.0", + "@logto/schemas": "workspace:1.16.0", + "@logto/shared": "workspace:^3.1.1", "@silverhand/essentials": "^2.9.0", "@silverhand/slonik": "31.0.0-beta.2", "chalk": "^5.0.0", diff --git a/packages/connectors/connector-github/CHANGELOG.md b/packages/connectors/connector-github/CHANGELOG.md index 73b8a2eb0ee..1866264bb7c 100644 --- a/packages/connectors/connector-github/CHANGELOG.md +++ b/packages/connectors/connector-github/CHANGELOG.md @@ -1,5 +1,14 @@ # @logto/connector-github +## 1.4.0 + +### Minor Changes + +- 0227822b2: fetch GitHub account's private email address list and pick the verified primary email as a fallback + + - Add `user:email` as part of default scope to fetch GitHub account's private email address list + - Pick the verified primary email among private email address list as a fallback if the user does not set a public email for GitHub account + ## 1.3.0 ### Minor Changes diff --git a/packages/connectors/connector-github/package.json b/packages/connectors/connector-github/package.json index 83fa7cbc5f6..233070e6f2f 100644 --- a/packages/connectors/connector-github/package.json +++ b/packages/connectors/connector-github/package.json @@ -1,6 +1,6 @@ { "name": "@logto/connector-github", - "version": "1.3.0", + "version": "1.4.0", "description": "Github web connector implementation.", "author": "Silverhand Inc. ", "dependencies": { diff --git a/packages/connectors/connector-huggingface/CHANGELOG.md b/packages/connectors/connector-huggingface/CHANGELOG.md new file mode 100644 index 00000000000..a64bffe3fd9 --- /dev/null +++ b/packages/connectors/connector-huggingface/CHANGELOG.md @@ -0,0 +1,12 @@ +# @logto/connector-huggingface + +## 0.1.0 + +### Minor Changes + +- 3e5ffc499: add Hugging Face social connector + +### Patch Changes + +- Updated dependencies [f9c7a72d5] + - @logto/connector-oauth@1.3.0 diff --git a/packages/connectors/connector-huggingface/package.json b/packages/connectors/connector-huggingface/package.json index 10841e88466..ef45e49e5a1 100644 --- a/packages/connectors/connector-huggingface/package.json +++ b/packages/connectors/connector-huggingface/package.json @@ -1,11 +1,11 @@ { "name": "@logto/connector-huggingface", - "version": "0.0.0", + "version": "0.1.0", "description": "Hugging Face connector implementation.", "author": "Silverhand Inc. ", "dependencies": { "@logto/connector-kit": "workspace:^3.0.0", - "@logto/connector-oauth": "workspace:^1.2.0", + "@logto/connector-oauth": "workspace:^1.3.0", "@silverhand/essentials": "^2.9.0", "ky": "^1.2.3", "zod": "^3.22.4" diff --git a/packages/connectors/connector-oauth2/CHANGELOG.md b/packages/connectors/connector-oauth2/CHANGELOG.md index b8f64dd545f..a1f37599889 100644 --- a/packages/connectors/connector-oauth2/CHANGELOG.md +++ b/packages/connectors/connector-oauth2/CHANGELOG.md @@ -1,5 +1,16 @@ # @logto/connector-oauth +## 1.3.0 + +### Minor Changes + +- f9c7a72d5: Support `client_secret_basic` and `client_secret_jwt` token endpoint auth method for oauth & oidc connectors + +### Patch Changes + +- Updated dependencies [21bb35b12] + - @logto/shared@3.1.1 + ## 1.2.0 ### Minor Changes diff --git a/packages/connectors/connector-oauth2/package.json b/packages/connectors/connector-oauth2/package.json index d05c0b6a969..1049718658d 100644 --- a/packages/connectors/connector-oauth2/package.json +++ b/packages/connectors/connector-oauth2/package.json @@ -1,11 +1,11 @@ { "name": "@logto/connector-oauth", - "version": "1.2.0", + "version": "1.3.0", "description": "OAuth standard connector implementation.", "author": "Silverhand Inc. ", "dependencies": { "@logto/connector-kit": "workspace:^3.0.0", - "@logto/shared": "workspace:^3.1.0", + "@logto/shared": "workspace:^3.1.1", "@silverhand/essentials": "^2.9.0", "jose": "^5.0.0", "ky": "^1.2.3", diff --git a/packages/connectors/connector-oidc/CHANGELOG.md b/packages/connectors/connector-oidc/CHANGELOG.md index 028aa310b9a..c135a5550d1 100644 --- a/packages/connectors/connector-oidc/CHANGELOG.md +++ b/packages/connectors/connector-oidc/CHANGELOG.md @@ -1,5 +1,18 @@ # @logto/connector-oidc +## 1.3.0 + +### Minor Changes + +- f9c7a72d5: Support `client_secret_basic` and `client_secret_jwt` token endpoint auth method for oauth & oidc connectors + +### Patch Changes + +- Updated dependencies [f9c7a72d5] +- Updated dependencies [21bb35b12] + - @logto/connector-oauth@1.3.0 + - @logto/shared@3.1.1 + ## 1.2.0 ### Minor Changes diff --git a/packages/connectors/connector-oidc/package.json b/packages/connectors/connector-oidc/package.json index 41ee8d68fa5..50199345428 100644 --- a/packages/connectors/connector-oidc/package.json +++ b/packages/connectors/connector-oidc/package.json @@ -1,11 +1,11 @@ { "name": "@logto/connector-oidc", - "version": "1.2.0", + "version": "1.3.0", "description": "OIDC standard connector implementation.", "dependencies": { "@logto/connector-kit": "workspace:^3.0.0", - "@logto/connector-oauth": "workspace:^1.2.0", - "@logto/shared": "workspace:^3.1.0", + "@logto/connector-oauth": "workspace:^1.3.0", + "@logto/shared": "workspace:^3.1.1", "@silverhand/essentials": "^2.9.0", "jose": "^5.0.0", "ky": "^1.2.3", diff --git a/packages/console/CHANGELOG.md b/packages/console/CHANGELOG.md index 1d632565e22..31946e9f97b 100644 --- a/packages/console/CHANGELOG.md +++ b/packages/console/CHANGELOG.md @@ -1,5 +1,31 @@ # Change Log +## 1.14.0 + +### Minor Changes + +- 21bb35b12: refactor the definition of hook event types + + - Add `DataHook` event types. `DataHook` are triggered by data changes. + - Add "interaction" prefix to existing hook event types. Interaction hook events are triggered by end user interactions, e.g. completing sign-in. + +- 5872172cb: enable custom JWT feature for OSS version + + OSS version users can now use custom JWT feature to add custom claims to JWT access tokens payload (previously, this feature was only available to Logto Cloud). + +- 6fe6f87bc: support adding API resource permissions to organization roles and organization permissions in 3rd-party applications + + ## Updates + + - Separated the "Organization template" from the "Organization" page, establishing it as a standalone page for clearer navigation and functionality. + - Enhanced the "Organization template" page by adding functionality that allows users to click on an organization role, which then navigates to the organization role details page where users can view its corresponding permissions and general settings. + - Enabled the assignment of API resource permissions directly from the organization role details page, improving role management and access control. + - Split the permission list for third-party apps into two separate lists: user permissions and organization permissions. Users can now add user profile permissions and API resource permissions for users under user permissions, and add organization permissions and API resource permissions for organizations under organization permissions. + +### Patch Changes + +- 9cf03c8ed: Add Java Spring Boot web integration guide to the application creation page + ## 1.13.0 ### Minor Changes diff --git a/packages/console/package.json b/packages/console/package.json index da6a8649509..5a9e24c6c50 100644 --- a/packages/console/package.json +++ b/packages/console/package.json @@ -1,6 +1,6 @@ { "name": "@logto/console", - "version": "1.13.0", + "version": "1.14.0", "description": "> TODO: description", "author": "Silverhand Inc. ", "homepage": "https://github.com/logto-io/logto#readme", @@ -31,11 +31,11 @@ "@logto/connector-kit": "workspace:^3.0.0", "@logto/core-kit": "workspace:^2.4.0", "@logto/language-kit": "workspace:^1.1.0", - "@logto/phrases": "workspace:^1.10.0", + "@logto/phrases": "workspace:^1.10.1", "@logto/phrases-experience": "workspace:^1.6.1", "@logto/react": "^3.0.8", - "@logto/schemas": "workspace:^1.15.0", - "@logto/shared": "workspace:^3.1.0", + "@logto/schemas": "workspace:^1.16.0", + "@logto/shared": "workspace:^3.1.1", "@mdx-js/react": "^1.6.22", "@monaco-editor/react": "^4.6.0", "@parcel/compressor-brotli": "2.9.3", diff --git a/packages/core/CHANGELOG.md b/packages/core/CHANGELOG.md index e8c4dd10bc6..e77119e5bbb 100644 --- a/packages/core/CHANGELOG.md +++ b/packages/core/CHANGELOG.md @@ -1,5 +1,123 @@ # Change Log +## 1.16.0 + +### Minor Changes + +- 8ef021fb3: add support for Redis Cluster and extra TLS options for Redis connections +- 21bb35b12: refactor the definition of hook event types + + - Add `DataHook` event types. `DataHook` are triggered by data changes. + - Add "interaction" prefix to existing hook event types. Interaction hook events are triggered by end user interactions, e.g. completing sign-in. + +- e8c41b164: support organization custom data + + Now you can save additional data associated with the organization with the organization-level `customData` field by: + + - Edit in the Console organization details page. + - Specify `customData` field when using organization Management APIs. + +- 5872172cb: enable custom JWT feature for OSS version + + OSS version users can now use custom JWT feature to add custom claims to JWT access tokens payload (previously, this feature was only available to Logto Cloud). + +- 1ef32d6d5: update token grant to support organization API resources + + Organization roles can be assigned with scopes (permissions) from the API resources, and the token grant now supports this. + + Once the user is consent to an application with "resources" assigned, the token grant will now include the scopes inherited from all assigned organization roles. + + Users can narrow down the scopes by passing `organization_id` when granting an access token, and the token will only include the scopes from the organization roles of the specified organization, the access token will contain an extra claim `organization_id` to indicate the organization the token is granted for. Then the resource server can use this claim to protect the resource with additional organization-level authorization. + + This change is backward compatible, and the existing token grant will continue to work as before. + +### Patch Changes + +- 52df3ebbb: Bug fix: organization invitation APIs should handle invitee emails case insensitively +- 368385b93: Management API will not return 500 in production for status codes that are not listed in the OpenAPI spec +- d54530356: Fix OIDC AccessDenied error code to 403. + + This error may happen when you try to grant an access token to a user lacking the required permissions, especially when granting for orgnization related resources. The error code should be 403 instead of 400. + +- 5b03030de: Not allow to modify management API resource through API. + + Previously, management API resource and its scopes are readonly in Console. But it was possible to modify through the API. This is not allowed anymore. + +- 5660c54cb: Sign out user after deletion or suspension + + When a user is deleted or suspended through Management API, they should be signed out immediately, including sessions and refresh tokens. + +- a9ccfc738: implement request ID for API requests + + - All requests will now include a request ID in the headers (`Logto-Core-Request-Id`) + - Terminal logs will now include the request ID as the prefix + +- bbd399e15: fix the new user from SSO register hook event not triggering bug + + ### Issue + + When a new user registers via SSO, the `PostRegister` interaction hook event is not triggered. `PostSignIn` event is mistakenly triggered instead. + + ### Root Cause + + In the SSO `post /api/interaction/sso/:connectionId/registration` API, we update the interaction event to `Register`. + However, the hook middleware reads the event from interaction session ahead of the API logic, and the event is not updated resulting in the wrong event being triggered. + + In the current interaction API design, we should mutate the interaction event by calling the `PUT /api/interaction/event` API, instead of updating the event directly in the submit interaction APIs. (Just like the no direct mutation rule for a react state). So we can ensure the correct side effect like logs and hooks are triggered properly. + + All the other sign-in methods are using the `PUT /api/interaction/event` API to update the event. But when implementing the SSO registration API, we were trying to reduce the API requests and directly updated the event in the registration API which will submit the interaction directly. + + ### Solution + + Remove the event update logic in the SSO registration API and call the `PUT /api/interaction/event` API to update the event. + This will ensure the correct event is triggered in the hook middleware. + + ### Action Items + + Align the current interaction API design for now. + Need to improve the session/interaction API logic to simplify the whole process. + +- b4b8015db: fix a bug that prevents invitee from accepting the organization invitation if the email letter case is not matching +- b575f57ac: Support comma separated resource parameter + + Some third-party libraries or plugins do not support array of resources, and can only specify `resource` through `additionalParameters` config, e.g. `flutter-appauth`. However, only one resource can be specified at a time in this way. This PR enables comma separated resource parameter support in Logto core service, so that multiple resources can be specified via a single string. + + For example: Auth URL like `/oidc/auth?resource=https://example.com/api1,https://example.com/api2` will be interpreted and parsed to Logto core service as `/ordc/auth?resource=https://example.com/api1&resource=https://example.com/api2`. + +- aacbebcbc: Provide management API to fetch user organization scopes based on user organization roles + + - GET `organizations/:id/users/:userId/scopes` + +- 3486b12e8: Fix file upload API. + + The `koa-body` has been upgraded to the latest version, which caused the file upload API to break. This change fixes the issue. + + The `ctx.request.files.file` in the new version is an array, so the code has been updated to pick the first one. + +- ead2abde6: fix a bug that API resource indicator does not work if the indicator is not followed by a trailing slash or a pathname + + - Bump `oidc-provider@8.4.6` to fix the above issue + +- Updated dependencies [21bb35b12] +- Updated dependencies [5b03030de] +- Updated dependencies [b80934ac5] +- Updated dependencies [a9ccfc738] +- Updated dependencies [e8c41b164] +- Updated dependencies [5872172cb] +- Updated dependencies [6fe6f87bc] +- Updated dependencies [21bb35b12] +- Updated dependencies [bbd399e15] +- Updated dependencies [3486b12e8] +- Updated dependencies [9cf03c8ed] +- Updated dependencies [c1c746bca] + - @logto/schemas@1.16.0 + - @logto/console@1.14.0 + - @logto/phrases@1.10.1 + - @logto/experience@1.6.1 + - @logto/app-insights@2.0.0 + - @logto/shared@3.1.1 + - @logto/cli@1.16.0 + ## 1.15.0 ### Minor Changes diff --git a/packages/core/package.json b/packages/core/package.json index 66659006127..49bf3027824 100644 --- a/packages/core/package.json +++ b/packages/core/package.json @@ -1,6 +1,6 @@ { "name": "@logto/core", - "version": "1.15.0", + "version": "1.16.0", "description": "The open source identity solution.", "main": "build/index.js", "author": "Silverhand Inc. ", @@ -31,18 +31,18 @@ "@google-cloud/storage": "^7.10.0", "@koa/cors": "^5.0.0", "@logto/affiliate": "^0.1.0", - "@logto/app-insights": "workspace:^1.4.0", - "@logto/cli": "workspace:^1.15.0", + "@logto/app-insights": "workspace:^2.0.0", + "@logto/cli": "workspace:^1.16.0", "@logto/connector-kit": "workspace:^3.0.0", "@logto/console": "workspace:*", "@logto/core-kit": "workspace:^2.4.0", "@logto/demo-app": "workspace:*", "@logto/experience": "workspace:*", "@logto/language-kit": "workspace:^1.1.0", - "@logto/phrases": "workspace:^1.10.0", + "@logto/phrases": "workspace:^1.10.1", "@logto/phrases-experience": "workspace:^1.6.1", - "@logto/schemas": "workspace:^1.15.0", - "@logto/shared": "workspace:^3.1.0", + "@logto/schemas": "workspace:^1.16.0", + "@logto/shared": "workspace:^3.1.1", "@silverhand/essentials": "^2.9.0", "@silverhand/slonik": "31.0.0-beta.2", "@simplewebauthn/server": "^10.0.0", diff --git a/packages/create/CHANGELOG.md b/packages/create/CHANGELOG.md index c5a425275d2..a5d5e5b0a8a 100644 --- a/packages/create/CHANGELOG.md +++ b/packages/create/CHANGELOG.md @@ -1,5 +1,11 @@ # Change Log +## 1.16.0 + +### Patch Changes + +- @logto/cli@1.16.0 + ## 1.15.0 ### Patch Changes diff --git a/packages/create/package.json b/packages/create/package.json index bbd1ad8189c..549b51fd589 100644 --- a/packages/create/package.json +++ b/packages/create/package.json @@ -1,6 +1,6 @@ { "name": "@logto/create", - "version": "1.15.0", + "version": "1.16.0", "author": "Silverhand Inc. ", "license": "MPL-2.0", "type": "module", @@ -15,6 +15,6 @@ "node": "^20.9.0" }, "dependencies": { - "@logto/cli": "workspace:^1.15.0" + "@logto/cli": "workspace:^1.16.0" } } diff --git a/packages/experience/CHANGELOG.md b/packages/experience/CHANGELOG.md index 444e95c4a7e..2788635a8b6 100644 --- a/packages/experience/CHANGELOG.md +++ b/packages/experience/CHANGELOG.md @@ -1,5 +1,40 @@ # Change Log +## 1.6.1 + +### Patch Changes + +- b80934ac5: fix native social sign-in callback + + In a native environment, the social sign-in callback that posts to the native container (e.g. WKWebView in iOS) was wrong. + + This was introduced by a refactor in #5536: It updated the callback path from `/sign-in/social/:connectorId` to `/callback/social/:connectorId`. However, the function to post the message to the native container was not updated accordingly. + +- bbd399e15: fix the new user from SSO register hook event not triggering bug + + ### Issue + + When a new user registers via SSO, the `PostRegister` interaction hook event is not triggered. `PostSignIn` event is mistakenly triggered instead. + + ### Root Cause + + In the SSO `post /api/interaction/sso/:connectionId/registration` API, we update the interaction event to `Register`. + However, the hook middleware reads the event from interaction session ahead of the API logic, and the event is not updated resulting in the wrong event being triggered. + + In the current interaction API design, we should mutate the interaction event by calling the `PUT /api/interaction/event` API, instead of updating the event directly in the submit interaction APIs. (Just like the no direct mutation rule for a react state). So we can ensure the correct side effect like logs and hooks are triggered properly. + + All the other sign-in methods are using the `PUT /api/interaction/event` API to update the event. But when implementing the SSO registration API, we were trying to reduce the API requests and directly updated the event in the registration API which will submit the interaction directly. + + ### Solution + + Remove the event update logic in the SSO registration API and call the `PUT /api/interaction/event` API to update the event. + This will ensure the correct event is triggered in the hook middleware. + + ### Action Items + + Align the current interaction API design for now. + Need to improve the session/interaction API logic to simplify the whole process. + ## 1.6.0 ### Minor Changes diff --git a/packages/experience/package.json b/packages/experience/package.json index 7f5685163e1..72a4d545543 100644 --- a/packages/experience/package.json +++ b/packages/experience/package.json @@ -1,6 +1,6 @@ { "name": "@logto/experience", - "version": "1.6.0", + "version": "1.6.1", "license": "MPL-2.0", "type": "module", "private": true, @@ -24,9 +24,9 @@ "@logto/connector-kit": "workspace:^3.0.0", "@logto/core-kit": "workspace:^2.4.0", "@logto/language-kit": "workspace:^1.1.0", - "@logto/phrases": "workspace:^1.10.0", + "@logto/phrases": "workspace:^1.10.1", "@logto/phrases-experience": "workspace:^1.6.1", - "@logto/schemas": "workspace:^1.15.0", + "@logto/schemas": "workspace:^1.16.0", "@parcel/compressor-brotli": "2.9.3", "@parcel/compressor-gzip": "2.9.3", "@parcel/core": "2.9.3", diff --git a/packages/integration-tests/CHANGELOG.md b/packages/integration-tests/CHANGELOG.md index ed211b8a2cc..bf99ba1a5d6 100644 --- a/packages/integration-tests/CHANGELOG.md +++ b/packages/integration-tests/CHANGELOG.md @@ -1,5 +1,13 @@ # Change Log +## 1.6.1 + +### Patch Changes + +- 5b03030de: Not allow to modify management API resource through API. + + Previously, management API resource and its scopes are readonly in Console. But it was possible to modify through the API. This is not allowed anymore. + ## 1.6.0 ### Minor Changes diff --git a/packages/integration-tests/package.json b/packages/integration-tests/package.json index b336684a136..606ed82df9f 100644 --- a/packages/integration-tests/package.json +++ b/packages/integration-tests/package.json @@ -1,6 +1,6 @@ { "name": "@logto/integration-tests", - "version": "1.6.0", + "version": "1.6.1", "description": "Integration tests for Logto.", "author": "Silverhand Inc. ", "license": "MPL-2.0", @@ -28,8 +28,8 @@ "@logto/core-kit": "workspace:^", "@logto/js": "^4.1.1", "@logto/node": "^2.4.7", - "@logto/schemas": "workspace:^1.15.0", - "@logto/shared": "workspace:^3.1.0", + "@logto/schemas": "workspace:^1.16.0", + "@logto/shared": "workspace:^3.1.1", "@silverhand/eslint-config": "6.0.1", "@silverhand/essentials": "^2.9.0", "@silverhand/ts-config": "6.0.0", diff --git a/packages/phrases/CHANGELOG.md b/packages/phrases/CHANGELOG.md index 3c45d4b5d28..645d66c5419 100644 --- a/packages/phrases/CHANGELOG.md +++ b/packages/phrases/CHANGELOG.md @@ -1,5 +1,19 @@ # Change Log +## 1.10.1 + +### Patch Changes + +- 5b03030de: Not allow to modify management API resource through API. + + Previously, management API resource and its scopes are readonly in Console. But it was possible to modify through the API. This is not allowed anymore. + +- 3486b12e8: Fix file upload API. + + The `koa-body` has been upgraded to the latest version, which caused the file upload API to break. This change fixes the issue. + + The `ctx.request.files.file` in the new version is an array, so the code has been updated to pick the first one. + ## 1.10.0 ### Minor Changes diff --git a/packages/phrases/package.json b/packages/phrases/package.json index 993510ad3a5..6e867bc6f95 100644 --- a/packages/phrases/package.json +++ b/packages/phrases/package.json @@ -1,6 +1,6 @@ { "name": "@logto/phrases", - "version": "1.10.0", + "version": "1.10.1", "description": "Logto shared phrases (i18n).", "author": "Silverhand Inc. ", "homepage": "https://github.com/logto-io/logto#readme", diff --git a/packages/schemas/CHANGELOG.md b/packages/schemas/CHANGELOG.md index 383fb91185a..aaaaef2c337 100644 --- a/packages/schemas/CHANGELOG.md +++ b/packages/schemas/CHANGELOG.md @@ -1,5 +1,29 @@ # Change Log +## 1.16.0 + +### Minor Changes + +- 21bb35b12: refactor the definition of hook event types + + - Add `DataHook` event types. `DataHook` are triggered by data changes. + - Add "interaction" prefix to existing hook event types. Interaction hook events are triggered by end user interactions, e.g. completing sign-in. + +- e8c41b164: support organization custom data + + Now you can save additional data associated with the organization with the organization-level `customData` field by: + + - Edit in the Console organization details page. + - Specify `customData` field when using organization Management APIs. + +### Patch Changes + +- Updated dependencies [5b03030de] +- Updated dependencies [21bb35b12] +- Updated dependencies [3486b12e8] + - @logto/phrases@1.10.1 + - @logto/shared@3.1.1 + ## 1.15.0 ### Minor Changes diff --git a/packages/schemas/alterations/next-1712912361-delete-jwt-customier-with-empty-script.ts b/packages/schemas/alterations/1.16.0-1712912361-delete-jwt-customier-with-empty-script.ts similarity index 100% rename from packages/schemas/alterations/next-1712912361-delete-jwt-customier-with-empty-script.ts rename to packages/schemas/alterations/1.16.0-1712912361-delete-jwt-customier-with-empty-script.ts diff --git a/packages/schemas/alterations/next-1713942039-add-organization-custom-data.ts b/packages/schemas/alterations/1.16.0-1713942039-add-organization-custom-data.ts similarity index 100% rename from packages/schemas/alterations/next-1713942039-add-organization-custom-data.ts rename to packages/schemas/alterations/1.16.0-1713942039-add-organization-custom-data.ts diff --git a/packages/schemas/alterations/next-1714270244-application-org-resource-scope.ts b/packages/schemas/alterations/1.16.0-1714270244-application-org-resource-scope.ts similarity index 100% rename from packages/schemas/alterations/next-1714270244-application-org-resource-scope.ts rename to packages/schemas/alterations/1.16.0-1714270244-application-org-resource-scope.ts diff --git a/packages/schemas/package.json b/packages/schemas/package.json index 503752f159a..481cfb4f51d 100644 --- a/packages/schemas/package.json +++ b/packages/schemas/package.json @@ -1,6 +1,6 @@ { "name": "@logto/schemas", - "version": "1.15.0", + "version": "1.16.0", "author": "Silverhand Inc. ", "license": "MPL-2.0", "type": "module", @@ -81,9 +81,9 @@ "@logto/connector-kit": "workspace:^3.0.0", "@logto/core-kit": "workspace:^2.4.0", "@logto/language-kit": "workspace:^1.1.0", - "@logto/phrases": "workspace:^1.10.0", + "@logto/phrases": "workspace:^1.10.1", "@logto/phrases-experience": "workspace:^1.6.1", - "@logto/shared": "workspace:^3.1.0", + "@logto/shared": "workspace:^3.1.1", "@withtyped/server": "^0.13.6" }, "peerDependencies": { diff --git a/packages/shared/CHANGELOG.md b/packages/shared/CHANGELOG.md index 372951b2e7b..9d60f600a7a 100644 --- a/packages/shared/CHANGELOG.md +++ b/packages/shared/CHANGELOG.md @@ -1,5 +1,13 @@ # Change Log +## 3.1.1 + +### Patch Changes + +- 21bb35b12: add `normalizeError` method to `@logto/shared` package + + Use this method to normalize error objects for logging. This method is useful for logging errors in a consistent format. + ## 3.1.0 ### Minor Changes diff --git a/packages/shared/package.json b/packages/shared/package.json index d667762af30..431bbbd2468 100644 --- a/packages/shared/package.json +++ b/packages/shared/package.json @@ -1,6 +1,6 @@ { "name": "@logto/shared", - "version": "3.1.0", + "version": "3.1.1", "main": "lib/index.js", "author": "Silverhand Inc. ", "license": "MPL-2.0", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index f87002d9833..7c8fc1b7a90 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -92,16 +92,16 @@ importers: specifier: workspace:^1.1.0 version: link:../toolkit/language-kit '@logto/phrases': - specifier: workspace:^1.10.0 + specifier: workspace:^1.10.1 version: link:../phrases '@logto/phrases-experience': specifier: workspace:^1.6.1 version: link:../phrases-experience '@logto/schemas': - specifier: workspace:1.15.0 + specifier: workspace:1.16.0 version: link:../schemas '@logto/shared': - specifier: workspace:^3.1.0 + specifier: workspace:^3.1.1 version: link:../shared '@silverhand/essentials': specifier: ^2.9.0 @@ -1128,7 +1128,7 @@ importers: specifier: workspace:^3.0.0 version: link:../../toolkit/connector-kit '@logto/connector-oauth': - specifier: workspace:^1.2.0 + specifier: workspace:^1.3.0 version: link:../connector-oauth2 '@silverhand/essentials': specifier: ^2.9.0 @@ -1934,7 +1934,7 @@ importers: specifier: workspace:^3.0.0 version: link:../../toolkit/connector-kit '@logto/shared': - specifier: workspace:^3.1.0 + specifier: workspace:^3.1.1 version: link:../../shared '@silverhand/essentials': specifier: ^2.9.0 @@ -2016,10 +2016,10 @@ importers: specifier: workspace:^3.0.0 version: link:../../toolkit/connector-kit '@logto/connector-oauth': - specifier: workspace:^1.2.0 + specifier: workspace:^1.3.0 version: link:../connector-oauth2 '@logto/shared': - specifier: workspace:^3.1.0 + specifier: workspace:^3.1.1 version: link:../../shared '@silverhand/essentials': specifier: ^2.9.0 @@ -2785,7 +2785,7 @@ importers: specifier: workspace:^1.1.0 version: link:../toolkit/language-kit '@logto/phrases': - specifier: workspace:^1.10.0 + specifier: workspace:^1.10.1 version: link:../phrases '@logto/phrases-experience': specifier: workspace:^1.6.1 @@ -2794,10 +2794,10 @@ importers: specifier: ^3.0.8 version: 3.0.8(react@18.2.0) '@logto/schemas': - specifier: workspace:^1.15.0 + specifier: workspace:^1.16.0 version: link:../schemas '@logto/shared': - specifier: workspace:^3.1.0 + specifier: workspace:^3.1.1 version: link:../shared '@mdx-js/react': specifier: ^1.6.22 @@ -3091,10 +3091,10 @@ importers: specifier: ^0.1.0 version: 0.1.0 '@logto/app-insights': - specifier: workspace:^1.4.0 + specifier: workspace:^2.0.0 version: link:../app-insights '@logto/cli': - specifier: workspace:^1.15.0 + specifier: workspace:^1.16.0 version: link:../cli '@logto/connector-kit': specifier: workspace:^3.0.0 @@ -3115,16 +3115,16 @@ importers: specifier: workspace:^1.1.0 version: link:../toolkit/language-kit '@logto/phrases': - specifier: workspace:^1.10.0 + specifier: workspace:^1.10.1 version: link:../phrases '@logto/phrases-experience': specifier: workspace:^1.6.1 version: link:../phrases-experience '@logto/schemas': - specifier: workspace:^1.15.0 + specifier: workspace:^1.16.0 version: link:../schemas '@logto/shared': - specifier: workspace:^3.1.0 + specifier: workspace:^3.1.1 version: link:../shared '@silverhand/essentials': specifier: ^2.9.0 @@ -3371,7 +3371,7 @@ importers: packages/create: dependencies: '@logto/cli': - specifier: workspace:^1.15.0 + specifier: workspace:^1.16.0 version: link:../cli packages/demo-app: @@ -3476,13 +3476,13 @@ importers: specifier: workspace:^1.1.0 version: link:../toolkit/language-kit '@logto/phrases': - specifier: workspace:^1.10.0 + specifier: workspace:^1.10.1 version: link:../phrases '@logto/phrases-experience': specifier: workspace:^1.6.1 version: link:../phrases-experience '@logto/schemas': - specifier: workspace:^1.15.0 + specifier: workspace:^1.16.0 version: link:../schemas '@parcel/compressor-brotli': specifier: 2.9.3 @@ -3705,10 +3705,10 @@ importers: specifier: ^2.4.7 version: 2.4.7 '@logto/schemas': - specifier: workspace:^1.15.0 + specifier: workspace:^1.16.0 version: link:../schemas '@logto/shared': - specifier: workspace:^3.1.0 + specifier: workspace:^3.1.1 version: link:../shared '@silverhand/eslint-config': specifier: 6.0.1 @@ -3851,13 +3851,13 @@ importers: specifier: workspace:^1.1.0 version: link:../toolkit/language-kit '@logto/phrases': - specifier: workspace:^1.10.0 + specifier: workspace:^1.10.1 version: link:../phrases '@logto/phrases-experience': specifier: workspace:^1.6.1 version: link:../phrases-experience '@logto/shared': - specifier: workspace:^3.1.0 + specifier: workspace:^3.1.1 version: link:../shared '@withtyped/server': specifier: ^0.13.6 From 5462ab4765eb6025c0bc3411e313a2b0bda23ed7 Mon Sep 17 00:00:00 2001 From: simeng-li Date: Wed, 15 May 2024 11:17:46 +0800 Subject: [PATCH 390/687] feat(core): trigger user create DataHook event on user registration (#5837) * feat(core): trigger user data hook event on interaction api call trigger user data hook event on interaction api call * chore(core): refine comments refine comments * fix(core): fix the interactionHookMiddleware fix the interactionHookMiddleware * test(core): add integration tests add integration tests for interaction hooks * chore(test): remove legacy test remove legacy test --- .../src/libraries/hook/context-manager.ts | 2 +- .../src/routes/interaction/actions/helpers.ts | 13 +- .../actions/submit-interaction.mfa.test.ts | 1 + .../actions/submit-interaction.test.ts | 83 +++- .../interaction/actions/submit-interaction.ts | 35 +- .../middleware/koa-interaction-hooks.ts | 54 ++- .../src/routes/interaction/single-sign-on.ts | 7 +- .../interaction/utils/single-sign-on.test.ts | 6 +- .../interaction/utils/single-sign-on.ts | 10 +- .../src/helpers/connector.ts | 11 +- .../integration-tests/src/helpers/hook.ts | 32 +- .../src/helpers/interactions.ts | 43 +- .../src/tests/api/hook/WebhookMockServer.ts | 29 +- .../tests/api/hook/hook.trigger.data.test.ts | 69 +-- .../api/hook/hook.trigger.interaction.test.ts | 439 +++++++++--------- .../happy-path.test.ts | 202 ++------ 16 files changed, 573 insertions(+), 463 deletions(-) diff --git a/packages/core/src/libraries/hook/context-manager.ts b/packages/core/src/libraries/hook/context-manager.ts index b4ac5f6f7cf..1c0984b94fb 100644 --- a/packages/core/src/libraries/hook/context-manager.ts +++ b/packages/core/src/libraries/hook/context-manager.ts @@ -35,7 +35,7 @@ type InteractionHookMetadata = { * In the `koaInteractionHooks` middleware, * if we get an interaction hook result after the interaction is processed, related hooks will be triggered. */ -export type InteractionHookResult = { +type InteractionHookResult = { userId: string; }; diff --git a/packages/core/src/routes/interaction/actions/helpers.ts b/packages/core/src/routes/interaction/actions/helpers.ts index 9bc5629a5f5..5e32d586c77 100644 --- a/packages/core/src/routes/interaction/actions/helpers.ts +++ b/packages/core/src/routes/interaction/actions/helpers.ts @@ -1,5 +1,5 @@ import { defaults, parseAffiliateData } from '@logto/affiliate'; -import { type CreateUser, type User, adminTenantId } from '@logto/schemas'; +import { adminTenantId, type CreateUser, type User } from '@logto/schemas'; import { conditional, trySafe } from '@silverhand/essentials'; import { type IRouterContext } from 'koa-router'; @@ -15,8 +15,8 @@ import { type OmitAutoSetFields } from '#src/utils/sql.js'; import { type Identifier, type SocialIdentifier, - type VerifiedSignInInteractionResult, type VerifiedRegisterInteractionResult, + type VerifiedSignInInteractionResult, } from '../types/index.js'; import { categorizeIdentifiers } from '../utils/interaction.js'; @@ -149,3 +149,12 @@ export const postAffiliateLogs = async ( getConsoleLogFromContext(ctx).info('Affiliate logs posted', userId); } }; + +/* Verify if user has updated profile */ +export const hasUpdatedProfile = ({ + lastSignInAt, + ...profile +}: Omit, 'id'>) => { + // Check if the lastSignInAt is the only field in the updated profile + return Object.keys(profile).length > 0; +}; diff --git a/packages/core/src/routes/interaction/actions/submit-interaction.mfa.test.ts b/packages/core/src/routes/interaction/actions/submit-interaction.mfa.test.ts index 9d3fbe9aefe..e45458c1329 100644 --- a/packages/core/src/routes/interaction/actions/submit-interaction.mfa.test.ts +++ b/packages/core/src/routes/interaction/actions/submit-interaction.mfa.test.ts @@ -73,6 +73,7 @@ describe('submit action', () => { // eslint-disable-next-line @typescript-eslint/consistent-type-assertions interactionDetails: { params: {} } as Awaited>, assignInteractionHookResult: jest.fn(), + assignDataHookContext: jest.fn(), }; const profile = { username: 'username', diff --git a/packages/core/src/routes/interaction/actions/submit-interaction.test.ts b/packages/core/src/routes/interaction/actions/submit-interaction.test.ts index bc9007ac851..c34d4a0bc98 100644 --- a/packages/core/src/routes/interaction/actions/submit-interaction.test.ts +++ b/packages/core/src/routes/interaction/actions/submit-interaction.test.ts @@ -1,4 +1,11 @@ -import { InteractionEvent, adminConsoleApplicationId, adminTenantId } from '@logto/schemas'; +/* eslint-disable max-lines */ +import { + InteractionEvent, + adminConsoleApplicationId, + adminTenantId, + type CreateUser, + type User, +} from '@logto/schemas'; import { createMockUtils, pickDefault } from '@logto/shared/esm'; import type Provider from 'oidc-provider'; @@ -8,9 +15,9 @@ import { createContextWithRouteParameters } from '#src/utils/test-utils.js'; import type { Identifier, + VerifiedForgotPasswordInteractionResult, VerifiedRegisterInteractionResult, VerifiedSignInInteractionResult, - VerifiedForgotPasswordInteractionResult, } from '../types/index.js'; import { userMfaDataKey } from '../verifications/mfa-verification.js'; @@ -45,7 +52,7 @@ const userQueries = { identities: { google: { userId: 'googleId', details: {} } }, mfaVerifications: [], }), - updateUserById: jest.fn(), + updateUserById: jest.fn(async (id: string, user: Partial) => user as User), hasActiveUsers: jest.fn().mockResolvedValue(true), hasUserWithEmail: jest.fn().mockResolvedValue(false), hasUserWithPhone: jest.fn().mockResolvedValue(false), @@ -53,7 +60,10 @@ const userQueries = { const { hasActiveUsers, updateUserById, hasUserWithEmail, hasUserWithPhone } = userQueries; -const userLibraries = { generateUserId: jest.fn().mockResolvedValue('uid'), insertUser: jest.fn() }; +const userLibraries = { + generateUserId: jest.fn().mockResolvedValue('uid'), + insertUser: jest.fn(async (user: CreateUser) => user as User), +}; const { generateUserId, insertUser } = userLibraries; const submitInteraction = await pickDefault(import('./submit-interaction.js')); @@ -74,6 +84,7 @@ describe('submit action', () => { // eslint-disable-next-line @typescript-eslint/consistent-type-assertions interactionDetails: { params: {} } as Awaited>, assignInteractionHookResult: jest.fn(), + assignDataHookContext: jest.fn(), }; const profile = { username: 'username', @@ -141,6 +152,14 @@ describe('submit action', () => { expect(assignInteractionResults).toBeCalledWith(ctx, tenant.provider, { login: { accountId: 'uid' }, }); + + expect(ctx.assignDataHookContext).toBeCalledWith({ + event: 'User.Created', + user: { + id: 'uid', + ...upsertProfile, + }, + }); }); it('register and use pendingAccountId', async () => { @@ -168,6 +187,14 @@ describe('submit action', () => { expect(assignInteractionResults).toBeCalledWith(ctx, tenant.provider, { login: { accountId: 'pending-account-id' }, }); + + expect(ctx.assignDataHookContext).toBeCalledWith({ + event: 'User.Created', + user: { + id: 'pending-account-id', + ...upsertProfile, + }, + }); }); it('register with mfaSkipped', async () => { @@ -294,11 +321,30 @@ describe('submit action', () => { }); }); + it('sign-in without new profile', async () => { + const interaction: VerifiedSignInInteractionResult = { + event: InteractionEvent.SignIn, + accountId: 'foo', + identifiers: [{ key: 'accountId', value: 'foo' }], + }; + + await submitInteraction(interaction, ctx, tenant); + + expect(updateUserById).toBeCalledWith('foo', { + lastSignInAt: now, + }); + expect(assignInteractionResults).toBeCalledWith(ctx, tenant.provider, { + login: { accountId: 'foo' }, + }); + expect(ctx.assignDataHookContext).not.toBeCalled(); + }); + it('sign-in with new profile', async () => { getLogtoConnectorById.mockResolvedValueOnce({ metadata: { target: 'logto' }, dbEntry: { syncProfile: false }, }); + const interaction: VerifiedSignInInteractionResult = { event: InteractionEvent.SignIn, accountId: 'foo', @@ -311,7 +357,7 @@ describe('submit action', () => { expect(encryptUserPassword).toBeCalledWith('password'); expect(getLogtoConnectorById).toBeCalledWith('logto'); - expect(updateUserById).toBeCalledWith('foo', { + const updateProfile = { passwordEncrypted: 'passwordEncrypted', passwordEncryptionMethod: 'plain', identities: { @@ -319,10 +365,16 @@ describe('submit action', () => { google: { userId: 'googleId', details: {} }, }, lastSignInAt: now, - }); + }; + + expect(updateUserById).toBeCalledWith('foo', updateProfile); expect(assignInteractionResults).toBeCalledWith(ctx, tenant.provider, { login: { accountId: 'foo' }, }); + expect(ctx.assignDataHookContext).toBeCalledWith({ + event: 'User.Updated', + user: updateProfile, + }); }); it('sign-in with mfaSkipped', async () => { @@ -380,6 +432,15 @@ describe('submit action', () => { expect(assignInteractionResults).toBeCalledWith(ctx, tenant.provider, { login: { accountId: 'foo' }, }); + expect(ctx.assignDataHookContext).toBeCalledWith({ + event: 'User.Updated', + user: { + primaryEmail: 'email', + name: userInfo.name, + avatar: userInfo.avatar, + lastSignInAt: now, + }, + }); }); it('reset password', async () => { @@ -392,12 +453,18 @@ describe('submit action', () => { await submitInteraction(interaction, ctx, tenant); expect(encryptUserPassword).toBeCalledWith('password'); - expect(updateUserById).toBeCalledWith('foo', { passwordEncrypted: 'passwordEncrypted', passwordEncryptionMethod: 'plain', }); - expect(assignInteractionResults).not.toBeCalled(); + expect(ctx.assignDataHookContext).toBeCalledWith({ + event: 'User.Updated', + user: { + passwordEncrypted: 'passwordEncrypted', + passwordEncryptionMethod: 'plain', + }, + }); }); }); +/* eslint-enable max-lines */ diff --git a/packages/core/src/routes/interaction/actions/submit-interaction.ts b/packages/core/src/routes/interaction/actions/submit-interaction.ts index a16cea0275a..c3670cc66bd 100644 --- a/packages/core/src/routes/interaction/actions/submit-interaction.ts +++ b/packages/core/src/routes/interaction/actions/submit-interaction.ts @@ -3,17 +3,17 @@ import { appInsights } from '@logto/app-insights/node'; import type { User, UserOnboardingData } from '@logto/schemas'; import { AdminTenantRole, - SignInMode, - defaultTenantId, - adminTenantId, InteractionEvent, - adminConsoleApplicationId, MfaFactor, - getTenantOrganizationId, - getTenantRole, + OrganizationInvitationStatus, + SignInMode, TenantRole, + adminConsoleApplicationId, + adminTenantId, defaultManagementApiAdminName, - OrganizationInvitationStatus, + defaultTenantId, + getTenantOrganizationId, + getTenantRole, userOnboardingDataKey, } from '@logto/schemas'; import { generateStandardId } from '@logto/shared'; @@ -32,13 +32,13 @@ import type { WithInteractionDetailsContext } from '../middleware/koa-interactio import { type WithInteractionHooksContext } from '../middleware/koa-interaction-hooks.js'; import type { VerifiedInteractionResult, - VerifiedSignInInteractionResult, VerifiedRegisterInteractionResult, + VerifiedSignInInteractionResult, } from '../types/index.js'; import { clearInteractionStorage } from '../utils/interaction.js'; import { userMfaDataKey } from '../verifications/mfa-verification.js'; -import { postAffiliateLogs, parseUserProfile } from './helpers.js'; +import { hasUpdatedProfile, parseUserProfile, postAffiliateLogs } from './helpers.js'; const parseBindMfas = ({ bindMfas, @@ -133,7 +133,7 @@ async function handleSubmitRegister( (invitation) => invitation.status === OrganizationInvitationStatus.Pending ); - await insertUser( + const user = await insertUser( { id, ...userProfile, @@ -184,10 +184,13 @@ async function handleSubmitRegister( } await assignInteractionResults(ctx, provider, { login: { accountId: id } }); + ctx.assignInteractionHookResult({ userId: id }); + ctx.assignDataHookContext({ event: 'User.Created', user }); log?.append({ userId: id }); appInsights.client?.trackEvent({ name: getEventName(Component.Core, CoreEvent.Register) }); + void trySafe(postAffiliateLogs(ctx, cloudConnection, id, tenantId), (error) => { getConsoleLogFromContext(ctx).warn('Failed to post affiliate logs', error); void appInsights.trackException(error, buildAppInsightsTelemetry(ctx)); @@ -211,7 +214,7 @@ async function handleSubmitSignIn( const mfaVerifications = parseBindMfas(interaction); const { mfaSkipped } = interaction; - await updateUserById(accountId, { + const updatedUser = await updateUserById(accountId, { ...updateUserProfile, ...conditional( mfaVerifications.length > 0 && { @@ -229,8 +232,14 @@ async function handleSubmitSignIn( } ), }); + await assignInteractionResults(ctx, provider, { login: { accountId } }); + ctx.assignInteractionHookResult({ userId: accountId }); + // Trigger user.updated data hook event if the user profile or mfa data is updated + if (hasUpdatedProfile(updateUserProfile) || mfaVerifications.length > 0) { + ctx.assignDataHookContext({ event: 'User.Updated', user: updatedUser }); + } appInsights.client?.trackEvent({ name: getEventName(Component.Core, CoreEvent.SignIn) }); } @@ -261,8 +270,10 @@ export default async function submitInteraction( profile.password ); - await updateUserById(accountId, { passwordEncrypted, passwordEncryptionMethod }); + const user = await updateUserById(accountId, { passwordEncrypted, passwordEncryptionMethod }); ctx.assignInteractionHookResult({ userId: accountId }); + ctx.assignDataHookContext({ event: 'User.Updated', user }); + await clearInteractionStorage(ctx, provider); ctx.status = 204; } diff --git a/packages/core/src/routes/interaction/middleware/koa-interaction-hooks.ts b/packages/core/src/routes/interaction/middleware/koa-interaction-hooks.ts index d9518c03486..7e51f0041bd 100644 --- a/packages/core/src/routes/interaction/middleware/koa-interaction-hooks.ts +++ b/packages/core/src/routes/interaction/middleware/koa-interaction-hooks.ts @@ -1,10 +1,12 @@ -import { conditionalString, trySafe } from '@silverhand/essentials'; +import { userInfoSelectFields, type DataHookEvent, type User } from '@logto/schemas'; +import { conditional, conditionalString, noop, pick, trySafe } from '@silverhand/essentials'; import type { MiddlewareType } from 'koa'; import type { IRouterParamContext } from 'koa-router'; +import { EnvSet } from '#src/env-set/index.js'; import { + DataHookContextManager, InteractionHookContextManager, - type InteractionHookResult, } from '#src/libraries/hook/context-manager.js'; import type Libraries from '#src/tenants/Libraries.js'; import { getConsoleLogFromContext } from '#src/utils/console.js'; @@ -13,11 +15,18 @@ import { getInteractionStorage } from '../utils/interaction.js'; import type { WithInteractionDetailsContext } from './koa-interaction-details.js'; -type AssignInteractionHookResult = (result: InteractionHookResult) => void; +type AssignDataHookContext = (payload: { + event: DataHookEvent; + user?: User; + data?: Record; +}) => void; export type WithInteractionHooksContext< ContextT extends IRouterParamContext = IRouterParamContext, -> = ContextT & { assignInteractionHookResult: AssignInteractionHookResult }; +> = ContextT & { + assignInteractionHookResult: InteractionHookContextManager['assignInteractionHookResult']; + assignDataHookContext: AssignDataHookContext; +}; /** * The factory to create a new interaction hook middleware function. @@ -29,9 +38,10 @@ export default function koaInteractionHooks< ContextT extends WithInteractionDetailsContext, ResponseT, >({ - hooks: { triggerInteractionHooks }, + hooks: { triggerInteractionHooks, triggerDataHooks }, }: Libraries): MiddlewareType, ResponseT> { return async (ctx, next) => { + const { isDevFeaturesEnabled } = EnvSet.values; const { event: interactionEvent } = getInteractionStorage(ctx.interactionDetails.result); const { @@ -40,18 +50,40 @@ export default function koaInteractionHooks< ip, } = ctx; - const interactionHookContext = new InteractionHookContextManager({ + const interactionApiMetadata = { interactionEvent, userAgent, - userIp: ip, applicationId: conditionalString(interactionDetails.params.client_id), sessionId: interactionDetails.jti, + }; + + const interactionHookContext = new InteractionHookContextManager({ + ...interactionApiMetadata, + userIp: ip, }); ctx.assignInteractionHookResult = interactionHookContext.assignInteractionHookResult.bind(interactionHookContext); - // TODO: @simeng-li Add DataHookContext to the interaction hook middleware as well + const dataHookContext = new DataHookContextManager({ + ...interactionApiMetadata, + ip, + }); + + // Assign user and event data to the data hook context + const assignDataHookContext: AssignDataHookContext = ({ event, user, data: extraData }) => { + dataHookContext.appendContext({ + event, + data: { + // Only return the selected user fields + ...conditional(user && pick(user, ...userInfoSelectFields)), + ...extraData, + }, + }); + }; + + // TODO: remove dev features check + ctx.assignDataHookContext = isDevFeaturesEnabled ? assignDataHookContext : noop; await next(); @@ -59,5 +91,11 @@ export default function koaInteractionHooks< // Hooks should not crash the app void trySafe(triggerInteractionHooks(getConsoleLogFromContext(ctx), interactionHookContext)); } + + // TODO: remove dev features check + if (isDevFeaturesEnabled && dataHookContext.contextArray.length > 0) { + // Hooks should not crash the app + void trySafe(triggerDataHooks(getConsoleLogFromContext(ctx), dataHookContext)); + } }; } diff --git a/packages/core/src/routes/interaction/single-sign-on.ts b/packages/core/src/routes/interaction/single-sign-on.ts index e02dac16031..65e428c9c85 100644 --- a/packages/core/src/routes/interaction/single-sign-on.ts +++ b/packages/core/src/routes/interaction/single-sign-on.ts @@ -135,6 +135,7 @@ export default function singleSignOnRoutes( async (ctx, next) => { const { assignInteractionHookResult, + assignDataHookContext, guard: { params }, } = ctx; const { @@ -153,10 +154,14 @@ export default function singleSignOnRoutes( params.connectorId ); - const accountId = await registerWithSsoAuthentication(ctx, tenant, authenticationResult); + const user = await registerWithSsoAuthentication(ctx, tenant, authenticationResult); + const { id: accountId } = user; await assignInteractionResults(ctx, provider, { login: { accountId } }); + + // Trigger webhooks assignInteractionHookResult({ userId: accountId }); + assignDataHookContext({ event: 'User.Created', user }); return next(); } diff --git a/packages/core/src/routes/interaction/utils/single-sign-on.test.ts b/packages/core/src/routes/interaction/utils/single-sign-on.test.ts index fc85eda76d4..831dd90f441 100644 --- a/packages/core/src/routes/interaction/utils/single-sign-on.test.ts +++ b/packages/core/src/routes/interaction/utils/single-sign-on.test.ts @@ -35,7 +35,7 @@ class MockOidcSsoConnector extends OidcSsoConnector { override getUserInfo = getUserInfoMock; } -const { storeInteractionResult: storeInteractionResultMock } = mockEsm('./interaction.js', () => ({ +mockEsm('./interaction.js', () => ({ storeInteractionResult: jest.fn(), })); @@ -290,13 +290,13 @@ describe('Single sign on util methods tests', () => { it('should register if no related user account found', async () => { insertUserMock.mockResolvedValueOnce({ id: 'foo' }); - const accountId = await registerWithSsoAuthentication(mockContext, tenant, { + const { id } = await registerWithSsoAuthentication(mockContext, tenant, { connectorId: wellConfiguredSsoConnector.id, issuer: mockIssuer, userInfo: mockSsoUserInfo, }); - expect(accountId).toBe('foo'); + expect(id).toBe('foo'); // Should create new user expect(insertUserMock).toBeCalledWith( diff --git a/packages/core/src/routes/interaction/utils/single-sign-on.ts b/packages/core/src/routes/interaction/utils/single-sign-on.ts index 32b49c6db62..f9cb5220fd7 100644 --- a/packages/core/src/routes/interaction/utils/single-sign-on.ts +++ b/packages/core/src/routes/interaction/utils/single-sign-on.ts @@ -2,9 +2,9 @@ import { ConnectorError, type SocialUserInfo } from '@logto/connector-kit'; import { validateRedirectUrl } from '@logto/core-kit'; import { InteractionEvent, + type SupportedSsoConnector, type User, type UserSsoIdentity, - type SupportedSsoConnector, } from '@logto/schemas'; import { generateStandardId } from '@logto/shared'; import { conditional } from '@silverhand/essentials'; @@ -19,8 +19,8 @@ import type TenantContext from '#src/tenants/TenantContext.js'; import assertThat from '#src/utils/assert-that.js'; import { - getSingleSignOnSessionResult, assignSingleSignOnAuthenticationResult, + getSingleSignOnSessionResult, } from './single-sign-on-session.js'; import { assignConnectorSessionResult } from './social-verification.js'; @@ -308,7 +308,7 @@ export const registerWithSsoAuthentication = async ( }; // Insert new user - const { id: userId } = await usersLibrary.insertUser( + const user = await usersLibrary.insertUser( { id: await usersLibrary.generateUserId(), ...syncingProfile, @@ -317,6 +317,8 @@ export const registerWithSsoAuthentication = async ( [] ); + const { id: userId } = user; + // Insert new user SSO identity await userSsoIdentitiesQueries.insert({ id: generateStandardId(), @@ -340,5 +342,5 @@ export const registerWithSsoAuthentication = async ( }, }); - return userId; + return user; }; diff --git a/packages/integration-tests/src/helpers/connector.ts b/packages/integration-tests/src/helpers/connector.ts index f52d84b1c77..5789bc8f685 100644 --- a/packages/integration-tests/src/helpers/connector.ts +++ b/packages/integration-tests/src/helpers/connector.ts @@ -1,14 +1,14 @@ -import type { ConnectorType } from '@logto/schemas'; +import { ConnectorType } from '@logto/schemas'; import { mockEmailConnectorConfig, mockEmailConnectorId, mockSmsConnectorConfig, mockSmsConnectorId, - mockSocialConnectorId, mockSocialConnectorConfig, + mockSocialConnectorId, } from '#src/__mocks__/connectors-mock.js'; -import { listConnectors, deleteConnectorById, postConnector } from '#src/api/index.js'; +import { deleteConnectorById, listConnectors, postConnector } from '#src/api/index.js'; import { deleteSsoConnectorById, getSsoConnectors } from '#src/api/sso-connector.js'; export const clearConnectorsByTypes = async (types: ConnectorType[]) => { @@ -41,3 +41,8 @@ export const setSocialConnector = async () => connectorId: mockSocialConnectorId, config: mockSocialConnectorConfig, }); + +export const resetPasswordlessConnectors = async () => { + await clearConnectorsByTypes([ConnectorType.Email, ConnectorType.Sms]); + await Promise.all([setEmailConnector(), setSmsConnector()]); +}; diff --git a/packages/integration-tests/src/helpers/hook.ts b/packages/integration-tests/src/helpers/hook.ts index b2dea044be3..d730d886293 100644 --- a/packages/integration-tests/src/helpers/hook.ts +++ b/packages/integration-tests/src/helpers/hook.ts @@ -1,4 +1,6 @@ -import { type Hook, type HookConfig, type HookEvent } from '@logto/schemas'; +import { type CreateHook, type Hook, type HookConfig, type HookEvent } from '@logto/schemas'; + +import { authedAdminApi } from '#src/api/api.js'; type HookCreationPayload = Pick & { config: HookConfig; @@ -15,3 +17,31 @@ export const getHookCreationPayload = ( headers: { foo: 'bar' }, }, }); + +export class WebHookApiTest { + readonly #hooks = new Map(); + + get hooks(): Map { + return this.#hooks; + } + + async create(json: Omit): Promise { + const hook = await authedAdminApi.post('hooks', { json }).json(); + this.#hooks.set(hook.name, hook); + + return hook; + } + + async delete(name: string): Promise { + const hook = this.#hooks.get(name); + + if (hook) { + await authedAdminApi.delete(`hooks/${hook.id}`); + this.#hooks.delete(name); + } + } + + async cleanUp(): Promise { + await Promise.all(Array.from(this.#hooks.keys()).map(async (name) => this.delete(name))); + } +} diff --git a/packages/integration-tests/src/helpers/interactions.ts b/packages/integration-tests/src/helpers/interactions.ts index a744d8bae95..19e180846c0 100644 --- a/packages/integration-tests/src/helpers/interactions.ts +++ b/packages/integration-tests/src/helpers/interactions.ts @@ -1,20 +1,20 @@ import type { - UsernamePasswordPayload, EmailPasswordPayload, PhonePasswordPayload, + UsernamePasswordPayload, } from '@logto/schemas'; import { InteractionEvent } from '@logto/schemas'; import { - putInteraction, createSocialAuthorizationUri, patchInteractionIdentifiers, + putInteraction, putInteractionProfile, sendVerificationCode, } from '#src/api/index.js'; import { generateUserId } from '#src/utils.js'; -import { initClient, processSession, logoutClient } from './client.js'; +import { initClient, logoutClient, processSession } from './client.js'; import { expectRejects, readConnectorMessage } from './index.js'; import { enableAllPasswordSignInMethods } from './sign-in-experience.js'; import { generateNewUser } from './user.js'; @@ -90,6 +90,43 @@ export const createNewSocialUserWithUsernameAndPassword = async (connectorId: st return processSession(client, redirectTo); }; +export const signInWithUsernamePasswordAndUpdateEmailOrPhone = async ( + username: string, + password: string, + profile: { email: string } | { phone: string } +) => { + const client = await initClient(); + + await client.successSend(putInteraction, { + event: InteractionEvent.SignIn, + identifier: { + username, + password, + }, + }); + + await expectRejects(client.submitInteraction(), { + code: 'user.missing_profile', + status: 422, + }); + + await client.successSend(sendVerificationCode, profile); + + const { code } = await readConnectorMessage('email' in profile ? 'Email' : 'Sms'); + + await client.successSend(patchInteractionIdentifiers, { + ...profile, + verificationCode: code, + }); + + await client.successSend(putInteractionProfile, profile); + + const { redirectTo } = await client.submitInteraction(); + + await processSession(client, redirectTo); + await logoutClient(client); +}; + export const resetPassword = async ( profile: { email: string } | { phone: string }, newPassword: string diff --git a/packages/integration-tests/src/tests/api/hook/WebhookMockServer.ts b/packages/integration-tests/src/tests/api/hook/WebhookMockServer.ts index 952b8f95542..1b9c77b0977 100644 --- a/packages/integration-tests/src/tests/api/hook/WebhookMockServer.ts +++ b/packages/integration-tests/src/tests/api/hook/WebhookMockServer.ts @@ -1,5 +1,9 @@ +import { createHmac } from 'node:crypto'; import { createServer, type RequestListener, type Server } from 'node:http'; +import { hookEventGuard } from '@logto/schemas'; +import { z } from 'zod'; + /** * A mock server that listens for incoming requests and responds with the request body. * @@ -28,11 +32,14 @@ class WebhookMockServer { request.on('end', () => { response.writeHead(200, { 'Content-Type': 'application/json' }); - const payload: unknown = JSON.parse(Buffer.concat(data).toString()); + // Keep the raw payload for signature verification + const rawPayload = Buffer.concat(data).toString(); + const payload: unknown = JSON.parse(rawPayload); const body = JSON.stringify({ signature: request.headers['logto-signature-sha-256'], payload, + rawPayload, }); requestCallback?.(body); @@ -61,4 +68,24 @@ class WebhookMockServer { } } +export const mockHookResponseGuard = z.object({ + body: z.object({ + signature: z.string(), + payload: z + .object({ + event: hookEventGuard, + createdAt: z.string(), + hookId: z.string(), + }) + .catchall(z.any()), + // Use the raw payload for signature verification + rawPayload: z.string(), + }), +}); + export default WebhookMockServer; + +export const verifySignature = (payload: string, secret: string, signature: string) => { + const calculatedSignature = createHmac('sha256', secret).update(payload).digest('hex'); + return calculatedSignature === signature; +}; diff --git a/packages/integration-tests/src/tests/api/hook/hook.trigger.data.test.ts b/packages/integration-tests/src/tests/api/hook/hook.trigger.data.test.ts index d744c0e44ed..5cf6b6bc210 100644 --- a/packages/integration-tests/src/tests/api/hook/hook.trigger.data.test.ts +++ b/packages/integration-tests/src/tests/api/hook/hook.trigger.data.test.ts @@ -4,14 +4,15 @@ import { hookEvents, jsonGuard, managementApiHooksRegistration, - type Hook, type Role, } from '@logto/schemas'; +import { assert } from '@silverhand/essentials'; import { z } from 'zod'; import { authedAdminApi } from '#src/api/api.js'; import { createResource } from '#src/api/resource.js'; import { createScope } from '#src/api/scope.js'; +import { WebHookApiTest } from '#src/helpers/hook.js'; import { OrganizationApiTest, OrganizationRoleApiTest, @@ -20,7 +21,7 @@ import { import { UserApiTest, generateNewUser } from '#src/helpers/user.js'; import { generateName, waitFor } from '#src/utils.js'; -import WebhookMockServer from './WebhookMockServer.js'; +import WebhookMockServer, { verifySignature } from './WebhookMockServer.js'; import { organizationDataHookTestCases, organizationRoleDataHookTestCases, @@ -32,24 +33,28 @@ import { const mockHookResponseGuard = z.object({ signature: z.string(), - payload: z.object({ - event: hookEventGuard, - createdAt: z.string(), - hookId: z.string(), - data: jsonGuard.optional(), - method: z - .string() - .optional() - .transform((value) => value?.toUpperCase()), - matchedRoute: z.string().optional(), - }), + payload: z + .object({ + event: hookEventGuard, + createdAt: z.string(), + hookId: z.string(), + data: jsonGuard.optional(), + method: z + .string() + .optional() + .transform((value) => value?.toUpperCase()), + matchedRoute: z.string().optional(), + }) + .catchall(z.any()), + // Keep the raw payload for signature verification + rawPayload: z.string(), }); type MockHookResponse = z.infer; const hookName = 'management-api-hook'; -const webhooks = new Map(); const webhookResults = new Map(); +const webHookApi = new WebHookApiTest(); // Record the hook response to the webhookResults map. // Compare the webhookResults map with the managementApiHooksRegistration to verify all hook is triggered. @@ -80,27 +85,17 @@ const webhookServer = new WebhookMockServer(9999, webhookResponseHandler); beforeAll(async () => { await webhookServer.listen(); - const webhookInstance = await authedAdminApi - .post('hooks', { - json: { - name: hookName, - events: [...hookEvents], - config: { - url: webhookServer.endpoint, - headers: { foo: 'bar' }, - }, - }, - }) - .json(); - - webhooks.set(hookName, webhookInstance); + await webHookApi.create({ + name: hookName, + events: [...hookEvents], + config: { + url: webhookServer.endpoint, + }, + }); }); afterAll(async () => { - await Promise.all( - Array.from(webhooks.values()).map(async (hook) => authedAdminApi.delete(`hooks/${hook.id}`)) - ); - + await webHookApi.cleanUp(); await webhookServer.close(); }); @@ -332,11 +327,17 @@ describe('organization role data hook events', () => { ); }); -describe('data hook events coverage', () => { +describe('data hook events coverage and signature verification', () => { const keys = Object.keys(managementApiHooksRegistration); + it.each(keys)('should have test case for %s', async (key) => { + const webhook = webHookApi.hooks.get(hookName)!; + const webhookResult = await getWebhookResult(key); expect(webhookResult).toBeDefined(); - expect(webhookResult?.signature).toBeDefined(); + assert(webhookResult, new Error('webhookResult is undefined')); + + const { signature, rawPayload } = webhookResult; + expect(verifySignature(rawPayload, webhook.signingKey, signature)).toBeTruthy(); }); }); diff --git a/packages/integration-tests/src/tests/api/hook/hook.trigger.interaction.test.ts b/packages/integration-tests/src/tests/api/hook/hook.trigger.interaction.test.ts index 0ea20f897c4..5d9fa08b8d2 100644 --- a/packages/integration-tests/src/tests/api/hook/hook.trigger.interaction.test.ts +++ b/packages/integration-tests/src/tests/api/hook/hook.trigger.interaction.test.ts @@ -1,270 +1,295 @@ -import { createHmac } from 'node:crypto'; -import { type RequestListener } from 'node:http'; - import { - ConnectorType, + InteractionEvent, InteractionHookEvent, LogResult, SignInIdentifier, + hookEvents, type Hook, - type Log, - type LogContextPayload, - type LogKey, + type HookEvent, } from '@logto/schemas'; -import { type Optional } from '@silverhand/essentials'; +import { assert } from '@silverhand/essentials'; -import { deleteUser } from '#src/api/admin-user.js'; import { authedAdminApi } from '#src/api/api.js'; import { getWebhookRecentLogs } from '#src/api/logs.js'; +import { resetPasswordlessConnectors } from '#src/helpers/connector.js'; +import { WebHookApiTest } from '#src/helpers/hook.js'; import { - clearConnectorsByTypes, - setEmailConnector, - setSmsConnector, -} from '#src/helpers/connector.js'; -import { getHookCreationPayload } from '#src/helpers/hook.js'; -import { createMockServer } from '#src/helpers/index.js'; -import { registerNewUser, resetPassword, signInWithPassword } from '#src/helpers/interactions.js'; + registerNewUser, + resetPassword, + signInWithPassword, + signInWithUsernamePasswordAndUpdateEmailOrPhone, +} from '#src/helpers/interactions.js'; import { enableAllPasswordSignInMethods, enableAllVerificationCodeSignInMethods, } from '#src/helpers/sign-in-experience.js'; -import { generateNewUser, generateNewUserProfile } from '#src/helpers/user.js'; -import { generatePassword, waitFor } from '#src/utils.js'; +import { UserApiTest, generateNewUserProfile } from '#src/helpers/user.js'; +import { generateEmail, generatePassword } from '#src/utils.js'; -type HookSecureData = { - signature: string; - payload: string; -}; +import WebhookMockServer, { mockHookResponseGuard, verifySignature } from './WebhookMockServer.js'; -// Note: return hook payload and signature for webhook security testing -const hookServerRequestListener: RequestListener = (request, response) => { - // eslint-disable-next-line @silverhand/fp/no-mutation - response.statusCode = 204; +const webbHookMockServer = new WebhookMockServer(9999); +const userNamePrefix = 'hookTriggerTestUser'; +const username = `${userNamePrefix}_0`; +const password = generatePassword(); +// For email fulfilling and reset password use +const email = generateEmail(); - const data: Uint8Array[] = []; - request.on('data', (chunk: Uint8Array) => { - // eslint-disable-next-line @silverhand/fp/no-mutating-methods - data.push(chunk); - }); +const userApi = new UserApiTest(); +const webHookApi = new WebHookApiTest(); - request.on('end', () => { - response.writeHead(200, { 'Content-Type': 'application/json' }); - const payload = Buffer.concat(data).toString(); - response.end( - JSON.stringify({ - signature: request.headers['logto-signature-sha-256'] as string, - payload, - } satisfies HookSecureData) - ); - }); -}; +const assertHookLogResult = async ( + { id: hookId, signingKey }: Hook, + event: HookEvent, + assertions: { + errorMessage?: string; + toBeUndefined?: boolean; + hookPayload?: Record; + } +) => { + const logs = await getWebhookRecentLogs( + hookId, + new URLSearchParams({ logKey: `TriggerHook.${event}`, page_size: '10' }) + ); -const assertHookLogError = ({ result, error }: LogContextPayload, errorMessage: string) => - result === LogResult.Error && typeof error === 'string' && error.includes(errorMessage); + const logEntry = logs[0]; -describe('trigger hooks', () => { - const { listen, close } = createMockServer(9999, hookServerRequestListener); + if (assertions.toBeUndefined) { + expect(logEntry).toBeUndefined(); + return; + } - beforeAll(async () => { - await enableAllPasswordSignInMethods({ + expect(logEntry).toBeTruthy(); + assert(logEntry, new Error('Log entry not found')); + + const { payload } = logEntry; + + expect(payload.hookId).toEqual(hookId); + expect(payload.key).toEqual(`TriggerHook.${event}`); + + const { result, error } = payload; + + if (result === LogResult.Success) { + expect(payload.response).toBeTruthy(); + + const { body } = mockHookResponseGuard.parse(payload.response); + expect(verifySignature(body.rawPayload, signingKey, body.signature)).toBeTruthy(); + + if (assertions.hookPayload) { + expect(body.payload).toEqual(expect.objectContaining(assertions.hookPayload)); + } + } + + if (assertions.errorMessage) { + expect(result).toEqual(LogResult.Error); + expect(error).toContain(assertions.errorMessage); + } +}; + +beforeAll(async () => { + await Promise.all([ + resetPasswordlessConnectors(), + enableAllPasswordSignInMethods({ identifiers: [SignInIdentifier.Username], password: true, verify: false, - }); - await listen(); - }); - - afterAll(async () => { - await close(); - }); + }), + webbHookMockServer.listen(), + userApi.create({ username, password }), + ]); +}); - it('should trigger sign-in hook and record error when interaction finished', async () => { - const createdHook = await authedAdminApi - .post('hooks', { json: getHookCreationPayload(InteractionHookEvent.PostSignIn) }) - .json(); - const logKey: LogKey = 'TriggerHook.PostSignIn'; +afterAll(async () => { + await Promise.all([userApi.cleanUp(), webbHookMockServer.close()]); +}); - const { - userProfile: { username, password }, - user, - } = await generateNewUser({ username: true, password: true }); +describe('trigger invalid hook', () => { + beforeAll(async () => { + await webHookApi.create({ + name: 'invalidHookEventListener', + events: [InteractionHookEvent.PostSignIn], + config: { url: 'not_work_url' }, + }); + }); + it('should log invalid hook url error', async () => { await signInWithPassword({ username, password }); - // Check hook trigger log - const logs = await getWebhookRecentLogs( - createdHook.id, - new URLSearchParams({ logKey, page_size: '100' }) - ); - - const hookLog = logs.find(({ payload: { hookId } }) => hookId === createdHook.id); - expect(hookLog).toBeTruthy(); + const hook = webHookApi.hooks.get('invalidHookEventListener')!; - if (hookLog) { - expect( - assertHookLogError(hookLog.payload, 'Failed to parse URL from not_work_url') - ).toBeTruthy(); - } + await assertHookLogResult(hook, InteractionHookEvent.PostSignIn, { + errorMessage: 'Failed to parse URL from not_work_url', + }); + }); - // Clean up - await authedAdminApi.delete(`hooks/${createdHook.id}`); - await deleteUser(user.id); + afterAll(async () => { + await webHookApi.cleanUp(); }); +}); - it('should trigger multiple register hooks and record properly when interaction finished', async () => { - const [hook1, hook2, hook3] = await Promise.all([ - authedAdminApi - .post('hooks', { json: getHookCreationPayload(InteractionHookEvent.PostRegister) }) - .json(), - authedAdminApi - .post('hooks', { - json: getHookCreationPayload(InteractionHookEvent.PostRegister, 'http://localhost:9999'), - }) - .json(), - // Using the old API to create a hook - authedAdminApi - .post('hooks', { - json: { - event: InteractionHookEvent.PostRegister, - config: { url: 'http://localhost:9999', retries: 2 }, - }, - }) - .json(), +describe('interaction api trigger hooks', () => { + // Use new hooks for each test to ensure test isolation + beforeEach(async () => { + await Promise.all([ + webHookApi.create({ + name: 'interactionHookEventListener', + events: Object.values(InteractionHookEvent), + config: { url: webbHookMockServer.endpoint }, + }), + webHookApi.create({ + name: 'dataHookEventListener', + events: hookEvents.filter((event) => !(event in InteractionHookEvent)), + config: { url: webbHookMockServer.endpoint }, + }), + webHookApi.create({ + name: 'registerOnlyInteractionHookEventListener', + events: [InteractionHookEvent.PostRegister], + config: { url: webbHookMockServer.endpoint }, + }), ]); - const logKey: LogKey = 'TriggerHook.PostRegister'; + }); + + afterEach(async () => { + await webHookApi.cleanUp(); + }); + it('new user registration interaction API', async () => { + const interactionHook = webHookApi.hooks.get('interactionHookEventListener')!; + const registerHook = webHookApi.hooks.get('registerOnlyInteractionHookEventListener')!; + const dataHook = webHookApi.hooks.get('dataHookEventListener')!; const { username, password } = generateNewUserProfile({ username: true, password: true }); const userId = await registerNewUser(username, password); - type HookRequest = { - body: { - userIp?: string; - } & Record; + const interactionHookEventPayload: Record = { + event: InteractionHookEvent.PostRegister, + interactionEvent: InteractionEvent.Register, + sessionId: expect.any(String), + user: expect.objectContaining({ id: userId, username }), }; - // Check hook trigger log - for (const [hook, expectedResult, expectedError] of [ - [hook1, LogResult.Error, 'Failed to parse URL from not_work_url'], - [hook2, LogResult.Success, undefined], - [hook3, LogResult.Success, undefined], - ] satisfies Array<[Hook, LogResult, Optional]>) { - // eslint-disable-next-line no-await-in-loop - const logs = await getWebhookRecentLogs( - hook.id, - new URLSearchParams({ logKey, page_size: '100' }) - ); - - const log = logs.find(({ payload: { hookId } }) => hookId === hook.id); - - expect(log).toBeTruthy(); - - // Skip the test if the log is not found - if (!log) { - return; - } + await assertHookLogResult(interactionHook, InteractionHookEvent.PostRegister, { + hookPayload: interactionHookEventPayload, + }); - // Assert user ip is in the hook request - expect((log.payload.hookRequest as HookRequest).body.userIp).toBeTruthy(); + // Verify multiple hooks can be triggered with the same event + await assertHookLogResult(registerHook, InteractionHookEvent.PostRegister, { + hookPayload: interactionHookEventPayload, + }); - // Assert the log result and error message - expect(log.payload.result).toEqual(expectedResult); + // Verify data hook is triggered + await assertHookLogResult(dataHook, 'User.Created', { + hookPayload: { + event: 'User.Created', + interactionEvent: InteractionEvent.Register, + sessionId: expect.any(String), + data: expect.objectContaining({ id: userId, username }), + }, + }); - if (expectedError) { - expect(assertHookLogError(log.payload, expectedError)).toBeTruthy(); - } - } + // Assert user updated event is not triggered + await assertHookLogResult(dataHook, 'User.Updated', { + toBeUndefined: true, + }); // Clean up - await Promise.all([ - authedAdminApi.delete(`hooks/${hook1.id}`), - authedAdminApi.delete(`hooks/${hook2.id}`), - authedAdminApi.delete(`hooks/${hook3.id}`), - ]); - await deleteUser(userId); + await authedAdminApi.delete(`users/${userId}`); }); - it('should secure webhook payload data successfully', async () => { - const createdHook = await authedAdminApi - .post('hooks', { - json: getHookCreationPayload(InteractionHookEvent.PostRegister, 'http://localhost:9999'), - }) - .json(); + it('user sign in interaction API without profile update', async () => { + await signInWithPassword({ username, password }); - const { username, password } = generateNewUserProfile({ username: true, password: true }); - const userId = await registerNewUser(username, password); + const interactionHook = webHookApi.hooks.get('interactionHookEventListener')!; + const dataHook = webHookApi.hooks.get('dataHookEventListener')!; + const user = userApi.users.find(({ username: name }) => name === username)!; - const logs = await authedAdminApi - .get(`hooks/${createdHook.id}/recent-logs?page_size=100`) - .json(); + const interactionHookEventPayload: Record = { + event: InteractionHookEvent.PostSignIn, + interactionEvent: InteractionEvent.SignIn, + sessionId: expect.any(String), + user: expect.objectContaining({ id: user.id, username }), + }; - const log = logs.find(({ payload: { hookId } }) => hookId === createdHook.id); - expect(log).toBeTruthy(); + await assertHookLogResult(interactionHook, InteractionHookEvent.PostSignIn, { + hookPayload: interactionHookEventPayload, + }); - const response = log?.payload.response; - expect(response).toBeTruthy(); + // Verify user create data hook is not triggered + await assertHookLogResult(dataHook, 'User.Created', { + toBeUndefined: true, + }); - const { - body: { signature, payload }, - } = response as { body: HookSecureData }; + await assertHookLogResult(dataHook, 'User.Updated', { + toBeUndefined: true, + }); + }); - expect(signature).toBeTruthy(); - expect(payload).toBeTruthy(); + it('user sign in interaction API with profile update', async () => { + await enableAllVerificationCodeSignInMethods({ + identifiers: [SignInIdentifier.Email], + password: true, + verify: true, + }); - const calculateSignature = createHmac('sha256', createdHook.signingKey) - .update(payload) - .digest('hex'); + const interactionHook = webHookApi.hooks.get('interactionHookEventListener')!; + const dataHook = webHookApi.hooks.get('dataHookEventListener')!; + const user = userApi.users.find(({ username: name }) => name === username)!; - expect(calculateSignature).toEqual(signature); + await signInWithUsernamePasswordAndUpdateEmailOrPhone(username, password, { + email, + }); - await authedAdminApi.delete(`hooks/${createdHook.id}`); + const interactionHookEventPayload: Record = { + event: InteractionHookEvent.PostSignIn, + interactionEvent: InteractionEvent.SignIn, + sessionId: expect.any(String), + user: expect.objectContaining({ id: user.id, username }), + }; - await deleteUser(userId); + await assertHookLogResult(interactionHook, InteractionHookEvent.PostSignIn, { + hookPayload: interactionHookEventPayload, + }); + + // Verify user create data hook is not triggered + await assertHookLogResult(dataHook, 'User.Created', { + toBeUndefined: true, + }); + + await assertHookLogResult(dataHook, 'User.Updated', { + hookPayload: { + event: 'User.Updated', + interactionEvent: InteractionEvent.SignIn, + sessionId: expect.any(String), + data: expect.objectContaining({ id: user.id, username, primaryEmail: email }), + }, + }); }); - it('should trigger reset password hook and record properly when interaction finished', async () => { - await clearConnectorsByTypes([ConnectorType.Email, ConnectorType.Sms]); - await setEmailConnector(); - await setSmsConnector(); - await enableAllVerificationCodeSignInMethods({ - identifiers: [SignInIdentifier.Email, SignInIdentifier.Phone], - password: true, - verify: true, + it('password reset interaction API', async () => { + const newPassword = generatePassword(); + const interactionHook = webHookApi.hooks.get('interactionHookEventListener')!; + const dataHook = webHookApi.hooks.get('dataHookEventListener')!; + const user = userApi.users.find(({ username: name }) => name === username)!; + + await resetPassword({ email }, newPassword); + + const interactionHookEventPayload: Record = { + event: InteractionHookEvent.PostResetPassword, + interactionEvent: InteractionEvent.ForgotPassword, + sessionId: expect.any(String), + user: expect.objectContaining({ id: user.id, username, primaryEmail: email }), + }; + + await assertHookLogResult(interactionHook, InteractionHookEvent.PostResetPassword, { + hookPayload: interactionHookEventPayload, }); - // Create a reset password hook - const resetPasswordHook = await authedAdminApi - .post('hooks', { - json: getHookCreationPayload( - InteractionHookEvent.PostResetPassword, - 'http://localhost:9999' - ), - }) - .json(); - const logKey: LogKey = 'TriggerHook.PostResetPassword'; - - const { user, userProfile } = await generateNewUser({ - primaryPhone: true, - primaryEmail: true, - password: true, + + await assertHookLogResult(dataHook, 'User.Updated', { + hookPayload: { + event: 'User.Updated', + interactionEvent: InteractionEvent.ForgotPassword, + sessionId: expect.any(String), + data: expect.objectContaining({ id: user.id, username, primaryEmail: email }), + }, }); - // Reset Password by Email - await resetPassword({ email: userProfile.primaryEmail }, generatePassword()); - // Reset Password by Phone - await resetPassword({ phone: userProfile.primaryPhone }, generatePassword()); - // Wait for the hook to be trigged - await waitFor(1000); - - const relatedLogs = await getWebhookRecentLogs( - resetPasswordHook.id, - new URLSearchParams({ logKey, page_size: '100' }) - ); - const succeedLogs = relatedLogs.filter( - ({ payload: { result } }) => result === LogResult.Success - ); - - expect(succeedLogs).toHaveLength(2); - - await authedAdminApi.delete(`hooks/${resetPasswordHook.id}`); - await deleteUser(user.id); - await clearConnectorsByTypes([ConnectorType.Email, ConnectorType.Sms]); }); }); diff --git a/packages/integration-tests/src/tests/api/interaction/sign-in-with-password-identifier/happy-path.test.ts b/packages/integration-tests/src/tests/api/interaction/sign-in-with-password-identifier/happy-path.test.ts index fe66b572a6e..94e7007c37b 100644 --- a/packages/integration-tests/src/tests/api/interaction/sign-in-with-password-identifier/happy-path.test.ts +++ b/packages/integration-tests/src/tests/api/interaction/sign-in-with-password-identifier/happy-path.test.ts @@ -1,24 +1,16 @@ -import { - InteractionEvent, - ConnectorType, - SignInIdentifier, - UsersPasswordEncryptionMethod, -} from '@logto/schemas'; +import { ConnectorType, SignInIdentifier, UsersPasswordEncryptionMethod } from '@logto/schemas'; -import { - putInteraction, - sendVerificationCode, - patchInteractionIdentifiers, - putInteractionProfile, - deleteUser, -} from '#src/api/index.js'; -import { initClient, processSession, logoutClient } from '#src/helpers/client.js'; +import { deleteUser } from '#src/api/index.js'; import { clearConnectorsByTypes, - setSmsConnector, setEmailConnector, + setSmsConnector, } from '#src/helpers/connector.js'; -import { readConnectorMessage, expectRejects, createUserByAdmin } from '#src/helpers/index.js'; +import { createUserByAdmin } from '#src/helpers/index.js'; +import { + signInWithPassword, + signInWithUsernamePasswordAndUpdateEmailOrPhone, +} from '#src/helpers/interactions.js'; import { enableAllPasswordSignInMethods, enableAllVerificationCodeSignInMethods, @@ -40,20 +32,8 @@ describe('Sign-in flow using password identifiers', () => { it('sign-in with username and password', async () => { const { userProfile, user } = await generateNewUser({ username: true, password: true }); - const client = await initClient(); - - await client.successSend(putInteraction, { - event: InteractionEvent.SignIn, - identifier: { - username: userProfile.username, - password: userProfile.password, - }, - }); - const { redirectTo } = await client.submitInteraction(); - - await processSession(client, redirectTo); - await logoutClient(client); + await signInWithPassword({ username: userProfile.username, password: userProfile.password }); await deleteUser(user.id); }); @@ -61,81 +41,31 @@ describe('Sign-in flow using password identifiers', () => { it('sign-in with username and password twice to test algorithm transition', async () => { const username = generateUsername(); const password = 'password'; + const user = await createUserByAdmin({ username, passwordDigest: '5f4dcc3b5aa765d61d8327deb882cf99', passwordAlgorithm: UsersPasswordEncryptionMethod.MD5, }); - const client = await initClient(); - - await client.successSend(putInteraction, { - event: InteractionEvent.SignIn, - identifier: { - username, - password, - }, - }); - const { redirectTo } = await client.submitInteraction(); + await signInWithPassword({ username, password }); - await processSession(client, redirectTo); - await logoutClient(client); - - const client2 = await initClient(); - - await client2.successSend(putInteraction, { - event: InteractionEvent.SignIn, - identifier: { - username, - password, - }, - }); - - const { redirectTo: redirectTo2 } = await client2.submitInteraction(); - - await processSession(client2, redirectTo2); - await logoutClient(client2); + await signInWithPassword({ username, password }); await deleteUser(user.id); }); it('sign-in with email and password', async () => { const { userProfile, user } = await generateNewUser({ primaryEmail: true, password: true }); - const client = await initClient(); - - await client.successSend(putInteraction, { - event: InteractionEvent.SignIn, - identifier: { - email: userProfile.primaryEmail, - password: userProfile.password, - }, - }); - const { redirectTo } = await client.submitInteraction(); - - await processSession(client, redirectTo); - await logoutClient(client); + await signInWithPassword({ email: userProfile.primaryEmail, password: userProfile.password }); await deleteUser(user.id); }); it('sign-in with phone and password', async () => { const { userProfile, user } = await generateNewUser({ primaryPhone: true, password: true }); - const client = await initClient(); - - await client.successSend(putInteraction, { - event: InteractionEvent.SignIn, - identifier: { - phone: userProfile.primaryPhone, - password: userProfile.password, - }, - }); - - const { redirectTo } = await client.submitInteraction(); - - await processSession(client, redirectTo); - await logoutClient(client); - + await signInWithPassword({ phone: userProfile.primaryPhone, password: userProfile.password }); await deleteUser(user.id); }); @@ -149,54 +79,16 @@ describe('Sign-in flow using password identifiers', () => { const { userProfile, user } = await generateNewUser({ username: true, password: true }); const { primaryEmail } = generateNewUserProfile({ primaryEmail: true }); - const client = await initClient(); - await client.successSend(putInteraction, { - event: InteractionEvent.SignIn, - identifier: { - username: userProfile.username, - password: userProfile.password, - }, - }); - - await expectRejects(client.submitInteraction(), { - code: 'user.missing_profile', - status: 422, - }); - - await client.successSend(sendVerificationCode, { - email: primaryEmail, - }); - - const { code } = await readConnectorMessage('Email'); - - await client.successSend(patchInteractionIdentifiers, { - email: primaryEmail, - verificationCode: code, - }); - - await client.successSend(putInteractionProfile, { - email: primaryEmail, - }); - - const { redirectTo } = await client.submitInteraction(); - - await processSession(client, redirectTo); - await logoutClient(client); - - // SignIn with email and password - await client.initSession(); - await client.successSend(putInteraction, { - event: InteractionEvent.SignIn, - identifier: { + await signInWithUsernamePasswordAndUpdateEmailOrPhone( + userProfile.username, + userProfile.password, + { email: primaryEmail, - password: userProfile.password, - }, - }); + } + ); - const { redirectTo: redirectTo2 } = await client.submitInteraction(); - await processSession(client, redirectTo2); - await logoutClient(client); + await signInWithPassword({ email: primaryEmail, password: userProfile.password }); await deleteUser(user.id); }); @@ -211,54 +103,14 @@ describe('Sign-in flow using password identifiers', () => { const { userProfile, user } = await generateNewUser({ username: true, password: true }); const { primaryPhone } = generateNewUserProfile({ primaryPhone: true }); - const client = await initClient(); - - await client.successSend(putInteraction, { - event: InteractionEvent.SignIn, - identifier: { - username: userProfile.username, - password: userProfile.password, - }, - }); - await expectRejects(client.submitInteraction(), { - code: 'user.missing_profile', - status: 422, - }); - - await client.successSend(sendVerificationCode, { - phone: primaryPhone, - }); - - const { code } = await readConnectorMessage('Sms'); - - await client.successSend(patchInteractionIdentifiers, { - phone: primaryPhone, - verificationCode: code, - }); - - await client.successSend(putInteractionProfile, { - phone: primaryPhone, - }); - - const { redirectTo } = await client.submitInteraction(); - - await processSession(client, redirectTo); - await logoutClient(client); - - // SignIn with new phone and password - await client.initSession(); - await client.successSend(putInteraction, { - event: InteractionEvent.SignIn, - identifier: { + await signInWithUsernamePasswordAndUpdateEmailOrPhone( + userProfile.username, + userProfile.password, + { phone: primaryPhone, - password: userProfile.password, - }, - }); - - const { redirectTo: redirectTo2 } = await client.submitInteraction(); - await processSession(client, redirectTo2); - await logoutClient(client); + } + ); await deleteUser(user.id); }); From ac26e8b96afc37055af9c14a8b8ab3bd91bff614 Mon Sep 17 00:00:00 2001 From: Gao Sun Date: Wed, 15 May 2024 12:39:56 +0800 Subject: [PATCH 391/687] ci: remove corepack (#5867) --- .github/workflows/main.yml | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 2bd1a72767d..fef2eec7073 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -132,11 +132,7 @@ jobs: - name: Prepack alteration working-directory: ./alteration - run: | - # Remove corepack commands once a new Logto release is out - corepack enable pnpm - corepack use pnpm@8 - pnpm i && pnpm prepack + run: pnpm i && pnpm prepack # ** End ** - name: Setup Postgres From c2a8e457c22e2df44775b4deed24b739204324d8 Mon Sep 17 00:00:00 2001 From: Gao Sun Date: Wed, 15 May 2024 14:05:25 +0800 Subject: [PATCH 392/687] refactor(console): report first app creation conversion (#5866) --- .../src/components/Conversion/utils.ts | 15 ++++++++---- .../pages/SignInExperience/index.tsx | 23 +++++++++---------- .../components/CreateForm/index.tsx | 8 +++++++ 3 files changed, 29 insertions(+), 17 deletions(-) diff --git a/packages/console/src/components/Conversion/utils.ts b/packages/console/src/components/Conversion/utils.ts index 730ab9f4915..1b73ba0a91b 100644 --- a/packages/console/src/components/Conversion/utils.ts +++ b/packages/console/src/components/Conversion/utils.ts @@ -7,6 +7,8 @@ export const gtagAwTrackingId = 'AW-11124811245'; export enum GtagConversionId { /** This ID indicates a user has truly signed up for Logto Cloud. */ SignUp = 'AW-11192640559/ZuqUCLvNpasYEK_IiNkp', + /** This ID indicates a user has created their first app. */ + CreateFirstApp = 'AW-11192640559/jbsaCPS67q8ZEK_IiNkp', /** This ID indicates a user has created a production tenant. */ CreateProductionTenant = 'AW-11192640559/m04fCMDrxI0ZEK_IiNkp', /** This ID indicates a user has purchased a Pro plan. */ @@ -102,7 +104,7 @@ type ReportConversionOptions = { redditType?: RedditReportType; }; -export const reportConversion = async ({ +export const reportConversion = ({ gtagId, redditType, transactionId, @@ -112,8 +114,11 @@ export const reportConversion = async ({ return; } - return Promise.all([ - gtagId ? reportToGoogle(gtagId, { transactionId }) : undefined, - redditType ? reportToReddit(redditType) : undefined, - ]); + if (gtagId) { + reportToGoogle(gtagId, { transactionId }); + } + + if (redditType) { + reportToReddit(redditType); + } }; diff --git a/packages/console/src/onboarding/pages/SignInExperience/index.tsx b/packages/console/src/onboarding/pages/SignInExperience/index.tsx index c31a6dedb6f..fb195df7263 100644 --- a/packages/console/src/onboarding/pages/SignInExperience/index.tsx +++ b/packages/console/src/onboarding/pages/SignInExperience/index.tsx @@ -118,18 +118,17 @@ function SignInExperience() { } } - const [updatedData] = await Promise.all([ - api - .patch(buildUrl('api/sign-in-exp', { removeUnusedDemoSocialConnector: '1' }), { - json: formDataParser.toUpdateOnboardingSieData(formData, signInExperience), - }) - .json(), - reportConversion({ - gtagId: GtagConversionId.SignUp, - redditType: 'SignUp', - transactionId: user?.id, - }), - ]); + const updatedData = await api + .patch(buildUrl('api/sign-in-exp', { removeUnusedDemoSocialConnector: '1' }), { + json: formDataParser.toUpdateOnboardingSieData(formData, signInExperience), + }) + .json(); + + reportConversion({ + gtagId: GtagConversionId.SignUp, + redditType: 'SignUp', + transactionId: user?.id, + }); void mutate(updatedData); diff --git a/packages/console/src/pages/Applications/components/CreateForm/index.tsx b/packages/console/src/pages/Applications/components/CreateForm/index.tsx index 98f75844b0d..31c172a89aa 100644 --- a/packages/console/src/pages/Applications/components/CreateForm/index.tsx +++ b/packages/console/src/pages/Applications/components/CreateForm/index.tsx @@ -7,12 +7,14 @@ import { toast } from 'react-hot-toast'; import { useTranslation } from 'react-i18next'; import Modal from 'react-modal'; +import { GtagConversionId, reportConversion } from '@/components/Conversion/utils'; import DynamicT from '@/ds-components/DynamicT'; import FormField from '@/ds-components/FormField'; import ModalLayout from '@/ds-components/ModalLayout'; import RadioGroup, { Radio } from '@/ds-components/RadioGroup'; import TextInput from '@/ds-components/TextInput'; import useApi from '@/hooks/use-api'; +import useCurrentUser from '@/hooks/use-current-user'; import * as modalStyles from '@/scss/modal.module.scss'; import { applicationTypeI18nKey } from '@/types/applications'; import { trySubmitSafe } from '@/utils/form'; @@ -50,6 +52,7 @@ function CreateForm({ } = useForm({ defaultValues: { type: defaultCreateType, isThirdParty: isDefaultCreateThirdParty }, }); + const { user } = useCurrentUser(); const { field: { onChange, value, name, ref }, @@ -69,6 +72,11 @@ function CreateForm({ } const createdApp = await api.post('api/applications', { json: data }).json(); + + // Report the conversion event after the application is created. Note that the conversion + // should be set as count once since this will be reported multiple times. + reportConversion({ gtagId: GtagConversionId.CreateFirstApp, transactionId: user?.id }); + toast.success(t('applications.application_created')); onClose?.(createdApp); }) From e04d9523a6badcb87a76e874f1033c553b0940de Mon Sep 17 00:00:00 2001 From: simeng-li Date: Wed, 15 May 2024 14:26:52 +0800 Subject: [PATCH 393/687] feat(console, phrases): update the supported webhook events (#5856) * test(core): add integration tests add integration tests for interaction hooks * chore(test): remove legacy test remove legacy test * feat(console, phrases): update the supported webhook events update the supported webhook events * refactor(console): rename webhook and webhook log keys rename webhook and webhook log keys * fix(test): fix integration test fix integration test * feat(console): add devFeature guard add devFeature guard * chore: add changeset add changeset * chore(console): remove the lint rule disable comment remove the lint rule disable comment * fix(test): fix the integartion tests fix the integration tests * fix(console): refine the code refine the code * chore(console): refine comments refine comments --- .changeset/curvy-boxes-hide.md | 12 ++++ .../src/components/BasicWebhookForm/index.tsx | 71 ++++++++++++------- packages/console/src/consts/env.ts | 2 +- packages/console/src/consts/webhooks.ts | 70 +++++++++++++----- .../index.module.scss | 14 ++++ .../CategorizedCheckboxGroup/index.tsx | 42 +++++++++++ .../Checkbox/CheckboxGroup/index.tsx | 6 +- .../src/pages/AuditLogDetails/index.tsx | 11 ++- .../WebhookDetails/WebhookLogs/index.tsx | 25 +++---- .../console/src/pages/WebhookDetails/utils.ts | 19 ++++- packages/console/src/pages/Webhooks/index.tsx | 12 +--- .../api/hook/hook.trigger.interaction.test.ts | 5 +- .../src/tests/console/webhooks/helpers.ts | 4 +- .../src/tests/console/webhooks/index.test.ts | 16 ++--- .../de/translation/admin-console/webhooks.ts | 19 +++-- .../en/translation/admin-console/webhooks.ts | 12 ++-- .../es/translation/admin-console/webhooks.ts | 19 +++-- .../fr/translation/admin-console/webhooks.ts | 19 +++-- .../it/translation/admin-console/webhooks.ts | 19 +++-- .../ja/translation/admin-console/webhooks.ts | 19 +++-- .../ko/translation/admin-console/webhooks.ts | 19 +++-- .../translation/admin-console/webhooks.ts | 19 +++-- .../translation/admin-console/webhooks.ts | 19 +++-- .../translation/admin-console/webhooks.ts | 19 +++-- .../ru/translation/admin-console/webhooks.ts | 19 +++-- .../translation/admin-console/webhooks.ts | 19 +++-- .../translation/admin-console/webhooks.ts | 19 +++-- .../translation/admin-console/webhooks.ts | 19 +++-- .../translation/admin-console/webhooks.ts | 19 +++-- .../src/foundations/jsonb-types/hooks.ts | 2 +- 30 files changed, 438 insertions(+), 151 deletions(-) create mode 100644 .changeset/curvy-boxes-hide.md create mode 100644 packages/console/src/ds-components/Checkbox/CategorizedCheckboxGroup/index.module.scss create mode 100644 packages/console/src/ds-components/Checkbox/CategorizedCheckboxGroup/index.tsx diff --git a/.changeset/curvy-boxes-hide.md b/.changeset/curvy-boxes-hide.md new file mode 100644 index 00000000000..632fef6c1c0 --- /dev/null +++ b/.changeset/curvy-boxes-hide.md @@ -0,0 +1,12 @@ +--- +"@logto/console": patch +"@logto/phrases": patch +--- + +replace the i18n translated hook event label with the hook event value directly in the console + +- remove all the legacy interaction hook events i18n phrases +- replace the translated label with the hook event value directly in the console + - `Create new account` -> `PostRegister` + - `Sign in` -> `PostSignIn` + - `Reset password` -> `PostResetPassword` diff --git a/packages/console/src/components/BasicWebhookForm/index.tsx b/packages/console/src/components/BasicWebhookForm/index.tsx index b332732964b..b3d11c50379 100644 --- a/packages/console/src/components/BasicWebhookForm/index.tsx +++ b/packages/console/src/components/BasicWebhookForm/index.tsx @@ -1,20 +1,39 @@ -import { type HookEvent, type Hook, type HookConfig, InteractionHookEvent } from '@logto/schemas'; +import { type Hook, type HookConfig, type HookEvent } from '@logto/schemas'; import { Controller, useFormContext } from 'react-hook-form'; import { useTranslation } from 'react-i18next'; -import { hookEventLabel } from '@/consts/webhooks'; -import { CheckboxGroup } from '@/ds-components/Checkbox'; +import { isDevFeaturesEnabled } from '@/consts/env'; +import { + dataHookEventsLabel, + interactionHookEvents, + schemaGroupedDataHookEvents, +} from '@/consts/webhooks'; +import CategorizedCheckboxGroup, { + type CheckboxOptionGroup, +} from '@/ds-components/Checkbox/CategorizedCheckboxGroup'; import FormField from '@/ds-components/FormField'; import TextInput from '@/ds-components/TextInput'; import { uriValidator } from '@/utils/validator'; import * as styles from './index.module.scss'; -// TODO: Implement all hook events -const hookEventOptions = Object.values(InteractionHookEvent).map((event) => ({ - title: hookEventLabel[event], - value: event, -})); +const hookEventGroups: Array> = [ + // TODO: Remove dev feature guard + ...(isDevFeaturesEnabled + ? schemaGroupedDataHookEvents.map(([schema, events]) => ({ + title: dataHookEventsLabel[schema], + options: events.map((event) => ({ + value: event, + })), + })) + : []), + { + title: 'webhooks.schemas.interaction', + options: interactionHookEvents.map((event) => ({ + value: event, + })), + }, +]; export type BasicWebhookFormType = { name: Hook['name']; @@ -32,24 +51,6 @@ function BasicWebhookForm() { return ( <> - -
- {t('webhooks.create_form.events_description')} -
- - value.length === 0 ? t('webhooks.create_form.missing_event_error') : true, - }} - render={({ field: { onChange, value } }) => ( - - )} - /> - {errors.events &&
{errors.events.message}
} -
+ + + value.length === 0 ? t('webhooks.create_form.missing_event_error') : true, + }} + render={({ field: { onChange, value } }) => ( + + )} + /> + {errors.events &&
{errors.events.message}
} +
); } diff --git a/packages/console/src/consts/env.ts b/packages/console/src/consts/env.ts index 6459febce95..888eb2d738f 100644 --- a/packages/console/src/consts/env.ts +++ b/packages/console/src/consts/env.ts @@ -3,6 +3,6 @@ import { yes } from '@silverhand/essentials'; const isProduction = process.env.NODE_ENV === 'production'; export const isCloud = yes(process.env.IS_CLOUD); export const adminEndpoint = process.env.ADMIN_ENDPOINT; -// eslint-disable-next-line import/no-unused-modules + export const isDevFeaturesEnabled = !isProduction || yes(process.env.DEV_FEATURES_ENABLED) || yes(process.env.INTEGRATION_TEST); diff --git a/packages/console/src/consts/webhooks.ts b/packages/console/src/consts/webhooks.ts index d3b8cec2bea..14674cb7c4a 100644 --- a/packages/console/src/consts/webhooks.ts +++ b/packages/console/src/consts/webhooks.ts @@ -1,24 +1,58 @@ import { type AdminConsoleKey } from '@logto/phrases'; -import { InteractionHookEvent, type LogKey } from '@logto/schemas'; +import { + DataHookSchema, + InteractionHookEvent, + hookEvents, + type DataHookEvent, +} from '@logto/schemas'; -type HookEventLabel = { - // TODO: Implement all hook events - [key in InteractionHookEvent]: AdminConsoleKey; -}; +export const dataHookEventsLabel = Object.freeze({ + [DataHookSchema.User]: 'webhooks.schemas.user', + [DataHookSchema.Organization]: 'webhooks.schemas.organization', + [DataHookSchema.Role]: 'webhooks.schemas.role', + [DataHookSchema.Scope]: 'webhooks.schemas.scope', + [DataHookSchema.OrganizationRole]: 'webhooks.schemas.organization_role', + [DataHookSchema.OrganizationScope]: 'webhooks.schemas.organization_scope', +} satisfies Record); + +export const interactionHookEvents = Object.values(InteractionHookEvent); + +const dataHookEvents: DataHookEvent[] = hookEvents.filter( + // eslint-disable-next-line no-restricted-syntax + (event): event is DataHookEvent => !interactionHookEvents.includes(event as InteractionHookEvent) +); + +const isDataHookSchema = (schema: string): schema is DataHookSchema => + // eslint-disable-next-line no-restricted-syntax + Object.values(DataHookSchema).includes(schema as DataHookSchema); + +// Group DataHook events by schema +// TODO: Replace this using `groupBy` once Node v22 goes LTS +const schemaGroupedDataHookEventsMap = dataHookEvents.reduce>( + (eventGroup, event) => { + const [schema] = event.split('.'); + + if (schema && isDataHookSchema(schema)) { + eventGroup.set(schema, [...(eventGroup.get(schema) ?? []), event]); + } -export const hookEventLabel = Object.freeze({ - [InteractionHookEvent.PostRegister]: 'webhooks.events.post_register', - [InteractionHookEvent.PostResetPassword]: 'webhooks.events.post_reset_password', - [InteractionHookEvent.PostSignIn]: 'webhooks.events.post_sign_in', -}) satisfies HookEventLabel; + return eventGroup; + }, + new Map() +); -type HookEventLogKey = { - // TODO: Implement all hook events - [key in InteractionHookEvent]: LogKey; +// Sort the grouped `DataHook` events per console product design +const hookEventSchemaOrder: { + [key in DataHookSchema]: number; +} = { + [DataHookSchema.User]: 0, + [DataHookSchema.Organization]: 1, + [DataHookSchema.Role]: 2, + [DataHookSchema.OrganizationRole]: 3, + [DataHookSchema.Scope]: 4, + [DataHookSchema.OrganizationScope]: 5, }; -export const hookEventLogKey = Object.freeze({ - [InteractionHookEvent.PostRegister]: 'TriggerHook.PostRegister', - [InteractionHookEvent.PostResetPassword]: 'TriggerHook.PostResetPassword', - [InteractionHookEvent.PostSignIn]: 'TriggerHook.PostSignIn', -}) satisfies HookEventLogKey; +export const schemaGroupedDataHookEvents = Array.from(schemaGroupedDataHookEventsMap.entries()) + .slice() + .sort(([schemaA], [schemaB]) => hookEventSchemaOrder[schemaA] - hookEventSchemaOrder[schemaB]); diff --git a/packages/console/src/ds-components/Checkbox/CategorizedCheckboxGroup/index.module.scss b/packages/console/src/ds-components/Checkbox/CategorizedCheckboxGroup/index.module.scss new file mode 100644 index 00000000000..6b508295da6 --- /dev/null +++ b/packages/console/src/ds-components/Checkbox/CategorizedCheckboxGroup/index.module.scss @@ -0,0 +1,14 @@ +@use '@/scss/underscore' as _; + +.groupTitle { + font: var(--font-body-2); + color: var(--color-text-secondary); + margin-bottom: _.unit(2); +} + +.groupList { + // Max two columns + gap: _.unit(5); + display: grid; + grid-template-columns: repeat(2, 1fr); +} diff --git a/packages/console/src/ds-components/Checkbox/CategorizedCheckboxGroup/index.tsx b/packages/console/src/ds-components/Checkbox/CategorizedCheckboxGroup/index.tsx new file mode 100644 index 00000000000..1f07557df05 --- /dev/null +++ b/packages/console/src/ds-components/Checkbox/CategorizedCheckboxGroup/index.tsx @@ -0,0 +1,42 @@ +import { type AdminConsoleKey } from '@logto/phrases'; +import classNames from 'classnames'; + +import DynamicT from '@/ds-components/DynamicT'; + +import CheckboxGroup, { type Option } from '../CheckboxGroup'; + +import * as styles from './index.module.scss'; + +export type CheckboxOptionGroup = { + title: AdminConsoleKey; + options: Array>; +}; + +type Props = { + readonly groups: Array>; + readonly value: T[]; + readonly onChange: (value: T[]) => void; + readonly className?: string; +}; + +function CategorizedCheckboxGroup({ + groups, + value: checkedValues, + onChange, + className, +}: Props) { + return ( +
+ {groups.map(({ title, options }) => ( +
+
+ +
+ +
+ ))} +
+ ); +} + +export default CategorizedCheckboxGroup; diff --git a/packages/console/src/ds-components/Checkbox/CheckboxGroup/index.tsx b/packages/console/src/ds-components/Checkbox/CheckboxGroup/index.tsx index 6bbd3e54064..faeb433559a 100644 --- a/packages/console/src/ds-components/Checkbox/CheckboxGroup/index.tsx +++ b/packages/console/src/ds-components/Checkbox/CheckboxGroup/index.tsx @@ -8,8 +8,8 @@ import Checkbox from '../Checkbox'; import * as styles from './index.module.scss'; -type Option = { - title: AdminConsoleKey; +export type Option = { + title?: AdminConsoleKey; tag?: ReactNode; value: T; }; @@ -42,7 +42,7 @@ function CheckboxGroup({ key={value} label={ <> - + {title ? : value} {tag} } diff --git a/packages/console/src/pages/AuditLogDetails/index.tsx b/packages/console/src/pages/AuditLogDetails/index.tsx index 8789187b6f1..a5eaa834fff 100644 --- a/packages/console/src/pages/AuditLogDetails/index.tsx +++ b/packages/console/src/pages/AuditLogDetails/index.tsx @@ -1,4 +1,5 @@ -import type { Application, User, Log, Hook } from '@logto/schemas'; +/* eslint-disable complexity */ +import type { Application, Hook, Log, User } from '@logto/schemas'; import { demoAppApplicationId } from '@logto/schemas'; import { conditional } from '@silverhand/essentials'; import { useTranslation } from 'react-i18next'; @@ -10,13 +11,13 @@ import DetailsPage from '@/components/DetailsPage'; import PageMeta from '@/components/PageMeta'; import UserName from '@/components/UserName'; import { logEventTitle } from '@/consts/logs'; -import { hookEventLogKey } from '@/consts/webhooks'; import Card from '@/ds-components/Card'; import CodeEditor from '@/ds-components/CodeEditor'; import DangerousRaw from '@/ds-components/DangerousRaw'; import FormField from '@/ds-components/FormField'; import TabNav, { TabNavItem } from '@/ds-components/TabNav'; import type { RequestError } from '@/hooks/use-api'; +import { isWebhookEventLogKey } from '@/pages/WebhookDetails/utils'; import { getUserTitle } from '@/utils/user'; import EventIcon from './components/EventIcon'; @@ -28,9 +29,6 @@ const getAuditLogDetailsRelatedResourceLink = (pathname: string) => const getDetailsTabNavLink = (logId: string, userId?: string) => userId ? `/users/${userId}/logs/${logId}` : `/audit-logs/${logId}`; -const isWebhookEventLog = (key?: string) => - key && Object.values(hookEventLogKey).includes(key); - function AuditLogDetails() { const { appId, userId, hookId, logId } = useParams(); const { pathname } = useLocation(); @@ -70,7 +68,7 @@ function AuditLogDetails() { return null; } - const isWebHookEvent = isWebhookEventLog(data?.key); + const isWebHookEvent = isWebhookEventLogKey(data?.key ?? ''); return ( ({ - title: , - value: hookEventLogKey[event], +// TODO: Remove dev feature guard +const webhookEvents = isDevFeaturesEnabled ? hookEvents : interactionHookEvents; + +const hookLogEventOptions = webhookEvents.map((event) => ({ + title: event, + value: buildHookEventLogKey(event), })); function WebhookLogs() { @@ -96,13 +99,7 @@ function WebhookLogs() { title: t('logs.event'), dataIndex: 'event', colSpan: 6, - render: ({ key }) => { - // TODO: Implement all hook events - const event = Object.values(InteractionHookEvent).find( - (event) => hookEventLogKey[event] === key - ); - return conditional(event && t(hookEventLabel[event])) ?? '-'; - }, + render: ({ key }) => getHookEventKey(key), }, { title: t('logs.time'), diff --git a/packages/console/src/pages/WebhookDetails/utils.ts b/packages/console/src/pages/WebhookDetails/utils.ts index 84a134e55f2..237a562b87d 100644 --- a/packages/console/src/pages/WebhookDetails/utils.ts +++ b/packages/console/src/pages/WebhookDetails/utils.ts @@ -1,4 +1,4 @@ -import { type Hook } from '@logto/schemas'; +import { hookEvents, type Hook, type HookEvent, type WebhookLogKey } from '@logto/schemas'; import { conditional } from '@silverhand/essentials'; import { type WebhookDetailsFormType } from './types'; @@ -47,3 +47,20 @@ export const webhookDetailsParser = { }; }, }; + +export const buildHookEventLogKey = (event: HookEvent): WebhookLogKey => `TriggerHook.${event}`; + +export const isWebhookEventLogKey = (logKey: string): logKey is WebhookLogKey => { + const [prefix, ...events] = logKey.split('.'); + + // eslint-disable-next-line no-restricted-syntax + return prefix === 'TriggerHook' && hookEvents.includes(events.join('.') as HookEvent); +}; + +export const getHookEventKey = (logKey: string) => { + if (!isWebhookEventLogKey(logKey)) { + return ' - '; + } + + return logKey.replace('TriggerHook.', ''); +}; diff --git a/packages/console/src/pages/Webhooks/index.tsx b/packages/console/src/pages/Webhooks/index.tsx index c2a622cd9a1..04f925e78c0 100644 --- a/packages/console/src/pages/Webhooks/index.tsx +++ b/packages/console/src/pages/Webhooks/index.tsx @@ -1,4 +1,4 @@ -import { type Hook, Theme, type HookResponse, type InteractionHookEvent } from '@logto/schemas'; +import { Theme, type Hook, type HookResponse } from '@logto/schemas'; import { conditional } from '@silverhand/essentials'; import { toast } from 'react-hot-toast'; import { useTranslation } from 'react-i18next'; @@ -14,7 +14,6 @@ import ItemPreview from '@/components/ItemPreview'; import ListPage from '@/components/ListPage'; import SuccessRate from '@/components/SuccessRate'; import { defaultPageSize } from '@/consts'; -import { hookEventLabel } from '@/consts/webhooks'; import Button from '@/ds-components/Button'; import DynamicT from '@/ds-components/DynamicT'; import TablePlaceholder from '@/ds-components/Table/TablePlaceholder'; @@ -91,14 +90,7 @@ function Webhooks() { colSpan: 6, render: ({ event, events }) => { const eventArray = conditional(events.length > 0 && events) ?? [event]; - return ( - eventArray - // TODO: Implement all hook events - // eslint-disable-next-line unicorn/prefer-native-coercion-functions - .filter((_event): _event is InteractionHookEvent => Boolean(_event)) - .map((_event) => t(hookEventLabel[_event])) - .join(', ') - ); + return eventArray.join(', '); }, }, { diff --git a/packages/integration-tests/src/tests/api/hook/hook.trigger.interaction.test.ts b/packages/integration-tests/src/tests/api/hook/hook.trigger.interaction.test.ts index 5d9fa08b8d2..7fe528e69c3 100644 --- a/packages/integration-tests/src/tests/api/hook/hook.trigger.interaction.test.ts +++ b/packages/integration-tests/src/tests/api/hook/hook.trigger.interaction.test.ts @@ -24,7 +24,7 @@ import { enableAllVerificationCodeSignInMethods, } from '#src/helpers/sign-in-experience.js'; import { UserApiTest, generateNewUserProfile } from '#src/helpers/user.js'; -import { generateEmail, generatePassword } from '#src/utils.js'; +import { generateEmail, generatePassword, waitFor } from '#src/utils.js'; import WebhookMockServer, { mockHookResponseGuard, verifySignature } from './WebhookMockServer.js'; @@ -47,6 +47,9 @@ const assertHookLogResult = async ( hookPayload?: Record; } ) => { + // Since the webhook request is async, we need to wait for a while to ensure the webhook response is received. + await waitFor(50); + const logs = await getWebhookRecentLogs( hookId, new URLSearchParams({ logKey: `TriggerHook.${event}`, page_size: '10' }) diff --git a/packages/integration-tests/src/tests/console/webhooks/helpers.ts b/packages/integration-tests/src/tests/console/webhooks/helpers.ts index 9d38da29f59..bfdfb03bdaf 100644 --- a/packages/integration-tests/src/tests/console/webhooks/helpers.ts +++ b/packages/integration-tests/src/tests/console/webhooks/helpers.ts @@ -2,8 +2,8 @@ import { type Page } from 'puppeteer'; export const expectToCreateWebhook = async (page: Page) => { await expect(page).toClick('div[class$=main] div[class$=headline] > button'); - await expect(page).toClick('span[class$=label]', { text: 'Create new account' }); - await expect(page).toClick('span[class$=label]', { text: 'Sign in' }); + await expect(page).toClick('span[class$=label]', { text: 'PostRegister' }); + await expect(page).toClick('span[class$=label]', { text: 'User.Updated' }); await expect(page).toFill('input[name=name]', 'hook_name'); await expect(page).toFill('input[name=url]', 'https://localhost/webhook'); await expect(page).toClick('button[type=submit]'); diff --git a/packages/integration-tests/src/tests/console/webhooks/index.test.ts b/packages/integration-tests/src/tests/console/webhooks/index.test.ts index 4573c52f8de..4ad99d4b880 100644 --- a/packages/integration-tests/src/tests/console/webhooks/index.test.ts +++ b/packages/integration-tests/src/tests/console/webhooks/index.test.ts @@ -1,13 +1,13 @@ import { logtoConsoleUrl as logtoConsoleUrlString } from '#src/constants.js'; import { - goToAdminConsole, - expectToSaveChanges, - waitForToast, - expectToClickModalAction, - expectToClickDetailsPageOption, - expectModalWithTitle, expectConfirmModalAndAct, expectMainPageWithTitle, + expectModalWithTitle, + expectToClickDetailsPageOption, + expectToClickModalAction, + expectToSaveChanges, + goToAdminConsole, + waitForToast, } from '#src/ui-helpers/index.js'; import { appendPathname, dcls, expectNavigation } from '#src/utils.js'; @@ -63,8 +63,8 @@ describe('webhooks', () => { await expectNavigation(page.goto(appendPathname('/console/webhooks', logtoConsoleUrl).href)); await expect(page).toClick('div[class$=main] div[class$=headline] > button'); - await expect(page).toClick('span[class$=label]', { text: 'Create new account' }); - await expect(page).toClick('span[class$=label]', { text: 'Sign in' }); + await expect(page).toClick('span[class$=label]', { text: 'PostRegister' }); + await expect(page).toClick('span[class$=label]', { text: 'User.Create' }); await expect(page).toFill('input[name=name]', 'hook_name'); await expect(page).toFill('input[name=url]', 'http://localhost/webhook'); await expect(page).toClick('button[type=submit]'); diff --git a/packages/phrases/src/locales/de/translation/admin-console/webhooks.ts b/packages/phrases/src/locales/de/translation/admin-console/webhooks.ts index 6449feaebb9..240bb9bb574 100644 --- a/packages/phrases/src/locales/de/translation/admin-console/webhooks.ts +++ b/packages/phrases/src/locales/de/translation/admin-console/webhooks.ts @@ -4,10 +4,21 @@ const webhooks = { subtitle: 'Erstellen Sie Webhooks, um mühelos Echtzeit-Updates zu bestimmten Ereignissen zu empfangen.', create: 'Webhook erstellen', - events: { - post_register: 'Neuen Account anlegen', - post_sign_in: 'Anmelden', - post_reset_password: 'Passwort zurücksetzen', + schemas: { + /** UNTRANSLATED */ + interaction: 'User interaction', + /** UNTRANSLATED */ + user: 'User', + /** UNTRANSLATED */ + organization: 'Organization', + /** UNTRANSLATED */ + role: 'Role', + /** UNTRANSLATED */ + scope: 'Permission', + /** UNTRANSLATED */ + organization_role: 'Organization role', + /** UNTRANSLATED */ + organization_scope: 'Organization permission', }, table: { name: 'Name', diff --git a/packages/phrases/src/locales/en/translation/admin-console/webhooks.ts b/packages/phrases/src/locales/en/translation/admin-console/webhooks.ts index 7aef5f00040..2b6e5250c7c 100644 --- a/packages/phrases/src/locales/en/translation/admin-console/webhooks.ts +++ b/packages/phrases/src/locales/en/translation/admin-console/webhooks.ts @@ -3,10 +3,14 @@ const webhooks = { title: 'Webhooks', subtitle: 'Create webhooks to effortlessly receive real-time updates regarding specific events.', create: 'Create Webhook', - events: { - post_register: 'Create new account', - post_sign_in: 'Sign in', - post_reset_password: 'Reset password', + schemas: { + interaction: 'User interaction', + user: 'User', + organization: 'Organization', + role: 'Role', + scope: 'Permission', + organization_role: 'Organization role', + organization_scope: 'Organization permission', }, table: { name: 'Name', diff --git a/packages/phrases/src/locales/es/translation/admin-console/webhooks.ts b/packages/phrases/src/locales/es/translation/admin-console/webhooks.ts index 798f63a34e2..4323da5abc6 100644 --- a/packages/phrases/src/locales/es/translation/admin-console/webhooks.ts +++ b/packages/phrases/src/locales/es/translation/admin-console/webhooks.ts @@ -4,10 +4,21 @@ const webhooks = { subtitle: 'Crea webhooks para recibir de manera fácil actualizaciones en tiempo real sobre eventos específicos.', create: 'Crear Webhook', - events: { - post_register: 'Crear nueva cuenta', - post_sign_in: 'Iniciar sesión', - post_reset_password: 'Restablecer contraseña', + schemas: { + /** UNTRANSLATED */ + interaction: 'User interaction', + /** UNTRANSLATED */ + user: 'User', + /** UNTRANSLATED */ + organization: 'Organization', + /** UNTRANSLATED */ + role: 'Role', + /** UNTRANSLATED */ + scope: 'Permission', + /** UNTRANSLATED */ + organization_role: 'Organization role', + /** UNTRANSLATED */ + organization_scope: 'Organization permission', }, table: { name: 'Nombre', diff --git a/packages/phrases/src/locales/fr/translation/admin-console/webhooks.ts b/packages/phrases/src/locales/fr/translation/admin-console/webhooks.ts index 37bde2c1a5c..adc6ce86ae6 100644 --- a/packages/phrases/src/locales/fr/translation/admin-console/webhooks.ts +++ b/packages/phrases/src/locales/fr/translation/admin-console/webhooks.ts @@ -4,10 +4,21 @@ const webhooks = { subtitle: 'Créez des webhooks pour recevoir sans effort des mises à jour en temps réel concernant des événements spécifiques.', create: 'Créer un webhook', - events: { - post_register: 'Nouveau compte créé', - post_sign_in: 'Connectez-vous', - post_reset_password: 'Réinitialiser le mot de passe', + schemas: { + /** UNTRANSLATED */ + interaction: 'User interaction', + /** UNTRANSLATED */ + user: 'User', + /** UNTRANSLATED */ + organization: 'Organization', + /** UNTRANSLATED */ + role: 'Role', + /** UNTRANSLATED */ + scope: 'Permission', + /** UNTRANSLATED */ + organization_role: 'Organization role', + /** UNTRANSLATED */ + organization_scope: 'Organization permission', }, table: { name: 'Nom', diff --git a/packages/phrases/src/locales/it/translation/admin-console/webhooks.ts b/packages/phrases/src/locales/it/translation/admin-console/webhooks.ts index 6ff9208488c..ecc98cdbafc 100644 --- a/packages/phrases/src/locales/it/translation/admin-console/webhooks.ts +++ b/packages/phrases/src/locales/it/translation/admin-console/webhooks.ts @@ -4,10 +4,21 @@ const webhooks = { subtitle: 'Crea webhook per ricevere facilmente aggiornamenti in tempo reale relativi a eventi specifici.', create: 'Crea Webhook', - events: { - post_register: 'Crea nuovo account', - post_sign_in: 'Accedi', - post_reset_password: 'Reimposta password', + schemas: { + /** UNTRANSLATED */ + interaction: 'User interaction', + /** UNTRANSLATED */ + user: 'User', + /** UNTRANSLATED */ + organization: 'Organization', + /** UNTRANSLATED */ + role: 'Role', + /** UNTRANSLATED */ + scope: 'Permission', + /** UNTRANSLATED */ + organization_role: 'Organization role', + /** UNTRANSLATED */ + organization_scope: 'Organization permission', }, table: { name: 'Nome', diff --git a/packages/phrases/src/locales/ja/translation/admin-console/webhooks.ts b/packages/phrases/src/locales/ja/translation/admin-console/webhooks.ts index 8359cf3fd59..38a5767a181 100644 --- a/packages/phrases/src/locales/ja/translation/admin-console/webhooks.ts +++ b/packages/phrases/src/locales/ja/translation/admin-console/webhooks.ts @@ -3,10 +3,21 @@ const webhooks = { title: 'Webhooks', subtitle: '特定のイベントに関するリアルタイムの更新を手軽に受け取るためにWebhookを作成します。', create: 'Webhookを作成する', - events: { - post_register: '新しいアカウントを作成する', - post_sign_in: 'サインインする', - post_reset_password: 'パスワードをリセットする', + schemas: { + /** UNTRANSLATED */ + interaction: 'User interaction', + /** UNTRANSLATED */ + user: 'User', + /** UNTRANSLATED */ + organization: 'Organization', + /** UNTRANSLATED */ + role: 'Role', + /** UNTRANSLATED */ + scope: 'Permission', + /** UNTRANSLATED */ + organization_role: 'Organization role', + /** UNTRANSLATED */ + organization_scope: 'Organization permission', }, table: { name: '名前', diff --git a/packages/phrases/src/locales/ko/translation/admin-console/webhooks.ts b/packages/phrases/src/locales/ko/translation/admin-console/webhooks.ts index eb61cd51bf5..ba76cf57c95 100644 --- a/packages/phrases/src/locales/ko/translation/admin-console/webhooks.ts +++ b/packages/phrases/src/locales/ko/translation/admin-console/webhooks.ts @@ -3,10 +3,21 @@ const webhooks = { title: '웹훅', subtitle: '특정 이벤트에 대한 실시간 업데이트를 쉽게 수신할 수 있는 웹훅을 생성하세요.', create: '웹훅 생성', - events: { - post_register: '새 계정 만들기', - post_sign_in: '로그인', - post_reset_password: '비밀번호 재설정', + schemas: { + /** UNTRANSLATED */ + interaction: 'User interaction', + /** UNTRANSLATED */ + user: 'User', + /** UNTRANSLATED */ + organization: 'Organization', + /** UNTRANSLATED */ + role: 'Role', + /** UNTRANSLATED */ + scope: 'Permission', + /** UNTRANSLATED */ + organization_role: 'Organization role', + /** UNTRANSLATED */ + organization_scope: 'Organization permission', }, table: { name: '이름', diff --git a/packages/phrases/src/locales/pl-pl/translation/admin-console/webhooks.ts b/packages/phrases/src/locales/pl-pl/translation/admin-console/webhooks.ts index 527e9d519c4..6a438b010ca 100644 --- a/packages/phrases/src/locales/pl-pl/translation/admin-console/webhooks.ts +++ b/packages/phrases/src/locales/pl-pl/translation/admin-console/webhooks.ts @@ -4,10 +4,21 @@ const webhooks = { subtitle: 'Utwórz webhooki, aby bez wysiłku otrzymywać aktualizacje w czasie rzeczywistym dotyczące określonych zdarzeń.', create: 'Utwórz webhook', - events: { - post_register: 'Utwórz nowe konto', - post_sign_in: 'Zaloguj się', - post_reset_password: 'Zresetuj hasło', + schemas: { + /** UNTRANSLATED */ + interaction: 'User interaction', + /** UNTRANSLATED */ + user: 'User', + /** UNTRANSLATED */ + organization: 'Organization', + /** UNTRANSLATED */ + role: 'Role', + /** UNTRANSLATED */ + scope: 'Permission', + /** UNTRANSLATED */ + organization_role: 'Organization role', + /** UNTRANSLATED */ + organization_scope: 'Organization permission', }, table: { name: 'Nazwa', diff --git a/packages/phrases/src/locales/pt-br/translation/admin-console/webhooks.ts b/packages/phrases/src/locales/pt-br/translation/admin-console/webhooks.ts index f9bcbdfbb54..c4bd07a2858 100644 --- a/packages/phrases/src/locales/pt-br/translation/admin-console/webhooks.ts +++ b/packages/phrases/src/locales/pt-br/translation/admin-console/webhooks.ts @@ -4,10 +4,21 @@ const webhooks = { subtitle: 'Crie ganchos da web para receber atualizações em tempo real sobre eventos específicos sem esforço.', create: 'Criar Webhook', - events: { - post_register: 'Criar nova conta', - post_sign_in: 'Entrar', - post_reset_password: 'Redefinir senha', + schemas: { + /** UNTRANSLATED */ + interaction: 'User interaction', + /** UNTRANSLATED */ + user: 'User', + /** UNTRANSLATED */ + organization: 'Organization', + /** UNTRANSLATED */ + role: 'Role', + /** UNTRANSLATED */ + scope: 'Permission', + /** UNTRANSLATED */ + organization_role: 'Organization role', + /** UNTRANSLATED */ + organization_scope: 'Organization permission', }, table: { name: 'Nome', diff --git a/packages/phrases/src/locales/pt-pt/translation/admin-console/webhooks.ts b/packages/phrases/src/locales/pt-pt/translation/admin-console/webhooks.ts index 2b31db5628a..c9c68ae2127 100644 --- a/packages/phrases/src/locales/pt-pt/translation/admin-console/webhooks.ts +++ b/packages/phrases/src/locales/pt-pt/translation/admin-console/webhooks.ts @@ -3,10 +3,21 @@ const webhooks = { title: 'Webhooks', subtitle: 'Crie webhooks para receber atualizações em tempo real sobre eventos específicos.', create: 'Criar Webhook', - events: { - post_register: 'Criar nova conta', - post_sign_in: 'Entrar', - post_reset_password: 'Redefinir senha', + schemas: { + /** UNTRANSLATED */ + interaction: 'User interaction', + /** UNTRANSLATED */ + user: 'User', + /** UNTRANSLATED */ + organization: 'Organization', + /** UNTRANSLATED */ + role: 'Role', + /** UNTRANSLATED */ + scope: 'Permission', + /** UNTRANSLATED */ + organization_role: 'Organization role', + /** UNTRANSLATED */ + organization_scope: 'Organization permission', }, table: { name: 'Nome', diff --git a/packages/phrases/src/locales/ru/translation/admin-console/webhooks.ts b/packages/phrases/src/locales/ru/translation/admin-console/webhooks.ts index 40b98de17df..e26d245267e 100644 --- a/packages/phrases/src/locales/ru/translation/admin-console/webhooks.ts +++ b/packages/phrases/src/locales/ru/translation/admin-console/webhooks.ts @@ -4,10 +4,21 @@ const webhooks = { subtitle: 'Создайте вебхуки, чтобы легко получать обновления в реальном времени относительно определенных событий.', create: 'Создать вебхук', - events: { - post_register: 'Создать новый аккаунт', - post_sign_in: 'Войти', - post_reset_password: 'Сбросить пароль', + schemas: { + /** UNTRANSLATED */ + interaction: 'User interaction', + /** UNTRANSLATED */ + user: 'User', + /** UNTRANSLATED */ + organization: 'Organization', + /** UNTRANSLATED */ + role: 'Role', + /** UNTRANSLATED */ + scope: 'Permission', + /** UNTRANSLATED */ + organization_role: 'Organization role', + /** UNTRANSLATED */ + organization_scope: 'Organization permission', }, table: { name: 'Имя', diff --git a/packages/phrases/src/locales/tr-tr/translation/admin-console/webhooks.ts b/packages/phrases/src/locales/tr-tr/translation/admin-console/webhooks.ts index 1aa442df296..32e7e2843f5 100644 --- a/packages/phrases/src/locales/tr-tr/translation/admin-console/webhooks.ts +++ b/packages/phrases/src/locales/tr-tr/translation/admin-console/webhooks.ts @@ -4,10 +4,21 @@ const webhooks = { subtitle: 'Belirli olaylarla ilgili gerçek zamanlı güncellemeler almak için webhooklar oluşturun.', create: 'Webhook Oluştur', - events: { - post_register: 'Yeni hesap oluştur', - post_sign_in: 'Oturum açın', - post_reset_password: 'Parolayı sıfırla', + schemas: { + /** UNTRANSLATED */ + interaction: 'User interaction', + /** UNTRANSLATED */ + user: 'User', + /** UNTRANSLATED */ + organization: 'Organization', + /** UNTRANSLATED */ + role: 'Role', + /** UNTRANSLATED */ + scope: 'Permission', + /** UNTRANSLATED */ + organization_role: 'Organization role', + /** UNTRANSLATED */ + organization_scope: 'Organization permission', }, table: { name: 'Adı', diff --git a/packages/phrases/src/locales/zh-cn/translation/admin-console/webhooks.ts b/packages/phrases/src/locales/zh-cn/translation/admin-console/webhooks.ts index fdf993fae52..4497fc6cd19 100644 --- a/packages/phrases/src/locales/zh-cn/translation/admin-console/webhooks.ts +++ b/packages/phrases/src/locales/zh-cn/translation/admin-console/webhooks.ts @@ -3,10 +3,21 @@ const webhooks = { title: 'Webhooks', subtitle: '创建 Webhooks 以轻松接收有关特定事件的实时更新。', create: '创建 Webhook', - events: { - post_register: '创建新账户', - post_sign_in: '登录', - post_reset_password: '重置密码', + schemas: { + /** UNTRANSLATED */ + interaction: 'User interaction', + /** UNTRANSLATED */ + user: 'User', + /** UNTRANSLATED */ + organization: 'Organization', + /** UNTRANSLATED */ + role: 'Role', + /** UNTRANSLATED */ + scope: 'Permission', + /** UNTRANSLATED */ + organization_role: 'Organization role', + /** UNTRANSLATED */ + organization_scope: 'Organization permission', }, table: { name: '名称', diff --git a/packages/phrases/src/locales/zh-hk/translation/admin-console/webhooks.ts b/packages/phrases/src/locales/zh-hk/translation/admin-console/webhooks.ts index e3087e772a3..74ec1629714 100644 --- a/packages/phrases/src/locales/zh-hk/translation/admin-console/webhooks.ts +++ b/packages/phrases/src/locales/zh-hk/translation/admin-console/webhooks.ts @@ -3,10 +3,21 @@ const webhooks = { title: 'Webhooks', subtitle: '創建 Webhooks,輕鬆地接收有關特定事件的實時更新。', create: '創建 Webhook', - events: { - post_register: '創建新帳戶', - post_sign_in: '登錄', - post_reset_password: '重置密碼', + schemas: { + /** UNTRANSLATED */ + interaction: 'User interaction', + /** UNTRANSLATED */ + user: 'User', + /** UNTRANSLATED */ + organization: 'Organization', + /** UNTRANSLATED */ + role: 'Role', + /** UNTRANSLATED */ + scope: 'Permission', + /** UNTRANSLATED */ + organization_role: 'Organization role', + /** UNTRANSLATED */ + organization_scope: 'Organization permission', }, table: { name: '名稱', diff --git a/packages/phrases/src/locales/zh-tw/translation/admin-console/webhooks.ts b/packages/phrases/src/locales/zh-tw/translation/admin-console/webhooks.ts index 3cd34871c61..59aa90d2610 100644 --- a/packages/phrases/src/locales/zh-tw/translation/admin-console/webhooks.ts +++ b/packages/phrases/src/locales/zh-tw/translation/admin-console/webhooks.ts @@ -3,10 +3,21 @@ const webhooks = { title: 'Webhooks', subtitle: '創建 Webhook 以輕鬆收到特定事件的即時更新。', create: '創建 Webhook', - events: { - post_register: '創建新帳戶', - post_sign_in: '登錄', - post_reset_password: '重置密碼', + schemas: { + /** UNTRANSLATED */ + interaction: 'User interaction', + /** UNTRANSLATED */ + user: 'User', + /** UNTRANSLATED */ + organization: 'Organization', + /** UNTRANSLATED */ + role: 'Role', + /** UNTRANSLATED */ + scope: 'Permission', + /** UNTRANSLATED */ + organization_role: 'Organization role', + /** UNTRANSLATED */ + organization_scope: 'Organization permission', }, table: { name: '名稱', diff --git a/packages/schemas/src/foundations/jsonb-types/hooks.ts b/packages/schemas/src/foundations/jsonb-types/hooks.ts index 87746a3bff4..3505b810744 100644 --- a/packages/schemas/src/foundations/jsonb-types/hooks.ts +++ b/packages/schemas/src/foundations/jsonb-types/hooks.ts @@ -15,7 +15,7 @@ export enum InteractionHookEvent { } // DataHookEvent -enum DataHookSchema { +export enum DataHookSchema { User = 'User', Role = 'Role', Scope = 'Scope', From 7216f2ac967de1289cb1f8a4b83345dfbfafe0ba Mon Sep 17 00:00:00 2001 From: simeng-li Date: Thu, 16 May 2024 10:52:08 +0800 Subject: [PATCH 394/687] fix(console): update the svelte integration guide (#5869) update the svelte integration guide --- .../docs/guides/web-sveltekit/README.mdx | 20 +++++++------------ 1 file changed, 7 insertions(+), 13 deletions(-) diff --git a/packages/console/src/assets/docs/guides/web-sveltekit/README.mdx b/packages/console/src/assets/docs/guides/web-sveltekit/README.mdx index 0060639c4ee..3dbe09dc707 100644 --- a/packages/console/src/assets/docs/guides/web-sveltekit/README.mdx +++ b/packages/console/src/assets/docs/guides/web-sveltekit/README.mdx @@ -42,6 +42,8 @@ pnpm add @logto/sveltekit +Create a `hooks.server.ts` file in your project `src` root if you don't have one. This file is used to define server hooks for your SvelteKit app. + In your `hooks.server.ts` file, add the following code to inject the Logto hook into your server:
@@ -134,7 +136,9 @@ export const actions: Actions = {
     await locals.logtoClient.signIn('${props.redirectUris[0] ?? 'http://localhost:3000/callback'}');
   },
   signOut: async ({ locals }) => {
-    await locals.logtoClient.signOut('${props.postLogoutRedirectUris[0] ?? 'http://localhost:3000'}');
+    await locals.logtoClient.signOut('${
+      props.postLogoutRedirectUris[0] ?? 'http://localhost:3000'
+    }');
   },
 };
 `}
@@ -152,23 +156,12 @@ Then use these actions in your Svelte component:
 
 
 
-
-
-Since Nuxt pages will be hydrated and become a single-page application (SPA) after the initial load, we need to redirect the user to the sign-in or sign-out route when needed.
-
-```html
-Sign in
-
-Sign out -``` - -
- To display the user's information, you can inject the `locals.user` object into the layout, thus making it available to all pages: ```ts +// +layout.server.ts import type { LayoutServerLoad } from './$types'; export const load: LayoutServerLoad = async ({ locals }) => { @@ -179,6 +172,7 @@ export const load: LayoutServerLoad = async ({ locals }) => { In your Svelte component: ```html +{/* +page.svelte */} `} - -
+
@@ -59,15 +57,13 @@ First, let’s enter your redirect URI. E.g. `https://your-awesome-site.webflow. Return to your Webflow designer, drag and drop a "Sign in" button to the home page, and assign it an ID “sign-in” for later reference using `getElementById()`. -
-  
+
     {``}
-  
-
+ ### Handle redirect @@ -99,13 +95,11 @@ After signing out, it'll be great to redirect user back to your website. Let's a Return to the Webflow designer, and add a “Sign out” button on your home page. Similarly, assign an ID “sign-out” to the button, and add the following code to the page-level custom code. -
-  
+
     {`const signOutButton = document.getElementById('sign-out');
 const onClickSignOut = () => logtoClient.signOut('${props.postLogoutRedirectUris[0] ?? 'https://your-awesome-site.webflow.io'}');
 signOutButton.addEventListener('click', onClickSignOut);`}
-  
-
+ diff --git a/packages/console/src/assets/docs/guides/web-dotnet-core-blazor-server/README.mdx b/packages/console/src/assets/docs/guides/web-dotnet-core-blazor-server/README.mdx index 1258ea8a865..af12ef46d4c 100644 --- a/packages/console/src/assets/docs/guides/web-dotnet-core-blazor-server/README.mdx +++ b/packages/console/src/assets/docs/guides/web-dotnet-core-blazor-server/README.mdx @@ -24,8 +24,7 @@ dotnet add package Logto.AspNetCore.Authentication Open `Startup.cs` (or `Program.cs`) and add the following code to register Logto authentication middleware: -
-  
+
 {`using Logto.AspNetCore.Authentication;
 
 var builder = WebApplication.CreateBuilder(args);
@@ -38,8 +37,7 @@ builder.Services.AddLogtoAuthentication(options =>
 });
 
 app.UseAuthentication();`}
-  
-
+ The `AddLogtoAuthentication` method will do the following things: diff --git a/packages/console/src/assets/docs/guides/web-dotnet-core-blazor-wasm/README.mdx b/packages/console/src/assets/docs/guides/web-dotnet-core-blazor-wasm/README.mdx index 75718996401..1d111256d4e 100644 --- a/packages/console/src/assets/docs/guides/web-dotnet-core-blazor-wasm/README.mdx +++ b/packages/console/src/assets/docs/guides/web-dotnet-core-blazor-wasm/README.mdx @@ -90,8 +90,7 @@ For example, set the URI to {props.sampleUrls.origin + 'SignedOutCallback' Add the following code to the `appsettings.json` file: -
-  
+
 {`// ...
   IdentityServer: {
     Authority: '${props.endpoint}oidc',
@@ -103,8 +102,7 @@ Add the following code to the `appsettings.json` file:
   },
 }
 `}
-    
-
+ diff --git a/packages/console/src/assets/docs/guides/web-dotnet-core-mvc/README.mdx b/packages/console/src/assets/docs/guides/web-dotnet-core-mvc/README.mdx index 8fa99eea24c..4b109614ef5 100644 --- a/packages/console/src/assets/docs/guides/web-dotnet-core-mvc/README.mdx +++ b/packages/console/src/assets/docs/guides/web-dotnet-core-mvc/README.mdx @@ -24,8 +24,7 @@ dotnet add package Logto.AspNetCore.Authentication Open `Startup.cs` (or `Program.cs`) and add the following code to register Logto authentication middleware: -
-  
+
 {`using Logto.AspNetCore.Authentication;
 
 var builder = WebApplication.CreateBuilder(args);
@@ -38,8 +37,7 @@ builder.Services.AddLogtoAuthentication(options =>
 });
 
 app.UseAuthentication();`}
-  
-
+ The `AddLogtoAuthentication` method will do the following things: diff --git a/packages/console/src/assets/docs/guides/web-dotnet-core/README.mdx b/packages/console/src/assets/docs/guides/web-dotnet-core/README.mdx index 245a9fe3a51..0d98924340b 100644 --- a/packages/console/src/assets/docs/guides/web-dotnet-core/README.mdx +++ b/packages/console/src/assets/docs/guides/web-dotnet-core/README.mdx @@ -24,8 +24,7 @@ dotnet add package Logto.AspNetCore.Authentication Open `Startup.cs` (or `Program.cs`) and add the following code to register Logto authentication middleware: -
-  
+
 {`using Logto.AspNetCore.Authentication;
 
 var builder = WebApplication.CreateBuilder(args);
@@ -38,8 +37,7 @@ builder.Services.AddLogtoAuthentication(options =>
 });
 
 app.UseAuthentication();`}
-  
-
+ The `AddLogtoAuthentication` method will do the following things: diff --git a/packages/console/src/assets/docs/guides/web-express/README.mdx b/packages/console/src/assets/docs/guides/web-express/README.mdx index a498ee67a05..bc957f100bc 100644 --- a/packages/console/src/assets/docs/guides/web-express/README.mdx +++ b/packages/console/src/assets/docs/guides/web-express/README.mdx @@ -48,8 +48,7 @@ pnpm add @logto/express cookie-parser express-session Import and initialize LogtoClient: -
-  
+
     {`import LogtoClient from '@logto/express';
 
 export const logtoClient = new LogtoClient({
@@ -58,8 +57,7 @@ export const logtoClient = new LogtoClient({
   appSecret: '${props.app.secret}',
   baseUrl: 'http://localhost:3000', // Change to your own base URL
 });`}
-  
-
+ @@ -70,15 +68,13 @@ export const logtoClient = new LogtoClient({ The SDK requires [express-session](https://www.npmjs.com/package/express-session) to be configured in prior. -
-  
+
     {`import cookieParser from 'cookie-parser';
 import session from 'express-session';
 
 app.use(cookieParser());
 app.use(session({ secret: '${generateStandardSecret()}', cookie: { maxAge: 14 * 24 * 60 * 60 } }));`}
-  
-
+ diff --git a/packages/console/src/assets/docs/guides/web-go/README.mdx b/packages/console/src/assets/docs/guides/web-go/README.mdx index 3044cb21d9d..691056a82c9 100644 --- a/packages/console/src/assets/docs/guides/web-go/README.mdx +++ b/packages/console/src/assets/docs/guides/web-go/README.mdx @@ -144,8 +144,7 @@ sessionStorage := &SessionStorage{session: session} First, create a Logto config: -
-  
+
     {`// main.go
 func main() {
     // ...
@@ -158,8 +157,7 @@ func main() {
 
     // ...
 }`}
-  
-
+ Then, you can create a `LogtoClient` for each user request with the Logto config above: @@ -209,8 +207,7 @@ For example, if you add `http://localhost:8080/sign-in-callback` to your Redirec After the redirect URI is configured, we add a `sign-in` route to handle the sign-in request and also add an sign-in link on the home page: -
-  
+
     {`//main.go
 func main() {
     // ...
@@ -248,8 +245,7 @@ func main() {
 
     // ...
 }`}
-  
-
+ Now, when your user visit `http://localhost:8080/sign-in`, the user will be redirected to the Logto sign-in page. @@ -306,8 +302,7 @@ Assuming that you add `http://localhost:8080` to the Post Sign-out Redirect URI Now, let's add the `sign-out` route to handle the sign-out request and also add a sign-out link on the home page: -
-  
+
     {`//main.go
 func main() {
     // ...
@@ -346,8 +341,7 @@ func main() {
 
     // ...
 }`}
-  
-
+ After the user makes a signing-out request, Logto will clear all user authentication information in the session. diff --git a/packages/console/src/assets/docs/guides/web-java-spring-boot/README.mdx b/packages/console/src/assets/docs/guides/web-java-spring-boot/README.mdx index 7019654e233..b043d49b775 100644 --- a/packages/console/src/assets/docs/guides/web-java-spring-boot/README.mdx +++ b/packages/console/src/assets/docs/guides/web-java-spring-boot/README.mdx @@ -67,8 +67,7 @@ For maven, include the following dependencies in your `pom.xml` file: Register your application with Logto to get the client credentials and IdP configurations. Add the following configuration to your `application.properties` file: -
-  
+
     {`spring.security.oauth2.client.registration.logto.client-name=logto
 spring.security.oauth2.client.registration.logto.client-id=${props.app.id}
 spring.security.oauth2.client.registration.logto.client-secret=${props.app.secret}
@@ -81,8 +80,7 @@ spring.security.oauth2.client.provider.logto.issuer-uri=${props.endpoint}oidc
 spring.security.oauth2.client.provider.logto.authorization-uri=${props.endpoint}oidc/auth
 spring.security.oauth2.client.provider.logto.jwk-set-uri=${props.endpoint}oidc/jwks
   `}
-  
-
+ diff --git a/packages/console/src/assets/docs/guides/web-next-app-router/README.mdx b/packages/console/src/assets/docs/guides/web-next-app-router/README.mdx index 51cec13fd09..26915db22cc 100644 --- a/packages/console/src/assets/docs/guides/web-next-app-router/README.mdx +++ b/packages/console/src/assets/docs/guides/web-next-app-router/README.mdx @@ -47,8 +47,7 @@ pnpm add @logto/next Prepare configuration for the Logto client. Create a new file `app/logto.ts` and add the following code: -
-  
+
     {`export const logtoConfig = {
   endpoint: '${props.endpoint}',
   appId: '${props.app.id}',
@@ -58,8 +57,7 @@ Prepare configuration for the Logto client. Create a new file `app/logto.ts` and
   cookieSecure: process.env.NODE_ENV === 'production',
 };
 `}
-  
-
+ - \ No newline at end of file + diff --git a/packages/console/src/assets/docs/guides/web-next-auth/README.mdx b/packages/console/src/assets/docs/guides/web-next-auth/README.mdx index baeeff2600b..badcf966507 100644 --- a/packages/console/src/assets/docs/guides/web-next-auth/README.mdx +++ b/packages/console/src/assets/docs/guides/web-next-auth/README.mdx @@ -31,8 +31,7 @@ Modify your API route config of Next Auth, if you are using Pages Router, the fi The following is an example of App Router: -
-  
+
     {`import NextAuth from 'next-auth';
 
 const handler = NextAuth({
@@ -64,8 +63,7 @@ const handler = NextAuth({
 });
 
 export { handler as GET, handler as POST };`}
-  
-
+
diff --git a/packages/console/src/assets/docs/guides/web-next/README.mdx b/packages/console/src/assets/docs/guides/web-next/README.mdx index 0313e9dddfd..fa6100178d3 100644 --- a/packages/console/src/assets/docs/guides/web-next/README.mdx +++ b/packages/console/src/assets/docs/guides/web-next/README.mdx @@ -47,8 +47,7 @@ pnpm add @logto/next Import and initialize LogtoClient: -
-  
+
     {`// libraries/logto.js
 import LogtoClient from '@logto/next';
 
@@ -60,8 +59,7 @@ export const logtoClient = new LogtoClient({
   cookieSecret: '${generateStandardSecret()}', // Auto-generated 32 digit secret
   cookieSecure: process.env.NODE_ENV === 'production',
 });`}
-  
-
+ diff --git a/packages/console/src/assets/docs/guides/web-nuxt/README.mdx b/packages/console/src/assets/docs/guides/web-nuxt/README.mdx index 3ce9c63ca14..d4bf7ef8ece 100644 --- a/packages/console/src/assets/docs/guides/web-nuxt/README.mdx +++ b/packages/console/src/assets/docs/guides/web-nuxt/README.mdx @@ -46,7 +46,7 @@ pnpm add @logto/nuxt -In your Nuxt config file (`next.config.ts`), add the Logto module: +In your Nuxt config file (`nuxt.config.ts`), add the Logto module: ```ts export default defineNuxtConfig({ @@ -57,9 +57,8 @@ export default defineNuxtConfig({ The minimal configuration for the module is as follows: -
-  
-    {`export default defineNuxtConfig({
+
+{`export default defineNuxtConfig({
   modules: ['@logto/nuxt'],
   runtimeConfig: {
     logto: {
@@ -71,20 +70,17 @@ The minimal configuration for the module is as follows:
   },
   // ...other configurations
 });`}
-  
-
+ Since these information are sensitive, it's recommended to use environment variables (`.env`): -
-  
+
     {`NUXT_LOGTO_ENDPOINT=${props.endpoint}
 NUXT_LOGTO_APP_ID=${props.app.id}
 NUXT_LOGTO_APP_SECRET=${props.app.secret}
 NUXT_LOGTO_COOKIE_ENCRYPTION_KEY=${cookieEncryptionKey} # Random-generated
 `}
-  
-
+ See [runtime config](https://nuxt.com/docs/guide/going-further/runtime-config) for more information. diff --git a/packages/console/src/assets/docs/guides/web-php/README.mdx b/packages/console/src/assets/docs/guides/web-php/README.mdx index 08ad782494e..49122bc1a06 100644 --- a/packages/console/src/assets/docs/guides/web-php/README.mdx +++ b/packages/console/src/assets/docs/guides/web-php/README.mdx @@ -26,8 +26,7 @@ composer require logto/sdk Insert the following code into your PHP file: -
-  
+
 {`use logto\sdk\LogtoClient;
 use Logto\Sdk\LogtoConfig;
 
@@ -38,8 +37,7 @@ $client = new LogtoClient(
     appSecret: "${props.app.secret}",
   ),
 );`}
-  
-
+ By default, the SDK uses the built-in PHP session to store the Logto data. If you want to use other storage, you can pass a custom storage object as the second parameter: @@ -62,23 +60,19 @@ First, let’s enter your redirect URI. E.g. {props.sampleUrls.callback} -
-  
+
 {`Route::get('/sign-in', function () {
   return redirect($client->signIn('${props.redirectUris[0] || props.sampleUrls.callback}'));
 });`}
-  
-
+ If you want to show the sign-up page on the first screen, you can set `interactionMode` to `signUp`: -
-  
+
 {`Route::get('/sign-in', function () {
   return redirect($client->signIn('${props.redirectUris[0] || props.sampleUrls.callback}', InteractionMode::signUp));
 });`}
-  
-
+ Now, whenever your users visit `/sign-in`, it will start a new sign-in attempt and redirect the user to the Logto sign-in page. @@ -112,16 +106,14 @@ To clean up the Python session and Logto session, we can designate a post sign-o And a sign-out route can be implemented as follows: -
-  
+
 {`Route::get('/sign-out', function () {
   return redirect(
     // Redirect the user to the home page after a successful sign-out
     $client->signOut('${props.postLogoutRedirectUris[0] || props.sampleUrls.origin}')
   );
 });`}
-  
-
+ The post sign-out redierct URI is optional, and if not provided, the user will be redirected to a Logto default page after a successful sign-out (without redirecting back to your application). diff --git a/packages/console/src/assets/docs/guides/web-python/README.mdx b/packages/console/src/assets/docs/guides/web-python/README.mdx index c29d61fafa4..5900e8198f6 100644 --- a/packages/console/src/assets/docs/guides/web-python/README.mdx +++ b/packages/console/src/assets/docs/guides/web-python/README.mdx @@ -24,8 +24,7 @@ pip install logto # or `poetry add logto` or whatever you use Insert the following code into your Python file: -
-  
+
 {`from logto import LogtoClient, LogtoConfig
 
 client = LogtoClient(
@@ -35,8 +34,7 @@ client = LogtoClient(
         appSecret="${props.app.secret}",
     )
 )`}
-  
-
+ Also replace the default memory storage with a persistent storage, for example: @@ -71,21 +69,18 @@ First, let’s enter your redirect URI. E.g. {props.sampleUrls.callback} -
-  
+
 {`@app.route("/sign-in")
 async def sign_in():
     # Get the sign-in URL and redirect the user to it
     return redirect(await client.signIn(
         redirectUri="${props.redirectUris[0] || props.sampleUrls.callback}",
     ))`}
-  
-
+ If you want to show the sign-up page on the first screen, you can set `interactionMode` to `signUp`: -
-  
+
 {`@app.route("/sign-in")
 async def sign_in():
     # Get the sign-in URL and redirect the user to it
@@ -93,8 +88,7 @@ async def sign_in():
         redirectUri="${props.redirectUris[0] || props.sampleUrls.callback}",
         interactionMode="signUp", # Show the sign-up page on the first screen
     ))`}
-  
-
+ Now, whenever your users visit `/sign-in`, it will start a new sign-in attempt and redirect the user to the Logto sign-in page. @@ -104,8 +98,7 @@ Now, whenever your users visit `/sign-in`, it will start a new sign-in attempt a After the user signs in, Logto will redirect the user to the callback URL you set in the Logto Console. In this example, we use `/callback` as the callback URL: -
-  
+
 {`@app.route("/callback")
 async def callback():
     try:
@@ -115,8 +108,7 @@ async def callback():
         # Change this to your error handling logic
         return "Error: " + str(e)
 `}
-  
-
+
@@ -128,8 +120,7 @@ To clean up the Python session and Logto session, we can designate a post sign-o And a sign-out route can be implemented as follows: -
-  
+
 {`@app.route("/sign-out")
 async def sign_out():
     return redirect(
@@ -137,8 +128,7 @@ async def sign_out():
         await client.signOut(postLogoutRedirectUri="${props.postLogoutRedirectUris[0] || props.sampleUrls.origin}")
     )
 `}
-  
-
+ `postLogoutRedirectUri` is optional, and if not provided, the user will be redirected to a Logto default page after a successful sign-out (without redirecting back to your application). diff --git a/packages/console/src/assets/docs/guides/web-remix/README.mdx b/packages/console/src/assets/docs/guides/web-remix/README.mdx index 2c196c55907..a476caf5471 100644 --- a/packages/console/src/assets/docs/guides/web-remix/README.mdx +++ b/packages/console/src/assets/docs/guides/web-remix/README.mdx @@ -45,8 +45,7 @@ pnpm add @logto/remix Before initializing the SDK, we have to create a `SessionStorage` instance which takes care of the session persistence. In our case, we want to use a cookie-based session: -
-  
+
     {`
 // services/authentication.ts
 import { createCookieSessionStorage } from "@remix-run/node";
@@ -58,8 +57,7 @@ const sessionStorage = createCookieSessionStorage({
     secrets: '${generateStandardSecret()}', // Auto-generated secret
   },
 });`}
-  
-
+ @@ -70,8 +68,7 @@ const sessionStorage = createCookieSessionStorage({ Use the `sessionStorage` created in the previous step to initialize LogtoClient: -
-  
+
     {`// app/services/authentication.ts
 
 import { makeLogtoRemix } from "@logto/remix";
@@ -85,8 +82,7 @@ export const logto = makeLogtoRemix(
   },
   { sessionStorage }
 );`}
-  
-
+ diff --git a/packages/console/src/assets/docs/guides/web-ruby/README.mdx b/packages/console/src/assets/docs/guides/web-ruby/README.mdx index c94ffd88369..0f19d4387fb 100644 --- a/packages/console/src/assets/docs/guides/web-ruby/README.mdx +++ b/packages/console/src/assets/docs/guides/web-ruby/README.mdx @@ -32,8 +32,7 @@ The following demonstration is for Ruby on Rails. However, you can apply the sam In the file where you want to initialize the Logto client (e.g. a base controller or a middleware), add the following code: -
-  
+
     {`require "logto/client"
 
 @client = LogtoClient.new(
@@ -46,13 +45,11 @@ In the file where you want to initialize the Logto client (e.g. a base controlle
   storage: LogtoClient::SessionStorage.new(the_session_object)
 )
 end`}
-  
-
+ For instance, in a Rails controller, the code might look like this: -
-  
+
     {`# app/controllers/sample_controller.rb
 require "logto/client"
 
@@ -75,8 +72,7 @@ class SampleController < ApplicationController
     )
   end
 end`}
-  
-
+ @@ -104,26 +100,22 @@ After signing out, it'll be great to redirect user back to your website. For exa Since the redirect URI has been set to {props.redirectUris[0] || 'http://localhost:3000/callback'}, it needs to be handled it in our application. In a Rails controller, you can add the following code:

-
-  
+
     {`# app/controllers/sample_controller.rb
 class SampleController < ApplicationController
   def ${props.redirectUris[0]?.split('/').pop() || 'callback'}
     @client.handle_sign_in_callback(url: request.original_url)
   end
 end`}
-  
-
+ And configure the route in `config/routes.rb`: -
-  
+
     {`Rails.application.routes.draw do
   get "${new URL(props.redirectUris[0] || 'http://localhost:3000/callback').pathname}", to: "sample#${props.redirectUris[0]?.split('/').pop() || 'callback'}"
 end`}
-  
-
+ @@ -133,8 +125,7 @@ end`} There are various ways to invoke sign-in and sign-out in your application. For example, you can implement two routes in your Rails application: -
-  
+
     {`# app/controllers/sample_controller.rb
 class SampleController < ApplicationController
   def sign_in
@@ -147,8 +138,7 @@ class SampleController < ApplicationController
 
   # ...
 end`}
-  
-
+ ```ruby # config/routes.rb diff --git a/packages/console/src/assets/docs/guides/web-sveltekit/README.mdx b/packages/console/src/assets/docs/guides/web-sveltekit/README.mdx index 3dbe09dc707..97b8ddb26d6 100644 --- a/packages/console/src/assets/docs/guides/web-sveltekit/README.mdx +++ b/packages/console/src/assets/docs/guides/web-sveltekit/README.mdx @@ -46,8 +46,7 @@ Create a `hooks.server.ts` file in your project `src` root if you don't have one In your `hooks.server.ts` file, add the following code to inject the Logto hook into your server: -
-  
+
     {`import { handleLogto } from '@logto/sveltekit';
 
 export const handle = handleLogto(
@@ -60,13 +59,11 @@ export const handle = handleLogto(
     encryptionKey: '${cookieEncryptionKey}', // Random-generated
   }
 );`}
-  
-
+ Since these information are sensitive, it's recommended to use environment variables: -
-  
+
     {`import { handleLogto } from '@logto/sveltekit';
 import { env } from '$env/dynamic/private';
 
@@ -80,8 +77,7 @@ export const handle = handleLogto(
     encryptionKey: env.LOGTO_COOKIE_ENCRYPTION_KEY,
   }
 );`}
-  
-
+ If you have multiple hooks, you can use [the sequence() helper function](https://kit.svelte.dev/docs/modules#sveltejs-kit-hooks) to chain them: @@ -126,8 +122,7 @@ After signing out, it'll be great to redirect user back to your website. For exa In the page where you want to implement sign-in and sign-out, define the following actions: -
-  
+
     {`// +page.server.ts
 import type { Actions } from './$types';
 
@@ -142,8 +137,7 @@ export const actions: Actions = {
   },
 };
 `}
-  
-
+ Then use these actions in your Svelte component: diff --git a/packages/console/src/components/Guide/index.tsx b/packages/console/src/components/Guide/index.tsx index cebd7d168d8..9eee3125654 100644 --- a/packages/console/src/components/Guide/index.tsx +++ b/packages/console/src/components/Guide/index.tsx @@ -1,15 +1,12 @@ import { type ApplicationResponse } from '@logto/schemas'; -import { MDXProvider } from '@mdx-js/react'; import classNames from 'classnames'; import { type LazyExoticComponent, Suspense, createContext, useContext } from 'react'; import { guides } from '@/assets/docs/guides'; import { type GuideMetadata } from '@/assets/docs/guides/types'; import Button from '@/ds-components/Button'; -import CodeEditor from '@/ds-components/CodeEditor'; import OverlayScrollbar from '@/ds-components/OverlayScrollbar'; -import TextLink from '@/ds-components/TextLink'; -import DetailsSummary from '@/mdx-components/DetailsSummary'; +import MdxProvider from '@/mdx-components/MdxProvider'; import NotFound from '@/pages/NotFound'; import StepsSkeleton from './StepsSkeleton'; @@ -66,36 +63,11 @@ function Guide({ className, guideId, isEmpty, isLoading, onClose }: Props) { {isLoading && } {isEmpty && !guide && } - { - const [, language] = /language-(\w+)/.exec(String(className ?? '')) ?? []; - - return language ? ( - - ) : ( - {String(children).trimEnd()} - ); - }, - a: ({ children, ...props }) => ( - - {children} - - ), - details: DetailsSummary, - }} - > + }> {GuideComponent && } - + {!isApiResourceGuide && (