Compare commits

..

1 Commits

Author SHA1 Message Date
Tom Moor 2228df4054 fix: notifications.pixel requests hang
tests
2025-03-23 20:47:18 -04:00
52 changed files with 564 additions and 1737 deletions
+5 -1
View File
@@ -205,10 +205,14 @@ SENTRY_TUNNEL=
# To support sending outgoing transactional emails such as "document updated" or
# "you've been invited" you'll need to provide authentication for an SMTP server
SMTP_SERVICE=
SMTP_HOST=
SMTP_PORT=
SMTP_USERNAME=
SMTP_PASSWORD=
SMTP_FROM_EMAIL=
SMTP_REPLY_EMAIL=
SMTP_TLS_CIPHERS=
SMTP_SECURE=true
# The default interface language. See translate.getoutline.com for a list of
# available language codes and their rough percentage translated.
-2
View File
@@ -15,8 +15,6 @@ requestInfoDefaultTitles:
requestInfoLabelToAdd: more information needed
requestInfoUserstoExclude:
- tommoor
# Configuration for new-pr-welcome - https://github.com/behaviorbot/new-pr-welcome
-30
View File
@@ -1,30 +0,0 @@
name: Lint
on:
pull_request:
branches: [ main ]
jobs:
run-linters:
if: startsWith(github.actor, 'codegen-sh')
name: Run linters
runs-on: ubuntu-latest
permissions:
# Give the default GITHUB_TOKEN write permission to commit and push the
# added or changed files to the repository.
contents: write
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: 20.x
cache: 'yarn'
- run: yarn install --frozen-lockfile
- run: yarn lint --fix
- name: Commit changes
uses: stefanzweifel/git-auto-commit-action@v5
with:
commit_message: 'Applied automatic fixes'
-4
View File
@@ -171,10 +171,6 @@
"description": "smtp.example.com (optional)",
"required": false
},
"SMTP_SERVICE": {
"description": "Well-known SMTP service name for nodemailer (optional, e.g. 'gmail', 'SES')",
"required": false
},
"SMTP_PORT": {
"description": "1234 (optional)",
"required": false
@@ -7,43 +7,17 @@ import User from "~/models/User";
import Tooltip from "~/components/Tooltip";
import Avatar, { AvatarSize } from "./Avatar";
/**
* Props for the AvatarWithPresence component
*/
type Props = {
/** The user to display the avatar for */
user: User;
/** Whether the user is currently present in the document */
isPresent: boolean;
/** Whether the user is currently editing the document */
isEditing: boolean;
/** Whether the user is currently observing the document */
isObserving: boolean;
/** Whether this avatar represents the current user */
isCurrentUser: boolean;
/** Optional click handler for the avatar */
onClick?: React.MouseEventHandler<HTMLImageElement>;
/** Size of the avatar, defaults to AvatarSize.Large */
size?: AvatarSize;
/** Optional inline styles to apply to the avatar wrapper */
style?: React.CSSProperties;
};
/**
* AvatarWithPresence component displays a user's avatar with visual indicators
* for their current status (present, editing, observing).
*
* The component shows different visual states:
* - Present users have full opacity
* - Non-present users have reduced opacity
* - Observing users have a colored border matching their user color
* - Hovering shows a colored border
*
* A tooltip displays the user's name and current status.
*
* @param props - Component properties
* @returns React component
*/
function AvatarWithPresence({
onClick,
user,
@@ -90,33 +64,16 @@ function AvatarWithPresence({
);
}
/**
* Centered container for tooltip content
*/
const Centered = styled.div`
text-align: center;
`;
/**
* Props for the AvatarPresence styled component
*/
type AvatarWrapperProps = {
/** Whether the user is currently present */
$isPresent: boolean;
/** Whether the user is currently observing */
$isObserving: boolean;
/** The user's color for border highlighting */
$color: string;
};
/**
* Styled component that wraps the Avatar and provides visual indicators
* for the user's presence status.
*
* - Adjusts opacity based on presence
* - Adds colored borders for observing users
* - Handles hover effects
*/
const AvatarPresence = styled.div<AvatarWrapperProps>`
opacity: ${(props) => (props.$isPresent ? 1 : 0.5)};
transition: opacity 250ms ease-in-out;
+2 -2
View File
@@ -10,8 +10,8 @@ import {
import { Decoration, DecorationSet } from "prosemirror-view";
import * as React from "react";
import { v4 } from "uuid";
import { LANGUAGES } from "@shared/editor/extensions/Prism";
import Extension, { WidgetProps } from "@shared/editor/lib/Extension";
import { codeLanguages } from "@shared/editor/lib/code";
import isMarkdown from "@shared/editor/lib/isMarkdown";
import normalizePastedMarkdown from "@shared/editor/lib/markdown/normalize";
import { isRemoteTransaction } from "@shared/editor/lib/multiplayer";
@@ -228,7 +228,7 @@ export default class PasteHandler extends Extension {
state.tr
.replaceSelectionWith(
state.schema.nodes.code_block.create({
language: Object.keys(codeLanguages).includes(
language: Object.keys(LANGUAGES).includes(
vscodeMeta.mode
)
? vscodeMeta.mode
+12 -13
View File
@@ -2,11 +2,8 @@ import { CopyIcon, ExpandedIcon } from "outline-icons";
import { Node as ProseMirrorNode } from "prosemirror-model";
import { EditorState } from "prosemirror-state";
import * as React from "react";
import {
getFrequentCodeLanguages,
codeLanguages,
getLabelForLanguage,
} from "@shared/editor/lib/code";
import { LANGUAGES } from "@shared/editor/extensions/Prism";
import { getFrequentCodeLanguages } from "@shared/editor/lib/code";
import { MenuItem } from "@shared/editor/types";
import { Dictionary } from "~/hooks/useDictionary";
@@ -17,19 +14,20 @@ export default function codeMenuItems(
): MenuItem[] {
const node = state.selection.$from.node();
const allLanguages = Object.entries(LANGUAGES) as [
keyof typeof LANGUAGES,
string
][];
const frequentLanguages = getFrequentCodeLanguages();
const frequentLangMenuItems = frequentLanguages.map((value) => {
const label = codeLanguages[value]?.label;
const label = LANGUAGES[value];
return langToMenuItem({ node, value, label });
});
const remainingLangMenuItems = Object.entries(codeLanguages)
.filter(
([value]) =>
!frequentLanguages.includes(value as keyof typeof codeLanguages)
)
.map(([value, item]) => langToMenuItem({ node, value, label: item.label }));
const remainingLangMenuItems = allLanguages
.filter(([value]) => !frequentLanguages.includes(value))
.map(([value, label]) => langToMenuItem({ node, value, label }));
const languageMenuItems = frequentLangMenuItems.length
? [
@@ -54,7 +52,8 @@ export default function codeMenuItems(
visible: !readOnly,
name: "code_block",
icon: <ExpandedIcon />,
label: getLabelForLanguage(node.attrs.language ?? "none"),
// @ts-expect-error We have a fallback for incorrect mapping
label: LANGUAGES[node.attrs.language ?? "none"],
children: languageMenuItems,
},
];
-5
View File
@@ -1,11 +1,6 @@
import * as React from "react";
import { useTranslation } from "react-i18next";
/**
* Hook that provides a dictionary of translated UI strings.
*
* @returns An object containing all translated UI strings used throughout the application
*/
export default function useDictionary() {
const { t } = useTranslation();
-9
View File
@@ -1,15 +1,6 @@
import * as React from "react";
import useWindowSize from "./useWindowSize";
/**
* Hook to calculate the maximum height for an element based on its position and viewport size.
*
* @param options Configuration options
* @param options.elementRef A ref pointing to the element to calculate max height for
* @param options.maxViewportPercentage The maximum height of the element as a percentage of the viewport
* @param options.margin The margin to apply to the positioning
* @returns Object containing the calculated maxHeight and a function to recalculate it
*/
const useMaxHeight = ({
elementRef,
maxViewportPercentage = 90,
-6
View File
@@ -1,11 +1,5 @@
import { useState, useEffect } from "react";
/**
* Hook to check if a media query matches the current viewport.
*
* @param query The CSS media query to check against
* @returns boolean indicating whether the media query matches
*/
export default function useMediaQuery(query: string): boolean {
const [matches, setMatches] = useState<boolean>(false);
-5
View File
@@ -1,11 +1,6 @@
import { breakpoints } from "@shared/styles";
import useMediaQuery from "~/hooks/useMediaQuery";
/**
* Hook to detect if the current viewport is mobile-sized.
*
* @returns boolean indicating whether the current viewport is mobile-sized
*/
export default function useMobile(): boolean {
return useMediaQuery(`(max-width: ${breakpoints.tablet - 1}px)`);
}
-5
View File
@@ -1,11 +1,6 @@
import React from "react";
import { useLocation } from "react-router-dom";
/**
* Hook to access URL query parameters from the current location.
*
* @returns URLSearchParams object containing the current URL query parameters
*/
export default function useQuery() {
const location = useLocation();
-5
View File
@@ -2,11 +2,6 @@ import { MobXProviderContext } from "mobx-react";
import * as React from "react";
import RootStore from "~/stores";
/**
* Hook to access the MobX stores from the React context.
*
* @returns The root store containing all application stores
*/
export default function useStores() {
return React.useContext(MobXProviderContext) as typeof RootStore;
}
-5
View File
@@ -1,10 +1,5 @@
import * as React from "react";
/**
* Hook that executes a callback when the component unmounts.
*
* @param callback Function to be called on component unmount
*/
const useUnmount = (callback: (...args: Array<any>) => any) => {
const ref = React.useRef(callback);
ref.current = callback;
-6
View File
@@ -1,11 +1,5 @@
import { useLayoutEffect, useState } from "react";
/**
* Hook to get the current viewport height, accounting for mobile virtual keyboards.
* Uses the VisualViewport API when available, falling back to window.innerHeight.
*
* @returns The current viewport height in pixels
*/
export default function useViewportHeight(): number | void {
// https://developer.mozilla.org/en-US/docs/Web/API/VisualViewport#browser_compatibility
// Note: No support in Firefox at time of writing, however this mainly exists
-7
View File
@@ -13,13 +13,6 @@ const defaultOptions = {
throttle: 100,
};
/**
* Hook to track the window's scroll position.
*
* @param options Configuration options
* @param options.throttle Time in milliseconds to throttle the scroll event
* @returns Object containing the current scroll position (x, y coordinates)
*/
export default function useWindowScrollPosition(options: {
throttle: number;
}): {
+18 -19
View File
@@ -48,16 +48,16 @@
"> 0.25%, not dead"
],
"dependencies": {
"@aws-sdk/client-s3": "3.774.0",
"@aws-sdk/lib-storage": "3.774.0",
"@aws-sdk/s3-presigned-post": "3.774.0",
"@aws-sdk/s3-request-presigner": "3.774.0",
"@aws-sdk/signature-v4-crt": "^3.774.0",
"@babel/core": "^7.26.10",
"@aws-sdk/client-s3": "3.758.0",
"@aws-sdk/lib-storage": "3.758.0",
"@aws-sdk/s3-presigned-post": "3.758.0",
"@aws-sdk/s3-request-presigner": "3.758.0",
"@aws-sdk/signature-v4-crt": "^3.758.0",
"@babel/core": "^7.26.9",
"@babel/plugin-proposal-decorators": "^7.25.9",
"@babel/plugin-transform-class-properties": "^7.25.9",
"@babel/plugin-transform-destructuring": "^7.25.9",
"@babel/plugin-transform-regenerator": "^7.27.0",
"@babel/plugin-transform-regenerator": "^7.25.9",
"@babel/preset-env": "^7.26.9",
"@babel/preset-react": "^7.26.3",
"@benrbray/prosemirror-math": "^0.2.2",
@@ -110,7 +110,7 @@
"copy-to-clipboard": "^3.3.3",
"core-js": "^3.37.0",
"crypto-js": "^4.2.0",
"datadog-metrics": "^0.12.1",
"datadog-metrics": "^0.11.2",
"date-fns": "^3.6.0",
"dd-trace": "^5.40.0",
"diff": "^5.2.0",
@@ -129,12 +129,11 @@
"fuzzy-search": "^3.2.1",
"glob": "^8.1.0",
"http-errors": "2.0.0",
"https-proxy-agent": "^7.0.6",
"i18next": "^22.5.1",
"i18next-fs-backend": "^2.6.0",
"i18next-http-backend": "^2.7.3",
"invariant": "^2.2.4",
"ioredis": "^5.6.0",
"ioredis": "^5.4.1",
"is-printable-key-event": "^1.0.0",
"jsdom": "^22.1.0",
"jsonwebtoken": "^9.0.0",
@@ -173,13 +172,13 @@
"passport-oauth2": "^1.8.0",
"passport-slack-oauth2": "^1.2.0",
"patch-package": "^7.0.2",
"pg": "^8.14.1",
"pg": "^8.12.0",
"pg-tsquery": "^8.4.2",
"pluralize": "^8.0.0",
"png-chunks-extract": "^1.0.0",
"polished": "^4.3.1",
"prosemirror-codemark": "^0.4.2",
"prosemirror-commands": "^1.7.0",
"prosemirror-commands": "^1.6.2",
"prosemirror-dropcursor": "^1.8.1",
"prosemirror-gapcursor": "^1.3.2",
"prosemirror-history": "^1.4.1",
@@ -248,7 +247,7 @@
"uuid": "^8.3.2",
"validator": "13.12.0",
"vaul": "^1.1.2",
"vite": "^5.4.15",
"vite": "^5.4.14",
"vite-plugin-pwa": "^0.20.3",
"winston": "^3.17.0",
"ws": "^7.5.10",
@@ -257,11 +256,11 @@
"y-protocols": "^1.0.6",
"yauzl": "^2.10.0",
"yjs": "^13.6.1",
"zod": "^3.24.2"
"zod": "^3.23.8"
},
"devDependencies": {
"@babel/cli": "^7.27.0",
"@babel/preset-typescript": "^7.27.0",
"@babel/cli": "^7.26.4",
"@babel/preset-typescript": "^7.26.0",
"@faker-js/faker": "^8.4.1",
"@relative-ci/agent": "^4.2.14",
"@testing-library/react": "^12.0.0",
@@ -296,7 +295,7 @@
"@types/markdown-it-emoji": "^2.0.4",
"@types/mime-types": "^2.1.4",
"@types/natural-sort": "^0.0.24",
"@types/node": "20.17.27",
"@types/node": "20.17.16",
"@types/node-fetch": "^2.6.9",
"@types/nodemailer": "^6.4.17",
"@types/passport-oauth2": "^1.4.17",
@@ -360,7 +359,7 @@
"prettier": "^2.8.8",
"react-refresh": "^0.14.2",
"rimraf": "^2.5.4",
"rollup-plugin-webpack-stats": "^2.0.3",
"rollup-plugin-webpack-stats": "^2.0.1",
"terser": "^5.39.0",
"typescript": "^5.7.3",
"vite-plugin-static-copy": "^0.17.0",
@@ -378,4 +377,4 @@
"prismjs": "1.30.0"
},
"version": "0.82.0"
}
}
+1 -1
View File
@@ -3,7 +3,7 @@ import { Hook, PluginManager } from "@server/utils/PluginManager";
import config from "../plugin.json";
import router from "./auth/email";
const enabled = !!(env.SMTP_HOST || env.SMTP_SERVICE) || env.isDevelopment;
const enabled = !!env.SMTP_HOST || env.isDevelopment;
if (enabled) {
PluginManager.add({
+1 -6
View File
@@ -81,12 +81,7 @@ export const Notion = observer(() => {
}, [t, appName, oauthError]);
return (
<Button
type="submit"
onClick={() => redirectTo(authUrl)}
disabled={!env.NOTION_CLIENT_ID}
neutral
>
<Button type="submit" onClick={() => redirectTo(authUrl)} neutral>
{t("Import")}
</Button>
);
+1 -1
View File
@@ -5,8 +5,8 @@ import environment from "@server/utils/environment";
import { CannotUseWithout } from "@server/utils/validators";
class NotionPluginEnvironment extends Environment {
@Public
@IsOptional()
@Public
public NOTION_CLIENT_ID = this.toOptionalString(environment.NOTION_CLIENT_ID);
@IsOptional()
+10 -23
View File
@@ -1,6 +1,4 @@
import {
APIErrorCode,
APIResponseError,
Client,
isFullPage,
isFullPageOrDatabase,
@@ -249,30 +247,19 @@ export class NotionClient {
private async fetchUsername(userId: string) {
await this.limiter();
try {
const user = await this.client.users.retrieve({ user_id: userId });
const user = await this.client.users.retrieve({ user_id: userId });
if (user.type === "person" || !user.bot.owner) {
return user.name;
}
// bot belongs to a user, get the user's name.
if (user.bot.owner.type === "user" && isFullUser(user.bot.owner.user)) {
return user.bot.owner.user.name;
}
// bot belongs to a workspace, fallback to bot's name.
if (user.type === "person" || !user.bot.owner) {
return user.name;
} catch (error) {
// Handle the case where a user can't be found
if (
error instanceof APIResponseError &&
error.code === APIErrorCode.ObjectNotFound
) {
return "Unknown";
}
throw error;
}
// bot belongs to a user, get the user's name.
if (user.bot.owner.type === "user" && isFullUser(user.bot.owner.user)) {
return user.bot.owner.user.name;
}
// bot belongs to a workspace, fallback to bot's name.
return user.name;
}
private parseTitle(item: PageObjectResponse | DatabaseObjectResponse) {
@@ -1,22 +1,12 @@
import { Node } from "prosemirror-model";
import { ProsemirrorHelper } from "@server/models/helpers/ProsemirrorHelper";
import nodesWithEmptyTextNode from "@server/test/fixtures/notion-page-with-empty-text-nodes.json";
import allNodes from "@server/test/fixtures/notion-page.json";
import data from "@server/test/fixtures/notion-page.json";
import { NotionConverter, NotionPage } from "./NotionConverter";
describe("NotionConverter", () => {
it("converts a page", () => {
const response = NotionConverter.page({
children: allNodes,
} as NotionPage);
expect(response).toMatchSnapshot();
expect(ProsemirrorHelper.toProsemirror(response)).toBeInstanceOf(Node);
});
it("converts a page with empty text nodes", () => {
const response = NotionConverter.page({
children: nodesWithEmptyTextNode,
children: data,
} as NotionPage);
expect(response).toMatchSnapshot();
+13 -16
View File
@@ -179,15 +179,11 @@ export class NotionConverter {
}
private static bookmark(item: BookmarkBlockObjectResponse) {
const caption = item.bookmark.caption
.map(this.rich_text_to_plaintext)
.join("");
return {
type: "paragraph",
content: [
{
text: caption || item.bookmark.url,
text: item.bookmark.caption.map(this.rich_text_to_plaintext).join(""),
type: "text",
marks: [
{
@@ -225,14 +221,17 @@ export class NotionConverter {
}
private static code(item: CodeBlockObjectResponse) {
const text = item.code.rich_text.map(this.rich_text_to_plaintext).join("");
return {
type: "code_fence",
attrs: {
language: item.code.language,
},
content: text ? [{ type: "text", text }] : undefined,
content: [
{
type: "text",
text: item.code.rich_text.map(this.rich_text_to_plaintext).join(""),
},
],
};
}
@@ -365,14 +364,12 @@ export class NotionConverter {
private static equation(item: EquationBlockObjectResponse) {
return {
type: "math_block",
content: item.equation.expression
? [
{
type: "text",
text: item.equation.expression,
},
]
: undefined,
content: [
{
type: "text",
text: item.equation.expression,
},
],
};
}
@@ -1983,148 +1983,3 @@ exports[`NotionConverter converts a page 1`] = `
"type": "doc",
}
`;
exports[`NotionConverter converts a page with empty text nodes 1`] = `
{
"content": [
{
"content": [],
"type": "paragraph",
},
{
"attrs": {
"language": "javascript",
},
"content": undefined,
"type": "code_fence",
},
{
"content": [],
"type": "paragraph",
},
{
"content": [
{
"content": [
{
"text": "E",
"type": "text",
},
],
"type": "math_inline",
},
],
"type": "paragraph",
},
{
"content": [],
"type": "paragraph",
},
{
"content": [
{
"marks": [
{
"attrs": {
"href": "http://github.com/outline/",
},
"type": "link",
},
],
"text": "http://github.com/outline/",
"type": "text",
},
],
"type": "paragraph",
},
{
"content": [],
"type": "paragraph",
},
{
"content": [
{
"marks": [
{
"attrs": {
"href": "https://github.com/outline/outline",
},
"type": "link",
},
],
"text": "https://github.com/outline/outline",
"type": "text",
},
],
"type": "paragraph",
},
{
"content": [],
"type": "paragraph",
},
{
"content": undefined,
"type": "math_block",
},
{
"content": [],
"type": "paragraph",
},
{
"content": [
{
"marks": [
{
"attrs": {
"href": "https://google.com",
"title": null,
},
"type": "link",
},
],
"text": "https://google.com",
"type": "text",
},
],
"type": "paragraph",
},
{
"content": [],
"type": "paragraph",
},
{
"content": [
{
"marks": [
{
"attrs": {
"href": "https://github.com/outline/outline",
},
"type": "link",
},
],
"text": "https://github.com/outline/outline",
"type": "text",
},
],
"type": "paragraph",
},
{
"content": [],
"type": "paragraph",
},
{
"attrs": {
"href": "https://prod-files-secure.s3.us-west-2.amazonaws.com/2f3fcad6-fc32-434b-b6b2-a03ca7893c4d/49bfa851-95c1-458b-abb0-88ed591f7712/Empty_pdf.pdf",
"title": "",
},
"type": "attachment",
},
{
"content": [],
"type": "paragraph",
},
],
"type": "doc",
}
`;
-28
View File
@@ -1,28 +0,0 @@
import { HttpsProxyAgent } from "https-proxy-agent";
import OAuth2Strategy, { Strategy } from "passport-oauth2";
export class OIDCStrategy extends Strategy {
constructor(
options: OAuth2Strategy.StrategyOptionsWithRequest,
verify: OAuth2Strategy.VerifyFunctionWithRequest
) {
super(options, verify);
if (process.env.https_proxy) {
const httpsProxyAgent = new HttpsProxyAgent(process.env.https_proxy);
this._oauth2.setAgent(httpsProxyAgent);
}
}
authenticate(req: any, options: any) {
options.originalQuery = req.query;
super.authenticate(req, options);
}
authorizationParams(options: any) {
return {
...(options.originalQuery || {}),
...(super.authorizationParams?.(options) || {}),
};
}
}
+16 -2
View File
@@ -2,6 +2,7 @@ import passport from "@outlinewiki/koa-passport";
import type { Context } from "koa";
import Router from "koa-router";
import get from "lodash/get";
import { Strategy } from "passport-oauth2";
import { slugifyDomain } from "@shared/utils/domains";
import { parseEmail } from "@shared/utils/email";
import accountProvisioner from "@server/commands/accountProvisioner";
@@ -20,11 +21,24 @@ import {
} from "@server/utils/passport";
import config from "../../plugin.json";
import env from "../env";
import { OIDCStrategy } from "./OIDCStrategy";
const router = new Router();
const scopes = env.OIDC_SCOPES.split(" ");
const authorizationParams = Strategy.prototype.authorizationParams;
Strategy.prototype.authorizationParams = function (options) {
return {
...(options.originalQuery || {}),
...(authorizationParams.bind(this)(options) || {}),
};
};
const authenticate = Strategy.prototype.authenticate;
Strategy.prototype.authenticate = function (req, options) {
options.originalQuery = req.query;
authenticate.bind(this)(req, options);
};
if (
env.OIDC_CLIENT_ID &&
env.OIDC_CLIENT_SECRET &&
@@ -34,7 +48,7 @@ if (
) {
passport.use(
config.id,
new OIDCStrategy(
new Strategy(
{
authorizationURL: env.OIDC_AUTH_URI,
tokenURL: env.OIDC_TOKEN_URI,
+1 -12
View File
@@ -33,7 +33,7 @@ export class Mailer {
transporter: Transporter | undefined;
constructor() {
if (env.SMTP_HOST || env.SMTP_SERVICE) {
if (env.SMTP_HOST) {
this.transporter = nodemailer.createTransport(this.getOptions());
}
if (useTestEmailService) {
@@ -198,17 +198,6 @@ export class Mailer {
};
private getOptions(): SMTPTransport.Options {
// nodemailer will use the service config to determine host/port
if (env.SMTP_SERVICE) {
return {
service: env.SMTP_SERVICE,
auth: {
user: env.SMTP_USERNAME,
pass: env.SMTP_PASSWORD,
},
};
}
return {
name: env.SMTP_NAME,
host: env.SMTP_HOST,
+3 -13
View File
@@ -15,7 +15,7 @@ import {
} from "class-validator";
import uniq from "lodash/uniq";
import { languages } from "@shared/i18n";
import { CannotUseWith, CannotUseWithout } from "@server/utils/validators";
import { CannotUseWithout } from "@server/utils/validators";
import Deprecated from "./models/decorators/Deprecated";
import { getArg } from "./utils/args";
import { Public, PublicEnvironmentRegister } from "./utils/decorators/Public";
@@ -291,19 +291,10 @@ export class Environment {
/**
* The host of your SMTP server for enabling emails.
*/
@CannotUseWith("SMTP_SERVICE")
public SMTP_HOST = this.toOptionalString(environment.SMTP_HOST);
/**
* The service name of a well-known SMTP service for nodemailer.
* See https://community.nodemailer.com/2-0-0-beta/setup-smtp/well-known-services/
*/
@CannotUseWith("SMTP_HOST")
public SMTP_SERVICE = this.toOptionalString(environment.SMTP_SERVICE);
public SMTP_HOST = environment.SMTP_HOST;
@Public
public EMAIL_ENABLED =
!!(this.SMTP_HOST || this.SMTP_SERVICE) || this.isDevelopment;
public EMAIL_ENABLED = !!this.SMTP_HOST || this.isDevelopment;
/**
* Optional hostname of the client, used for identifying to the server
@@ -316,7 +307,6 @@ export class Environment {
*/
@IsNumber()
@IsOptional()
@CannotUseWith("SMTP_SERVICE")
public SMTP_PORT = this.toOptionalNumber(environment.SMTP_PORT);
/**
+3 -1
View File
@@ -48,7 +48,9 @@ class Metrics {
return Promise.resolve();
}
return ddMetrics.flush();
return new Promise((resolve, reject) => {
ddMetrics.flush(resolve, reject);
});
}
}
+2 -45
View File
@@ -1,5 +1,4 @@
/* eslint-disable lines-between-class-members */
import fractionalIndex from "fractional-index";
import find from "lodash/find";
import findIndex from "lodash/findIndex";
import remove from "lodash/remove";
@@ -12,8 +11,6 @@ import {
InferAttributes,
InferCreationAttributes,
EmptyResultError,
type CreateOptions,
type UpdateOptions,
} from "sequelize";
import {
Sequelize,
@@ -35,8 +32,6 @@ import {
BeforeDestroy,
IsDate,
AllowNull,
BeforeCreate,
BeforeUpdate,
} from "sequelize-typescript";
import isUUID from "validator/lib/isUUID";
import type { CollectionSort, ProsemirrorData } from "@shared/types";
@@ -46,9 +41,7 @@ import { sortNavigationNodes } from "@shared/utils/collections";
import slugify from "@shared/utils/slugify";
import { CollectionValidation } from "@shared/validations";
import { ValidationError } from "@server/errors";
import removeIndexCollision from "@server/utils/removeIndexCollision";
import { generateUrlId } from "@server/utils/url";
import { ValidateIndex } from "@server/validation";
import Document from "./Document";
import FileOperation from "./FileOperation";
import Group from "./Group";
@@ -224,8 +217,8 @@ class Collection extends ParanoidModel<
color: string | null;
@Length({
max: ValidateIndex.maxLength,
msg: `index must be ${ValidateIndex.maxLength} characters or less`,
max: 256,
msg: `index must be 256 characters or less`,
})
@Column
index: string | null;
@@ -331,30 +324,6 @@ class Collection extends ParanoidModel<
}
}
@BeforeCreate
static async setIndex(model: Collection, options: CreateOptions<Collection>) {
if (model.index) {
model.index = await removeIndexCollision(model.teamId, model.index, {
transaction: options.transaction,
});
return;
}
const firstCollectionForTeam = await this.findOne({
where: {
teamId: model.teamId,
},
order: [
// using LC_COLLATE:"C" because we need byte order to drive the sorting
Sequelize.literal('"collection"."index" collate "C"'),
["updatedAt", "DESC"],
],
...options,
});
model.index = fractionalIndex(null, firstCollectionForTeam?.index ?? null);
}
@AfterCreate
static async onAfterCreate(
model: Collection,
@@ -374,18 +343,6 @@ class Collection extends ParanoidModel<
});
}
@BeforeUpdate
static async checkIndex(
model: Collection,
options: UpdateOptions<Collection>
) {
if (model.index && model.changed("index")) {
model.index = await removeIndexCollision(model.teamId, model.index, {
transaction: options.transaction,
});
}
}
// associations
@BelongsTo(() => FileOperation, "importId")
+1 -1
View File
@@ -190,7 +190,7 @@ class Team extends ParanoidModel<
* @return {boolean} Whether to show email login options
*/
get emailSigninEnabled(): boolean {
return this.guestSignin && env.EMAIL_ENABLED;
return this.guestSignin && (!!env.SMTP_HOST || env.isDevelopment);
}
get url() {
+32 -100
View File
@@ -9,7 +9,7 @@ import NotificationHelper from "./NotificationHelper";
describe("NotificationHelper", () => {
describe("getCommentNotificationRecipients", () => {
it("should only return users who have notification enabled for comment creation and are subscribed to the document in case of new thread", async () => {
it("should return users who have notification enabled for comment creation and are subscribed to the document in case of parent comment", async () => {
const documentAuthor = await buildUser();
const document = await buildDocument({
userId: documentAuthor.id,
@@ -54,7 +54,7 @@ describe("NotificationHelper", () => {
expect(recipients[0].id).toEqual(notificationEnabledUser.id);
});
it("should only return users who have notification enabled for comment creation and are in the thread in case of child comment", async () => {
it("should return users who have notification enabled for comment creation and are in the thread in case of child comment", async () => {
const documentAuthor = await buildUser();
const document = await buildDocument({
userId: documentAuthor.id,
@@ -112,104 +112,32 @@ describe("NotificationHelper", () => {
expect(recipients.length).toEqual(1);
expect(recipients[0].id).toEqual(notificationEnabledUserInThread.id);
});
it("should not return users who have notification disabled for comment creation and are in the thread in case of child comment", async () => {
const documentAuthor = await buildUser();
const document = await buildDocument({
userId: documentAuthor.id,
teamId: documentAuthor.teamId,
});
const notificationEnabledUserInThread = await buildUser({
teamId: document.teamId,
notificationSettings: { [NotificationEventType.CreateComment]: false },
});
const notificationEnabledUserNotInThread = await buildUser({
teamId: document.teamId,
notificationSettings: { [NotificationEventType.CreateComment]: true },
});
const notificationDisabledUser = await buildUser({
teamId: document.teamId,
notificationSettings: {
[NotificationEventType.CreateComment]: false,
},
});
await Promise.all([
buildSubscription({
userId: documentAuthor.id,
documentId: document.id,
}),
buildSubscription({
userId: notificationEnabledUserInThread.id,
documentId: document.id,
}),
buildSubscription({
userId: notificationEnabledUserNotInThread.id,
documentId: document.id,
}),
buildSubscription({
userId: notificationDisabledUser.id,
documentId: document.id,
}),
]);
const parentComment = await buildComment({
documentId: document.id,
userId: notificationEnabledUserInThread.id,
});
const childComment = await buildComment({
documentId: document.id,
userId: documentAuthor.id,
parentCommentId: parentComment.id,
});
const recipients =
await NotificationHelper.getCommentNotificationRecipients(
document,
childComment,
childComment.createdById
);
expect(recipients.length).toEqual(0);
});
it("should return users who have notification enabled and are in the thread but not explicitly subscribed to document", async () => {
const documentAuthor = await buildUser();
const document = await buildDocument({
userId: documentAuthor.id,
teamId: documentAuthor.teamId,
});
const notificationEnabledUserInThread = await buildUser({
teamId: document.teamId,
notificationSettings: { [NotificationEventType.CreateComment]: true },
});
await buildUser({
teamId: document.teamId,
notificationSettings: {
[NotificationEventType.CreateComment]: false,
},
});
const parentComment = await buildComment({
documentId: document.id,
userId: notificationEnabledUserInThread.id,
});
const childComment = await buildComment({
documentId: document.id,
userId: documentAuthor.id,
parentCommentId: parentComment.id,
});
const recipients =
await NotificationHelper.getCommentNotificationRecipients(
document,
childComment,
childComment.createdById
);
expect(recipients.length).toEqual(1);
expect(recipients[0].id).toEqual(notificationEnabledUserInThread.id);
});
});
describe("getDocumentNotificationRecipients", () => {
it("should return all users who have notification enabled for the event", async () => {
const documentAuthor = await buildUser();
const document = await buildDocument({
userId: documentAuthor.id,
teamId: documentAuthor.teamId,
});
const notificationEnabledUser = await buildUser({
teamId: document.teamId,
notificationSettings: { [NotificationEventType.UpdateDocument]: true },
});
const recipients =
await NotificationHelper.getDocumentNotificationRecipients({
document,
notificationType: NotificationEventType.UpdateDocument,
onlySubscribers: false,
actorId: documentAuthor.id,
});
expect(recipients.length).toEqual(1);
expect(recipients[0].id).toEqual(notificationEnabledUser.id);
});
it("should return users who have subscribed to the document", async () => {
const documentAuthor = await buildUser();
const document = await buildDocument({
@@ -226,6 +154,7 @@ describe("NotificationHelper", () => {
await NotificationHelper.getDocumentNotificationRecipients({
document,
notificationType: NotificationEventType.UpdateDocument,
onlySubscribers: true,
actorId: documentAuthor.id,
});
@@ -249,6 +178,7 @@ describe("NotificationHelper", () => {
await NotificationHelper.getDocumentNotificationRecipients({
document,
notificationType: NotificationEventType.UpdateDocument,
onlySubscribers: true,
actorId: documentAuthor.id,
});
@@ -286,6 +216,7 @@ describe("NotificationHelper", () => {
await NotificationHelper.getDocumentNotificationRecipients({
document,
notificationType: NotificationEventType.UpdateDocument,
onlySubscribers: true,
actorId: documentAuthor.id,
});
@@ -304,19 +235,20 @@ describe("NotificationHelper", () => {
});
const notificationEnabledUser = await buildUser({
teamId: document.teamId,
notificationSettings: { [NotificationEventType.PublishDocument]: true },
notificationSettings: { [NotificationEventType.UpdateDocument]: true },
});
// suspended user
await buildUser({
suspendedAt: new Date(),
teamId: document.teamId,
notificationSettings: { [NotificationEventType.PublishDocument]: true },
notificationSettings: { [NotificationEventType.UpdateDocument]: true },
});
const recipients =
await NotificationHelper.getDocumentNotificationRecipients({
document,
notificationType: NotificationEventType.PublishDocument,
notificationType: NotificationEventType.UpdateDocument,
onlySubscribers: false,
actorId: documentAuthor.id,
});
+48 -74
View File
@@ -14,7 +14,7 @@ import {
Comment,
View,
} from "@server/models";
import { canUserAccessDocument } from "@server/utils/permissions";
import { can } from "@server/policies";
import { ProsemirrorHelper } from "./ProsemirrorHelper";
export default class NotificationHelper {
@@ -60,12 +60,18 @@ export default class NotificationHelper {
comment: Comment,
actorId: string
): Promise<User[]> => {
let recipients: User[];
let recipients = await this.getDocumentNotificationRecipients({
document,
notificationType: NotificationEventType.CreateComment,
onlySubscribers: !comment.parentCommentId,
actorId,
});
// If this is a reply to another comment, we want to notify all users
// that are involved in the thread of this comment (i.e. the original
// comment and all replies to it).
if (comment.parentCommentId) {
recipients = recipients.filter((recipient) =>
recipient.subscribedToEventType(NotificationEventType.CreateComment)
);
if (recipients.length > 0 && comment.parentCommentId) {
const contextComments = await Comment.findAll({
attributes: ["createdById", "data"],
where: {
@@ -89,37 +95,13 @@ export default class NotificationHelper {
const userIdsInThread = uniq([
...createdUserIdsInThread,
...mentionedUserIdsInThread,
]).filter((userId) => userId !== actorId);
recipients = await User.findAll({
where: {
id: {
[Op.in]: userIdsInThread,
},
teamId: document.teamId,
},
});
recipients = recipients.filter((recipient) =>
recipient.subscribedToEventType(NotificationEventType.CreateComment)
);
} else {
recipients = await this.getDocumentNotificationRecipients({
document,
notificationType: NotificationEventType.CreateComment,
actorId,
// We will check below, this just prevents duplicate queries
disableAccessCheck: true,
});
]);
recipients = recipients.filter((r) => userIdsInThread.includes(r.id));
}
const filtered: User[] = [];
for (const recipient of recipients) {
if (recipient.isSuspended) {
continue;
}
// If this recipient has viewed the document since the comment was made
// then we can avoid sending them a useless notification, yay.
const view = await View.findOne({
@@ -137,13 +119,7 @@ export default class NotificationHelper {
"processor",
`suppressing notification to ${recipient.id} because doc viewed`
);
continue;
}
// Check the recipient has access to the collection this document is in. Just
// because they are subscribed doesn't mean they still have access to read
// the document.
if (await canUserAccessDocument(recipient, document.id)) {
} else {
filtered.push(recipient);
}
}
@@ -156,76 +132,74 @@ export default class NotificationHelper {
*
* @param document The document to get recipients for.
* @param notificationType The notification type for which to find the recipients.
* @param onlySubscribers Whether to consider only the users who have active subscription to the document.
* @param actorId The id of the user that performed the action.
* @param disableAccessCheck Whether to disable the access check for the document.
* @returns A list of recipients
*/
public static getDocumentNotificationRecipients = async ({
document,
notificationType,
onlySubscribers,
actorId,
disableAccessCheck = false,
}: {
document: Document;
notificationType: NotificationEventType;
onlySubscribers: boolean;
actorId: string;
disableAccessCheck?: boolean;
}): Promise<User[]> => {
let recipients: User[];
if (notificationType === NotificationEventType.PublishDocument) {
recipients = await User.findAll({
where: {
id: {
[Op.ne]: actorId,
},
teamId: document.teamId,
notificationSettings: {
[notificationType]: true,
},
// First find all the users that have notifications enabled for this event
// type at all and aren't the one that performed the action.
let recipients = await User.findAll({
where: {
id: {
[Op.ne]: actorId,
},
});
} else {
teamId: document.teamId,
},
});
recipients = recipients.filter((recipient) =>
recipient.subscribedToEventType(notificationType)
);
// Filter further to only those that have a subscription to the document…
if (onlySubscribers) {
const subscriptions = await Subscription.findAll({
attributes: ["userId"],
where: {
userId: {
[Op.ne]: actorId,
},
userId: recipients.map((recipient) => recipient.id),
event: SubscriptionType.Document,
[Op.or]: [
{ collectionId: document.collectionId },
{ documentId: document.id },
],
},
include: [
{
association: "user",
},
],
});
recipients = subscriptions.map((s) => s.user);
}
const subscribedUserIds = subscriptions.map(
(subscription) => subscription.userId
);
recipients = recipients.filter((recipient) =>
recipient.subscribedToEventType(notificationType)
);
recipients = recipients.filter((recipient) =>
subscribedUserIds.includes(recipient.id)
);
}
const filtered = [];
for (const recipient of recipients) {
if (recipient.isSuspended) {
if (!recipient.email || recipient.isSuspended) {
continue;
}
// Check the recipient has access to the collection this document is in. Just
// because they are subscribed doesn't mean they still have access to read
// the document.
if (
disableAccessCheck ||
(await canUserAccessDocument(recipient, document.id))
) {
const doc = await Document.findByPk(document.id, {
userId: recipient.id,
});
if (can(recipient, "read", doc)) {
filtered.push(recipient);
}
}
@@ -41,7 +41,6 @@ export default class CleanupOldImportsTask extends BaseTask<Props> {
],
batchLimit: 50,
totalLimit: maxImportsPerTask,
paranoid: false,
},
async (imports) => {
// eslint-disable-next-line @typescript-eslint/no-explicit-any
@@ -54,6 +54,7 @@ export default class DocumentPublishedNotificationsTask extends BaseTask<Documen
await NotificationHelper.getDocumentNotificationRecipients({
document,
notificationType: NotificationEventType.PublishDocument,
onlySubscribers: false,
actorId: document.lastModifiedById,
})
).filter((recipient) => !userIdsMentioned.includes(recipient.id));
@@ -76,6 +76,7 @@ export default class RevisionCreatedNotificationsTask extends BaseTask<RevisionE
await NotificationHelper.getDocumentNotificationRecipients({
document,
notificationType: NotificationEventType.UpdateDocument,
onlySubscribers: true,
actorId: document.lastModifiedById,
})
).filter((recipient) => !userIdsMentioned.includes(recipient.id));
@@ -1327,32 +1327,6 @@ describe("#collections.create", () => {
expect(body.policies[0].abilities.read).toBeTruthy();
});
it("should ensure unique index across the team", async () => {
const team = await buildTeam();
const [adminA, adminB] = await Promise.all([
buildAdmin({ teamId: team.id }),
buildAdmin({ teamId: team.id }),
]);
const resA = await server.post("/api/collections.create", {
body: {
token: adminA.getJwtToken(),
name: "Test A",
},
});
const resB = await server.post("/api/collections.create", {
body: {
token: adminB.getJwtToken(),
name: "Test B",
},
});
const [bodyA, bodyB] = await Promise.all([resA.json(), resB.json()]);
expect(resA.status).toEqual(200);
expect(resB.status).toEqual(200);
expect(bodyA.data.index).not.toEqual(bodyB.data.index);
});
it("if index collision, should updated index of other collection", async () => {
const user = await buildUser();
const createdCollectionAResponse = await server.post(
+22 -16
View File
@@ -1,3 +1,4 @@
import fractionalIndex from "fractional-index";
import invariant from "invariant";
import Router from "koa-router";
import { Sequelize, Op, WhereOptions } from "sequelize";
@@ -41,6 +42,7 @@ import {
import { APIContext } from "@server/types";
import { RateLimiterStrategy } from "@server/utils/RateLimiter";
import { collectionIndexing } from "@server/utils/indexing";
import removeIndexCollision from "@server/utils/removeIndexCollision";
import pagination from "../middlewares/pagination";
import * as T from "./schema";
@@ -53,21 +55,23 @@ router.post(
transaction(),
async (ctx: APIContext<T.CollectionsCreateReq>) => {
const { transaction } = ctx.state;
const {
name,
color,
description,
data,
permission,
sharing,
icon,
sort,
index,
} = ctx.input.body;
const { name, color, description, data, permission, sharing, icon, sort } =
ctx.input.body;
let { index } = ctx.input.body;
const { user } = ctx.state.auth;
authorize(user, "createCollection", user.team);
if (index) {
index = await removeIndexCollision(user.teamId, index, { transaction });
} else {
const first = await Collection.findFirstCollectionForUser(user, {
attributes: ["id", "index"],
transaction,
});
index = fractionalIndex(null, first ? first.index : null);
}
const collection = Collection.build({
name,
content: data,
@@ -955,16 +959,18 @@ router.post(
transaction(),
async (ctx: APIContext<T.CollectionsMoveReq>) => {
const { transaction } = ctx.state;
const { id, index } = ctx.input.body;
const { id } = ctx.input.body;
let { index } = ctx.input.body;
const { user } = ctx.state.auth;
let collection = await Collection.findByPk(id, {
const collection = await Collection.findByPk(id, {
transaction,
lock: transaction.LOCK.UPDATE,
});
authorize(user, "move", collection);
collection = await collection.update(
index = await removeIndexCollision(user.teamId, index, { transaction });
await collection.update(
{
index,
},
@@ -976,14 +982,14 @@ router.post(
name: "collections.move",
collectionId: collection.id,
data: {
index: collection.index,
index,
},
});
ctx.body = {
success: true,
data: {
index: collection.index,
index,
},
};
}
+3 -2
View File
@@ -19,6 +19,7 @@ import { safeEqual } from "@server/utils/crypto";
import * as T from "./schema";
const router = new Router();
const emailEnabled = !!(env.SMTP_HOST || env.isDevelopment);
const handleTeamUpdate = async (ctx: APIContext<T.TeamsUpdateSchemaReq>) => {
const { transaction } = ctx.state;
@@ -67,7 +68,7 @@ router.post(
rateLimiter(RateLimiterStrategy.FivePerHour),
auth(),
async (ctx: APIContext) => {
if (!env.EMAIL_ENABLED) {
if (!emailEnabled) {
throw ValidationError("Email support is not setup for this instance");
}
@@ -100,7 +101,7 @@ router.post(
authorize(user, "delete", team);
if (env.EMAIL_ENABLED) {
if (emailEnabled) {
const deleteConfirmationCode = team.getDeleteConfirmationCode(user);
if (!safeEqual(code, deleteConfirmationCode)) {
+5 -4
View File
@@ -30,6 +30,7 @@ import pagination from "../middlewares/pagination";
import * as T from "./schema";
const router = new Router();
const emailEnabled = !!(env.SMTP_HOST || env.isDevelopment);
router.post(
"users.list",
@@ -209,7 +210,7 @@ router.post(
auth(),
validate(T.UsersUpdateEmailSchema),
async (ctx: APIContext<T.UsersUpdateEmailReq>) => {
if (!env.EMAIL_ENABLED) {
if (!emailEnabled) {
throw ValidationError("Email support is not setup for this instance");
}
@@ -251,7 +252,7 @@ router.get(
transaction(),
validate(T.UsersUpdateEmailConfirmSchema),
async (ctx: APIContext<T.UsersUpdateEmailConfirmReq>) => {
if (!env.EMAIL_ENABLED) {
if (!emailEnabled) {
throw ValidationError("Email support is not setup for this instance");
}
@@ -625,7 +626,7 @@ router.post(
rateLimiter(RateLimiterStrategy.FivePerHour),
auth(),
async (ctx: APIContext) => {
if (!env.EMAIL_ENABLED) {
if (!emailEnabled) {
throw ValidationError("Email support is not setup for this instance");
}
@@ -670,7 +671,7 @@ router.post(
// If we're attempting to delete our own account then a confirmation code
// is required. This acts as CSRF protection.
if ((!id || id === actor.id) && env.EMAIL_ENABLED) {
if ((!id || id === actor.id) && emailEnabled) {
const deleteConfirmationCode = user.deleteConfirmationCode;
if (!safeEqual(code, deleteConfirmationCode)) {
@@ -1,509 +0,0 @@
[
{
"object": "block",
"id": "1c12c2bb-bca8-803b-a8dc-d10fdf86fd60",
"parent": {
"type": "page_id",
"page_id": "1c12c2bb-bca8-8023-ba9a-f8fafab74e48"
},
"created_time": "2025-03-25T07:49:00.000Z",
"last_edited_time": "2025-03-25T07:49:00.000Z",
"created_by": {
"object": "user",
"id": "b69e71d0-c6c2-428c-ae38-5c020343b36b"
},
"last_edited_by": {
"object": "user",
"id": "b69e71d0-c6c2-428c-ae38-5c020343b36b"
},
"has_children": false,
"archived": false,
"in_trash": false,
"type": "paragraph",
"paragraph": {
"rich_text": [],
"color": "default"
}
},
{
"object": "block",
"id": "1c12c2bb-bca8-809a-a9e5-f33faf274c5f",
"parent": {
"type": "page_id",
"page_id": "1c12c2bb-bca8-8023-ba9a-f8fafab74e48"
},
"created_time": "2025-03-25T07:56:00.000Z",
"last_edited_time": "2025-03-25T08:09:00.000Z",
"created_by": {
"object": "user",
"id": "b69e71d0-c6c2-428c-ae38-5c020343b36b"
},
"last_edited_by": {
"object": "user",
"id": "b69e71d0-c6c2-428c-ae38-5c020343b36b"
},
"has_children": false,
"archived": false,
"in_trash": false,
"type": "code",
"code": {
"caption": [],
"rich_text": [],
"language": "javascript"
}
},
{
"object": "block",
"id": "1c12c2bb-bca8-80c2-986a-ef8ae792a0f9",
"parent": {
"type": "page_id",
"page_id": "1c12c2bb-bca8-8023-ba9a-f8fafab74e48"
},
"created_time": "2025-03-25T08:04:00.000Z",
"last_edited_time": "2025-03-25T08:04:00.000Z",
"created_by": {
"object": "user",
"id": "b69e71d0-c6c2-428c-ae38-5c020343b36b"
},
"last_edited_by": {
"object": "user",
"id": "b69e71d0-c6c2-428c-ae38-5c020343b36b"
},
"has_children": false,
"archived": false,
"in_trash": false,
"type": "paragraph",
"paragraph": {
"rich_text": [],
"color": "default"
}
},
{
"object": "block",
"id": "1c12c2bb-bca8-80b3-9180-c6bc089c00fc",
"parent": {
"type": "page_id",
"page_id": "1c12c2bb-bca8-8023-ba9a-f8fafab74e48"
},
"created_time": "2025-03-25T07:56:00.000Z",
"last_edited_time": "2025-03-25T08:05:00.000Z",
"created_by": {
"object": "user",
"id": "b69e71d0-c6c2-428c-ae38-5c020343b36b"
},
"last_edited_by": {
"object": "user",
"id": "b69e71d0-c6c2-428c-ae38-5c020343b36b"
},
"has_children": false,
"archived": false,
"in_trash": false,
"type": "paragraph",
"paragraph": {
"rich_text": [
{
"type": "equation",
"equation": {
"expression": "E"
},
"annotations": {
"bold": false,
"italic": false,
"strikethrough": false,
"underline": false,
"code": false,
"color": "default"
},
"plain_text": "E",
"href": null
}
],
"color": "default"
}
},
{
"object": "block",
"id": "1c12c2bb-bca8-80ca-974e-c226a1a1ae76",
"parent": {
"type": "page_id",
"page_id": "1c12c2bb-bca8-8023-ba9a-f8fafab74e48"
},
"created_time": "2025-03-25T08:10:00.000Z",
"last_edited_time": "2025-03-25T08:10:00.000Z",
"created_by": {
"object": "user",
"id": "b69e71d0-c6c2-428c-ae38-5c020343b36b"
},
"last_edited_by": {
"object": "user",
"id": "b69e71d0-c6c2-428c-ae38-5c020343b36b"
},
"has_children": false,
"archived": false,
"in_trash": false,
"type": "paragraph",
"paragraph": {
"rich_text": [],
"color": "default"
}
},
{
"object": "block",
"id": "1c12c2bb-bca8-8028-944b-e2593f20e09a",
"parent": {
"type": "page_id",
"page_id": "1c12c2bb-bca8-8023-ba9a-f8fafab74e48"
},
"created_time": "2025-03-25T08:09:00.000Z",
"last_edited_time": "2025-03-25T08:10:00.000Z",
"created_by": {
"object": "user",
"id": "b69e71d0-c6c2-428c-ae38-5c020343b36b"
},
"last_edited_by": {
"object": "user",
"id": "b69e71d0-c6c2-428c-ae38-5c020343b36b"
},
"has_children": false,
"archived": false,
"in_trash": false,
"type": "paragraph",
"paragraph": {
"rich_text": [
{
"type": "mention",
"mention": {
"type": "link_mention",
"link_mention": {
"href": "http://github.com/outline/",
"title": "Outline",
"icon_url": "https://github.com/fluidicon.png",
"description": "We're building an open source collaborative knowledge base for modern teams - Outline",
"link_provider": "GitHub",
"thumbnail_url": "https://avatars.githubusercontent.com/u/1765001?s=280&v=4"
}
},
"annotations": {
"bold": false,
"italic": false,
"strikethrough": false,
"underline": false,
"code": false,
"color": "default"
},
"plain_text": "http://github.com/outline/",
"href": "http://github.com/outline/"
}
],
"color": "default"
}
},
{
"object": "block",
"id": "1c12c2bb-bca8-80f8-a272-c519ce56de27",
"parent": {
"type": "page_id",
"page_id": "1c12c2bb-bca8-8023-ba9a-f8fafab74e48"
},
"created_time": "2025-03-25T08:12:00.000Z",
"last_edited_time": "2025-03-25T08:12:00.000Z",
"created_by": {
"object": "user",
"id": "b69e71d0-c6c2-428c-ae38-5c020343b36b"
},
"last_edited_by": {
"object": "user",
"id": "b69e71d0-c6c2-428c-ae38-5c020343b36b"
},
"has_children": false,
"archived": false,
"in_trash": false,
"type": "paragraph",
"paragraph": {
"rich_text": [],
"color": "default"
}
},
{
"object": "block",
"id": "1c12c2bb-bca8-8096-8a94-e44b32127e73",
"parent": {
"type": "page_id",
"page_id": "1c12c2bb-bca8-8023-ba9a-f8fafab74e48"
},
"created_time": "2025-03-25T08:12:00.000Z",
"last_edited_time": "2025-03-25T08:12:00.000Z",
"created_by": {
"object": "user",
"id": "b69e71d0-c6c2-428c-ae38-5c020343b36b"
},
"last_edited_by": {
"object": "user",
"id": "b69e71d0-c6c2-428c-ae38-5c020343b36b"
},
"has_children": false,
"archived": false,
"in_trash": false,
"type": "paragraph",
"paragraph": {
"rich_text": [
{
"type": "mention",
"mention": {
"type": "link_preview",
"link_preview": {
"url": "https://github.com/outline/outline"
}
},
"annotations": {
"bold": false,
"italic": false,
"strikethrough": false,
"underline": false,
"code": false,
"color": "default"
},
"plain_text": "https://github.com/outline/outline",
"href": "https://github.com/outline/outline"
}
],
"color": "default"
}
},
{
"object": "block",
"id": "1c12c2bb-bca8-807b-98de-ff2c1d0080f2",
"parent": {
"type": "page_id",
"page_id": "1c12c2bb-bca8-8023-ba9a-f8fafab74e48"
},
"created_time": "2025-03-25T08:13:00.000Z",
"last_edited_time": "2025-03-25T08:13:00.000Z",
"created_by": {
"object": "user",
"id": "b69e71d0-c6c2-428c-ae38-5c020343b36b"
},
"last_edited_by": {
"object": "user",
"id": "b69e71d0-c6c2-428c-ae38-5c020343b36b"
},
"has_children": false,
"archived": false,
"in_trash": false,
"type": "paragraph",
"paragraph": {
"rich_text": [],
"color": "default"
}
},
{
"object": "block",
"id": "1c12c2bb-bca8-80dd-b816-cb4dd04d4f46",
"parent": {
"type": "page_id",
"page_id": "1c12c2bb-bca8-8023-ba9a-f8fafab74e48"
},
"created_time": "2025-03-25T08:13:00.000Z",
"last_edited_time": "2025-03-25T08:13:00.000Z",
"created_by": {
"object": "user",
"id": "b69e71d0-c6c2-428c-ae38-5c020343b36b"
},
"last_edited_by": {
"object": "user",
"id": "b69e71d0-c6c2-428c-ae38-5c020343b36b"
},
"has_children": false,
"archived": false,
"in_trash": false,
"type": "equation",
"equation": {
"expression": ""
}
},
{
"object": "block",
"id": "1c12c2bb-bca8-8074-a5e0-f0ba30bd0510",
"parent": {
"type": "page_id",
"page_id": "1c12c2bb-bca8-8023-ba9a-f8fafab74e48"
},
"created_time": "2025-03-25T08:18:00.000Z",
"last_edited_time": "2025-03-25T08:18:00.000Z",
"created_by": {
"object": "user",
"id": "b69e71d0-c6c2-428c-ae38-5c020343b36b"
},
"last_edited_by": {
"object": "user",
"id": "b69e71d0-c6c2-428c-ae38-5c020343b36b"
},
"has_children": false,
"archived": false,
"in_trash": false,
"type": "paragraph",
"paragraph": {
"rich_text": [],
"color": "default"
}
},
{
"object": "block",
"id": "1c12c2bb-bca8-80dc-8a14-db8b714450f6",
"parent": {
"type": "page_id",
"page_id": "1c12c2bb-bca8-8023-ba9a-f8fafab74e48"
},
"created_time": "2025-03-25T08:18:00.000Z",
"last_edited_time": "2025-03-25T08:30:00.000Z",
"created_by": {
"object": "user",
"id": "b69e71d0-c6c2-428c-ae38-5c020343b36b"
},
"last_edited_by": {
"object": "user",
"id": "b69e71d0-c6c2-428c-ae38-5c020343b36b"
},
"has_children": false,
"archived": false,
"in_trash": false,
"type": "bookmark",
"bookmark": {
"caption": [],
"url": "https://google.com"
}
},
{
"object": "block",
"id": "1c12c2bb-bca8-80f2-94b4-df422d9cd18e",
"parent": {
"type": "page_id",
"page_id": "1c12c2bb-bca8-8023-ba9a-f8fafab74e48"
},
"created_time": "2025-03-25T08:24:00.000Z",
"last_edited_time": "2025-03-25T08:24:00.000Z",
"created_by": {
"object": "user",
"id": "b69e71d0-c6c2-428c-ae38-5c020343b36b"
},
"last_edited_by": {
"object": "user",
"id": "b69e71d0-c6c2-428c-ae38-5c020343b36b"
},
"has_children": false,
"archived": false,
"in_trash": false,
"type": "paragraph",
"paragraph": {
"rich_text": [],
"color": "default"
}
},
{
"object": "block",
"id": "1c12c2bb-bca8-8046-946c-d89c2bc7827c",
"parent": {
"type": "page_id",
"page_id": "1c12c2bb-bca8-8023-ba9a-f8fafab74e48"
},
"created_time": "2025-03-25T08:24:00.000Z",
"last_edited_time": "2025-03-25T08:24:00.000Z",
"created_by": {
"object": "user",
"id": "b69e71d0-c6c2-428c-ae38-5c020343b36b"
},
"last_edited_by": {
"object": "user",
"id": "1b32c2bb-bca8-816a-99c0-0027ab5c4cb0"
},
"has_children": false,
"archived": false,
"in_trash": false,
"type": "link_preview",
"link_preview": {
"url": "https://github.com/outline/outline"
}
},
{
"object": "block",
"id": "1c12c2bb-bca8-80e6-80d3-f9501fc1a6fb",
"parent": {
"type": "page_id",
"page_id": "1c12c2bb-bca8-8023-ba9a-f8fafab74e48"
},
"created_time": "2025-03-25T08:24:00.000Z",
"last_edited_time": "2025-03-25T08:24:00.000Z",
"created_by": {
"object": "user",
"id": "b69e71d0-c6c2-428c-ae38-5c020343b36b"
},
"last_edited_by": {
"object": "user",
"id": "b69e71d0-c6c2-428c-ae38-5c020343b36b"
},
"has_children": false,
"archived": false,
"in_trash": false,
"type": "paragraph",
"paragraph": {
"rich_text": [],
"color": "default"
}
},
{
"object": "block",
"id": "1c12c2bb-bca8-8070-9c41-ca4c3aa1a419",
"parent": {
"type": "page_id",
"page_id": "1c12c2bb-bca8-8023-ba9a-f8fafab74e48"
},
"created_time": "2025-03-25T08:24:00.000Z",
"last_edited_time": "2025-03-25T08:30:00.000Z",
"created_by": {
"object": "user",
"id": "b69e71d0-c6c2-428c-ae38-5c020343b36b"
},
"last_edited_by": {
"object": "user",
"id": "b69e71d0-c6c2-428c-ae38-5c020343b36b"
},
"has_children": false,
"archived": false,
"in_trash": false,
"type": "pdf",
"pdf": {
"caption": [],
"type": "file",
"file": {
"url": "https://prod-files-secure.s3.us-west-2.amazonaws.com/2f3fcad6-fc32-434b-b6b2-a03ca7893c4d/49bfa851-95c1-458b-abb0-88ed591f7712/Empty_pdf.pdf",
"expiry_time": "2025-03-25T09:32:41.690Z"
}
}
},
{
"object": "block",
"id": "1c12c2bb-bca8-800c-8857-eca03207279f",
"parent": {
"type": "page_id",
"page_id": "1c12c2bb-bca8-8023-ba9a-f8fafab74e48"
},
"created_time": "2025-03-25T08:26:00.000Z",
"last_edited_time": "2025-03-25T08:26:00.000Z",
"created_by": {
"object": "user",
"id": "b69e71d0-c6c2-428c-ae38-5c020343b36b"
},
"last_edited_by": {
"object": "user",
"id": "b69e71d0-c6c2-428c-ae38-5c020343b36b"
},
"has_children": false,
"archived": false,
"in_trash": false,
"type": "paragraph",
"paragraph": {
"rich_text": [],
"color": "default"
}
}
]
+1 -3
View File
@@ -54,9 +54,7 @@ export class CacheHelper {
}
return value;
} finally {
if (lock && lock.expiration > new Date().getTime()) {
await lock.release();
}
await lock?.release();
}
}
+3 -1
View File
@@ -1,6 +1,9 @@
import crypto from "crypto";
import { addMinutes, subMinutes } from "date-fns";
import type { Context } from "koa";
// Allowed for trusted server<->server connections
// eslint-disable-next-line no-restricted-imports
import fetch from "node-fetch";
import {
StateStoreStoreCallback,
StateStoreVerifyCallback,
@@ -10,7 +13,6 @@ import { getCookieDomain, parseDomain } from "@shared/utils/domains";
import env from "@server/env";
import { Team } from "@server/models";
import { InternalError, OAuthStateMismatchError } from "../errors";
import fetch from "./fetch";
export class StateStore {
key = "state";
+4 -2
View File
@@ -1,5 +1,5 @@
import fractionalIndex from "fractional-index";
import { Sequelize, type FindOptions } from "sequelize";
import { Op, Sequelize, type FindOptions } from "sequelize";
import Collection from "@server/models/Collection";
/**
@@ -31,7 +31,9 @@ export default async function removeIndexCollision(
where: {
teamId,
deletedAt: null,
index: Sequelize.literal(`"collection"."index" collate "C" > '${index}'`),
index: {
[Op.gt]: index,
},
},
attributes: ["id", "index"],
limit: 1,
-28
View File
@@ -29,31 +29,3 @@ export function CannotUseWithout(
});
};
}
export function CannotUseWith(
property: string,
validationOptions?: ValidationOptions
) {
return function (object: Object, propertyName: string) {
registerDecorator({
name: "cannotUseWith",
target: object.constructor,
propertyName,
constraints: [property],
options: validationOptions,
validator: {
validate<T>(value: T, args: ValidationArguments) {
if (value === undefined) {
return true;
}
const obj = args.object as unknown as T;
const forbidden = args.constraints[0] as keyof T;
return obj[forbidden] === undefined;
},
defaultMessage(args: ValidationArguments) {
return `${propertyName} cannot be used with ${args.constraints[0]}.`;
},
},
});
};
}
+1 -1
View File
@@ -232,7 +232,7 @@ export class ValidateDocumentId {
export class ValidateIndex {
public static regex = new RegExp("^[\x20-\x7E]+$");
public static message = "Must be between x20 to x7E ASCII";
public static maxLength = 256;
public static maxLength = 100;
}
export class ValidateURL {
+1 -9
View File
@@ -1,5 +1,5 @@
import { NodeType } from "prosemirror-model";
import { liftListItem, wrapInList } from "prosemirror-schema-list";
import { wrapInList, liftListItem } from "prosemirror-schema-list";
import { Command } from "prosemirror-state";
import { chainTransactions } from "../lib/chainTransactions";
import { findParentNode } from "../queries/findParentNode";
@@ -29,14 +29,6 @@ export default function toggleList(
return liftListItem(itemType)(state, dispatch);
}
const currentItemType = parentList.node.content.firstChild?.type;
if (currentItemType && currentItemType !== itemType) {
return chainTransactions(clearNodes(), wrapInList(listType))(
state,
dispatch
);
}
if (
isList(parentList.node, schema) &&
listType.validContent(parentList.node.content)
+59 -4
View File
@@ -4,10 +4,62 @@ import { Node } from "prosemirror-model";
import { Plugin, PluginKey, Transaction } from "prosemirror-state";
import { Decoration, DecorationSet } from "prosemirror-view";
import refractor from "refractor/core";
import { getPrismLangForLanguage } from "../lib/code";
import { isRemoteTransaction } from "../lib/multiplayer";
import { findBlockNodes } from "../queries/findChildren";
export const LANGUAGES = {
none: "Plain text", // additional entry to disable highlighting
bash: "Bash",
clike: "C",
cpp: "C++",
csharp: "C#",
css: "CSS",
docker: "Docker",
elixir: "Elixir",
erlang: "Erlang",
go: "Go",
graphql: "GraphQL",
groovy: "Groovy",
haskell: "Haskell",
hcl: "HCL",
markup: "HTML",
ini: "INI",
java: "Java",
javascript: "JavaScript",
json: "JSON",
jsx: "JSX",
kotlin: "Kotlin",
lisp: "Lisp",
lua: "Lua",
mermaidjs: "Mermaid Diagram",
nginx: "Nginx",
nix: "Nix",
objectivec: "Objective-C",
ocaml: "OCaml",
perl: "Perl",
php: "PHP",
powershell: "Powershell",
protobuf: "Protobuf",
python: "Python",
r: "R",
ruby: "Ruby",
rust: "Rust",
scala: "Scala",
sass: "Sass",
scss: "SCSS",
sql: "SQL",
solidity: "Solidity",
swift: "Swift",
toml: "TOML",
tsx: "TSX",
typescript: "TypeScript",
vb: "Visual Basic",
verilog: "Verilog",
vhdl: "VHDL",
yaml: "YAML",
zig: "Zig",
};
type ParsedNode = {
text: string;
classes: string[];
@@ -57,9 +109,12 @@ function getDecorations({
blocks.forEach((block) => {
let startPos = block.pos + 1;
const language = getPrismLangForLanguage(block.node.attrs.language);
if (!language || !refractor.registered(language)) {
const language = (
block.node.attrs.language === "mermaidjs"
? "mermaid"
: block.node.attrs.language
) as string;
if (!language || language === "none" || !refractor.registered(language)) {
return;
}
-22
View File
@@ -1,22 +0,0 @@
import { getPrismLangForLanguage, getLabelForLanguage } from "./code";
describe("getPrismLangForLanguage", () => {
it("should return the correct Prism language identifier for a given language", () => {
expect(getPrismLangForLanguage("javascript")).toBe("javascript");
expect(getPrismLangForLanguage("mermaidjs")).toBe("mermaid");
expect(getPrismLangForLanguage("xml")).toBe("markup");
expect(getPrismLangForLanguage("unknown")).toBeUndefined();
expect(getPrismLangForLanguage("")).toBeUndefined();
});
});
describe("getLabelForLanguage", () => {
it("should return the correct human-readable label for a given language", () => {
expect(getLabelForLanguage("javascript")).toBe("JavaScript");
expect(getLabelForLanguage("mermaidjs")).toBe("Mermaid Diagram");
expect(getLabelForLanguage("xml")).toBe("XML");
expect(getLabelForLanguage("unknown")).toBe("Plain text");
expect(getLabelForLanguage("none")).toBe("Plain text");
expect(getLabelForLanguage("")).toBe("Plain text");
});
});
+11 -105
View File
@@ -1,97 +1,14 @@
import Storage from "../../utils/Storage";
import { LANGUAGES } from "../extensions/Prism";
const RecentStorageKey = "rme-code-language";
const StorageKey = "frequent-code-languages";
const frequentLanguagesToGet = 5;
const frequentLanguagesToTrack = 10;
/**
* List of supported code languages.
*
* Object key is the language identifier used in the editor, lang is the
* language identifier used by Prism. Note mismatches such as `markup` and
* `mermaid`.
*/
export const codeLanguages = {
none: { lang: "", label: "Plain text" },
bash: { lang: "bash", label: "Bash" },
clike: { lang: "clike", label: "C" },
cpp: { lang: "cpp", label: "C++" },
csharp: { lang: "csharp", label: "C#" },
css: { lang: "css", label: "CSS" },
docker: { lang: "docker", label: "Docker" },
elixir: { lang: "elixir", label: "Elixir" },
erlang: { lang: "erlang", label: "Erlang" },
go: { lang: "go", label: "Go" },
graphql: { lang: "graphql", label: "GraphQL" },
groovy: { lang: "groovy", label: "Groovy" },
haskell: { lang: "haskell", label: "Haskell" },
hcl: { lang: "hcl", label: "HCL" },
markup: { lang: "markup", label: "HTML" },
ini: { lang: "ini", label: "INI" },
java: { lang: "java", label: "Java" },
javascript: { lang: "javascript", label: "JavaScript" },
json: { lang: "json", label: "JSON" },
jsx: { lang: "jsx", label: "JSX" },
kotlin: { lang: "kotlin", label: "Kotlin" },
lisp: { lang: "lisp", label: "Lisp" },
lua: { lang: "lua", label: "Lua" },
mermaidjs: { lang: "mermaid", label: "Mermaid Diagram" },
nginx: { lang: "nginx", label: "Nginx" },
nix: { lang: "nix", label: "Nix" },
objectivec: { lang: "objectivec", label: "Objective-C" },
ocaml: { lang: "ocaml", label: "OCaml" },
perl: { lang: "perl", label: "Perl" },
php: { lang: "php", label: "PHP" },
powershell: { lang: "powershell", label: "Powershell" },
protobuf: { lang: "protobuf", label: "Protobuf" },
python: { lang: "python", label: "Python" },
r: { lang: "r", label: "R" },
ruby: { lang: "ruby", label: "Ruby" },
rust: { lang: "rust", label: "Rust" },
scala: { lang: "scala", label: "Scala" },
sass: { lang: "sass", label: "Sass" },
scss: { lang: "scss", label: "SCSS" },
sql: { lang: "sql", label: "SQL" },
solidity: { lang: "solidity", label: "Solidity" },
swift: { lang: "swift", label: "Swift" },
toml: { lang: "toml", label: "TOML" },
tsx: { lang: "tsx", label: "TSX" },
typescript: { lang: "typescript", label: "TypeScript" },
vb: { lang: "vb", label: "Visual Basic" },
verilog: { lang: "verilog", label: "Verilog" },
vhdl: { lang: "vhdl", label: "VHDL" },
yaml: { lang: "yaml", label: "YAML" },
xml: { lang: "markup", label: "XML" },
zig: { lang: "zig", label: "Zig" },
export const FrequentlyUsedCount = {
Get: 5,
Track: 10,
};
/**
* Get the human-readable label for a given language.
*
* @param language The language identifier.
* @returns The human-readable label for the language.
*/
export const getLabelForLanguage = (language: string) => {
const lang =
codeLanguages[language as keyof typeof codeLanguages] ?? codeLanguages.none;
return lang.label;
};
/**
* Get the Prism language identifier for a given language.
*
* @param language The language identifier.
* @returns The Prism language identifier for the language.
*/
export const getPrismLangForLanguage = (language: string): string | undefined =>
codeLanguages[language as keyof typeof codeLanguages]?.lang;
/**
* Set the most recent code language used.
*
* @param language The language identifier.
*/
export const setRecentCodeLanguage = (language: string) => {
const frequentLangs = (Storage.get(StorageKey) ?? {}) as Record<
string,
@@ -109,14 +26,14 @@ export const setRecentCodeLanguage = (language: string) => {
const frequentLangEntries = Object.entries(frequentLangs);
if (frequentLangEntries.length > frequentLanguagesToTrack) {
if (frequentLangEntries.length > FrequentlyUsedCount.Track) {
sortFrequencies(frequentLangEntries);
const lastEntry = frequentLangEntries[frequentLanguagesToTrack];
const lastEntry = frequentLangEntries[FrequentlyUsedCount.Track];
if (lastEntry[0] === language) {
frequentLangEntries.splice(frequentLanguagesToTrack - 1, 1);
frequentLangEntries.splice(FrequentlyUsedCount.Track - 1, 1);
} else {
frequentLangEntries.splice(frequentLanguagesToTrack);
frequentLangEntries.splice(FrequentlyUsedCount.Track);
}
}
@@ -124,28 +41,17 @@ export const setRecentCodeLanguage = (language: string) => {
Storage.set(RecentStorageKey, language);
};
/**
* Get the most recent code language used.
*
* @returns The most recent code language used, or undefined if none is set.
*/
export const getRecentCodeLanguage = () =>
Storage.get(RecentStorageKey) as keyof typeof codeLanguages | undefined;
export const getRecentCodeLanguage = () => Storage.get(RecentStorageKey);
/**
* Get the most frequent code languages used.
*
* @returns An array of the most frequent code languages used.
*/
export const getFrequentCodeLanguages = () => {
const recentLang = Storage.get(RecentStorageKey);
const frequentLangEntries = Object.entries(Storage.get(StorageKey) ?? {}) as [
keyof typeof codeLanguages,
keyof typeof LANGUAGES,
number
][];
const frequentLangs = sortFrequencies(frequentLangEntries)
.slice(0, frequentLanguagesToGet)
.slice(0, FrequentlyUsedCount.Get)
.map(([lang]) => lang);
const isRecentLangPresent = frequentLangs.includes(recentLang);
-64
View File
@@ -99,7 +99,6 @@ export default class Code extends Mark {
return false;
}
// Check if we're pasting inside backticks
const start = from - 1;
const end = to + 1;
if (
@@ -119,69 +118,6 @@ export default class Code extends Mark {
return true;
}
// Check if we're pasting over an existing inline code block
if (isInCode(state, { onlyMark: true })) {
// Get the range of the current code mark
const marks = state.doc.resolve(from).marks();
const codeMark = marks.find(
(mark) => mark.type === state.schema.marks.code_inline
);
if (codeMark) {
// Find the start and end of the code mark
let codeStart = from;
let codeEnd = to;
// Find the start of the code mark
for (let i = from; i > 0; i--) {
const resolvedPos = state.doc.resolve(i);
const marksAtPos = resolvedPos.marks();
const hasCodeMark = marksAtPos.some(
(mark) => mark.type === state.schema.marks.code_inline
);
if (!hasCodeMark) {
codeStart = i + 1;
break;
}
if (i === 1) {
codeStart = 1;
}
}
// Find the end of the code mark
for (let i = to; i < state.doc.nodeSize - 2; i++) {
const resolvedPos = state.doc.resolve(i);
const marksAtPos = resolvedPos.marks();
const hasCodeMark = marksAtPos.some(
(mark) => mark.type === state.schema.marks.code_inline
);
if (!hasCodeMark) {
codeEnd = i;
break;
}
if (i === state.doc.nodeSize - 3) {
codeEnd = state.doc.nodeSize - 2;
}
}
// Replace the content within the code mark
view.dispatch(
state.tr
.replaceRange(from, to, slice)
.addMark(
from,
from + slice.size,
state.schema.marks.code_inline.create()
)
);
return true;
}
}
return false;
},
+281 -293
View File
@@ -105,32 +105,32 @@
"@smithy/util-utf8" "^2.0.0"
tslib "^2.6.2"
"@aws-sdk/client-s3@3.774.0":
version "3.774.0"
resolved "https://registry.yarnpkg.com/@aws-sdk/client-s3/-/client-s3-3.774.0.tgz#b8fba20417464385ee6c855aaafb67d024d10019"
integrity sha512-HQ5Xi01r/Pv2IpzPTf5acrN0g/yJQalheDCYbBSA8VU31zoYiT/w5kLFWYJHQDB2hRozh2DB/VC/VDmntkWXxA==
"@aws-sdk/client-s3@3.758.0":
version "3.758.0"
resolved "https://registry.yarnpkg.com/@aws-sdk/client-s3/-/client-s3-3.758.0.tgz#430708980e86584172ea8e3dc1450be50bd86818"
integrity sha512-f8SlhU9/93OC/WEI6xVJf/x/GoQFj9a/xXK6QCtr5fvCjfSLgMVFmKTiIl/tgtDRzxUDc8YS6EGtbHjJ3Y/atg==
dependencies:
"@aws-crypto/sha1-browser" "5.2.0"
"@aws-crypto/sha256-browser" "5.2.0"
"@aws-crypto/sha256-js" "5.2.0"
"@aws-sdk/core" "3.774.0"
"@aws-sdk/credential-provider-node" "3.774.0"
"@aws-sdk/core" "3.758.0"
"@aws-sdk/credential-provider-node" "3.758.0"
"@aws-sdk/middleware-bucket-endpoint" "3.734.0"
"@aws-sdk/middleware-expect-continue" "3.734.0"
"@aws-sdk/middleware-flexible-checksums" "3.774.0"
"@aws-sdk/middleware-host-header" "3.774.0"
"@aws-sdk/middleware-flexible-checksums" "3.758.0"
"@aws-sdk/middleware-host-header" "3.734.0"
"@aws-sdk/middleware-location-constraint" "3.734.0"
"@aws-sdk/middleware-logger" "3.734.0"
"@aws-sdk/middleware-recursion-detection" "3.772.0"
"@aws-sdk/middleware-sdk-s3" "3.774.0"
"@aws-sdk/middleware-recursion-detection" "3.734.0"
"@aws-sdk/middleware-sdk-s3" "3.758.0"
"@aws-sdk/middleware-ssec" "3.734.0"
"@aws-sdk/middleware-user-agent" "3.774.0"
"@aws-sdk/middleware-user-agent" "3.758.0"
"@aws-sdk/region-config-resolver" "3.734.0"
"@aws-sdk/signature-v4-multi-region" "3.774.0"
"@aws-sdk/signature-v4-multi-region" "3.758.0"
"@aws-sdk/types" "3.734.0"
"@aws-sdk/util-endpoints" "3.743.0"
"@aws-sdk/util-user-agent-browser" "3.734.0"
"@aws-sdk/util-user-agent-node" "3.774.0"
"@aws-sdk/util-user-agent-node" "3.758.0"
"@aws-sdk/xml-builder" "3.734.0"
"@smithy/config-resolver" "^4.0.1"
"@smithy/core" "^3.1.5"
@@ -167,23 +167,23 @@
"@smithy/util-waiter" "^4.0.2"
tslib "^2.6.2"
"@aws-sdk/client-sso@3.774.0":
version "3.774.0"
resolved "https://registry.yarnpkg.com/@aws-sdk/client-sso/-/client-sso-3.774.0.tgz#8af5eeaa644eb1e4775babaa46de89e1e9f3ab21"
integrity sha512-bN+wd2gpTq+DNJ/fZdam/mX6K3TcVdZBIvxaVtg+imep6xAuRukdFhsoG0cDzk96+WHPCOhkyi+6lFljCof43Q==
"@aws-sdk/client-sso@3.758.0":
version "3.758.0"
resolved "https://registry.yarnpkg.com/@aws-sdk/client-sso/-/client-sso-3.758.0.tgz#59a249abdfa52125fbe98b1d59c11e4f08ca6527"
integrity sha512-BoGO6IIWrLyLxQG6txJw6RT2urmbtlwfggapNCrNPyYjlXpzTSJhBYjndg7TpDATFd0SXL0zm8y/tXsUXNkdYQ==
dependencies:
"@aws-crypto/sha256-browser" "5.2.0"
"@aws-crypto/sha256-js" "5.2.0"
"@aws-sdk/core" "3.774.0"
"@aws-sdk/middleware-host-header" "3.774.0"
"@aws-sdk/core" "3.758.0"
"@aws-sdk/middleware-host-header" "3.734.0"
"@aws-sdk/middleware-logger" "3.734.0"
"@aws-sdk/middleware-recursion-detection" "3.772.0"
"@aws-sdk/middleware-user-agent" "3.774.0"
"@aws-sdk/middleware-recursion-detection" "3.734.0"
"@aws-sdk/middleware-user-agent" "3.758.0"
"@aws-sdk/region-config-resolver" "3.734.0"
"@aws-sdk/types" "3.734.0"
"@aws-sdk/util-endpoints" "3.743.0"
"@aws-sdk/util-user-agent-browser" "3.734.0"
"@aws-sdk/util-user-agent-node" "3.774.0"
"@aws-sdk/util-user-agent-node" "3.758.0"
"@smithy/config-resolver" "^4.0.1"
"@smithy/core" "^3.1.5"
"@smithy/fetch-http-handler" "^5.0.1"
@@ -211,10 +211,10 @@
"@smithy/util-utf8" "^4.0.0"
tslib "^2.6.2"
"@aws-sdk/core@3.774.0":
version "3.774.0"
resolved "https://registry.yarnpkg.com/@aws-sdk/core/-/core-3.774.0.tgz#88926fc1c2efefa8fad602217865ee0c5ffca40b"
integrity sha512-JDkAAlPyGWMX42L4Cv8mxybwHTOoFweNbNrOc5oQJhFxZAe1zkW4uLTEfr79vYhnXCFbThCyPpBotmo3U2vULA==
"@aws-sdk/core@3.758.0":
version "3.758.0"
resolved "https://registry.yarnpkg.com/@aws-sdk/core/-/core-3.758.0.tgz#d13a4bb95de0460d5269cd5a40503c85b344b0b4"
integrity sha512-0RswbdR9jt/XKemaLNuxi2gGr4xGlHyGxkTdhSQzCyUe9A9OPCoLl3rIESRguQEech+oJnbHk/wuiwHqTuP9sg==
dependencies:
"@aws-sdk/types" "3.734.0"
"@smithy/core" "^3.1.5"
@@ -228,23 +228,23 @@
fast-xml-parser "4.4.1"
tslib "^2.6.2"
"@aws-sdk/credential-provider-env@3.774.0":
version "3.774.0"
resolved "https://registry.yarnpkg.com/@aws-sdk/credential-provider-env/-/credential-provider-env-3.774.0.tgz#1bbbb4e9ad0683d691aa65714a23ecdcbc649746"
integrity sha512-FkSDBi9Ly0bmzyrMDeqQq1lGsFMrrd/bIB3c9VD4Llh0sPLxB/DU31+VTPTuQ0pBPz4sX5Vay6tLy43DStzcFQ==
"@aws-sdk/credential-provider-env@3.758.0":
version "3.758.0"
resolved "https://registry.yarnpkg.com/@aws-sdk/credential-provider-env/-/credential-provider-env-3.758.0.tgz#6193d1607eedd0929640ff64013f7787f29ff6a1"
integrity sha512-N27eFoRrO6MeUNumtNHDW9WOiwfd59LPXPqDrIa3kWL/s+fOKFHb9xIcF++bAwtcZnAxKkgpDCUP+INNZskE+w==
dependencies:
"@aws-sdk/core" "3.774.0"
"@aws-sdk/core" "3.758.0"
"@aws-sdk/types" "3.734.0"
"@smithy/property-provider" "^4.0.1"
"@smithy/types" "^4.1.0"
tslib "^2.6.2"
"@aws-sdk/credential-provider-http@3.774.0":
version "3.774.0"
resolved "https://registry.yarnpkg.com/@aws-sdk/credential-provider-http/-/credential-provider-http-3.774.0.tgz#af35ae8b64a2d8347631259bf4ca0a2f1944fe35"
integrity sha512-iurWGQColf52HpHeHCQs/LnSjZ0Ufq3VtSQx/6QdZwIhmgbbqvGMAaBJg41SQjWhpqdufE96HzcaCJw/lnCefQ==
"@aws-sdk/credential-provider-http@3.758.0":
version "3.758.0"
resolved "https://registry.yarnpkg.com/@aws-sdk/credential-provider-http/-/credential-provider-http-3.758.0.tgz#f7b28d642f2ac933e81a7add08ce582b398c1635"
integrity sha512-Xt9/U8qUCiw1hihztWkNeIR+arg6P+yda10OuCHX6kFVx3auTlU7+hCqs3UxqniGU4dguHuftf3mRpi5/GJ33Q==
dependencies:
"@aws-sdk/core" "3.774.0"
"@aws-sdk/core" "3.758.0"
"@aws-sdk/types" "3.734.0"
"@smithy/fetch-http-handler" "^5.0.1"
"@smithy/node-http-handler" "^4.0.3"
@@ -255,18 +255,18 @@
"@smithy/util-stream" "^4.1.2"
tslib "^2.6.2"
"@aws-sdk/credential-provider-ini@3.774.0":
version "3.774.0"
resolved "https://registry.yarnpkg.com/@aws-sdk/credential-provider-ini/-/credential-provider-ini-3.774.0.tgz#5908b083a6f839de672c0b6cae7b725308ef3816"
integrity sha512-+AsJOX9pGsnGPAC8wQw7LAO8ZfXzjXTjJxSP1fvg04PX7OBk4zwhVaryH6pu5raan+9cVbfEO1Z7EEMdkweGQA==
"@aws-sdk/credential-provider-ini@3.758.0":
version "3.758.0"
resolved "https://registry.yarnpkg.com/@aws-sdk/credential-provider-ini/-/credential-provider-ini-3.758.0.tgz#66457e71d8f5013e18111b25629c2367ed8ef116"
integrity sha512-cymSKMcP5d+OsgetoIZ5QCe1wnp2Q/tq+uIxVdh9MbfdBBEnl9Ecq6dH6VlYS89sp4QKuxHxkWXVnbXU3Q19Aw==
dependencies:
"@aws-sdk/core" "3.774.0"
"@aws-sdk/credential-provider-env" "3.774.0"
"@aws-sdk/credential-provider-http" "3.774.0"
"@aws-sdk/credential-provider-process" "3.774.0"
"@aws-sdk/credential-provider-sso" "3.774.0"
"@aws-sdk/credential-provider-web-identity" "3.774.0"
"@aws-sdk/nested-clients" "3.774.0"
"@aws-sdk/core" "3.758.0"
"@aws-sdk/credential-provider-env" "3.758.0"
"@aws-sdk/credential-provider-http" "3.758.0"
"@aws-sdk/credential-provider-process" "3.758.0"
"@aws-sdk/credential-provider-sso" "3.758.0"
"@aws-sdk/credential-provider-web-identity" "3.758.0"
"@aws-sdk/nested-clients" "3.758.0"
"@aws-sdk/types" "3.734.0"
"@smithy/credential-provider-imds" "^4.0.1"
"@smithy/property-provider" "^4.0.1"
@@ -274,17 +274,17 @@
"@smithy/types" "^4.1.0"
tslib "^2.6.2"
"@aws-sdk/credential-provider-node@3.774.0":
version "3.774.0"
resolved "https://registry.yarnpkg.com/@aws-sdk/credential-provider-node/-/credential-provider-node-3.774.0.tgz#b82ecf506098a62b2f3774aee4377f3089e7bf39"
integrity sha512-/t+TNhHNW6BNyf7Lgv6I0NUfFk6/dz4+6dUjopRxpDVJtp1YvNza0Zhl25ffRkqX4CKmuXyJYusDbbObcsncUA==
"@aws-sdk/credential-provider-node@3.758.0":
version "3.758.0"
resolved "https://registry.yarnpkg.com/@aws-sdk/credential-provider-node/-/credential-provider-node-3.758.0.tgz#b0a5d18e5d7f1b091fd891e2e8088578c0246cef"
integrity sha512-+DaMv63wiq7pJrhIQzZYMn4hSarKiizDoJRvyR7WGhnn0oQ/getX9Z0VNCV3i7lIFoLNTb7WMmQ9k7+z/uD5EQ==
dependencies:
"@aws-sdk/credential-provider-env" "3.774.0"
"@aws-sdk/credential-provider-http" "3.774.0"
"@aws-sdk/credential-provider-ini" "3.774.0"
"@aws-sdk/credential-provider-process" "3.774.0"
"@aws-sdk/credential-provider-sso" "3.774.0"
"@aws-sdk/credential-provider-web-identity" "3.774.0"
"@aws-sdk/credential-provider-env" "3.758.0"
"@aws-sdk/credential-provider-http" "3.758.0"
"@aws-sdk/credential-provider-ini" "3.758.0"
"@aws-sdk/credential-provider-process" "3.758.0"
"@aws-sdk/credential-provider-sso" "3.758.0"
"@aws-sdk/credential-provider-web-identity" "3.758.0"
"@aws-sdk/types" "3.734.0"
"@smithy/credential-provider-imds" "^4.0.1"
"@smithy/property-provider" "^4.0.1"
@@ -292,57 +292,57 @@
"@smithy/types" "^4.1.0"
tslib "^2.6.2"
"@aws-sdk/credential-provider-process@3.774.0":
version "3.774.0"
resolved "https://registry.yarnpkg.com/@aws-sdk/credential-provider-process/-/credential-provider-process-3.774.0.tgz#f3e507621cdd9818dc538f8ca142bf323b71c76a"
integrity sha512-lycBRY1NeWa46LefN258m1MRVUPQgvf6TPA6ZYajyq6/dCr6BPeuUoUAyrzePTPlxV/M25YXNiyORHjjwlK0ug==
"@aws-sdk/credential-provider-process@3.758.0":
version "3.758.0"
resolved "https://registry.yarnpkg.com/@aws-sdk/credential-provider-process/-/credential-provider-process-3.758.0.tgz#563bfae58049afd9968ca60f61672753834ff506"
integrity sha512-AzcY74QTPqcbXWVgjpPZ3HOmxQZYPROIBz2YINF0OQk0MhezDWV/O7Xec+K1+MPGQO3qS6EDrUUlnPLjsqieHA==
dependencies:
"@aws-sdk/core" "3.774.0"
"@aws-sdk/core" "3.758.0"
"@aws-sdk/types" "3.734.0"
"@smithy/property-provider" "^4.0.1"
"@smithy/shared-ini-file-loader" "^4.0.1"
"@smithy/types" "^4.1.0"
tslib "^2.6.2"
"@aws-sdk/credential-provider-sso@3.774.0":
version "3.774.0"
resolved "https://registry.yarnpkg.com/@aws-sdk/credential-provider-sso/-/credential-provider-sso-3.774.0.tgz#61a384c6fd56b5dd5ec1cae4c8dcc90fd77551fc"
integrity sha512-j7vbGCWF6dVpd9qiT0PQGzY4NKf8KUa86sSoosGGbtu0dV9T/Y0s/fvPZ0F8ZyuPIKUMJaBpIJYZ/ECZRfT2mg==
"@aws-sdk/credential-provider-sso@3.758.0":
version "3.758.0"
resolved "https://registry.yarnpkg.com/@aws-sdk/credential-provider-sso/-/credential-provider-sso-3.758.0.tgz#5098c196a2dd38ba467aca052fc5193476b8a404"
integrity sha512-x0FYJqcOLUCv8GLLFDYMXRAQKGjoM+L0BG4BiHYZRDf24yQWFCAZsCQAYKo6XZYh2qznbsW6f//qpyJ5b0QVKQ==
dependencies:
"@aws-sdk/client-sso" "3.774.0"
"@aws-sdk/core" "3.774.0"
"@aws-sdk/token-providers" "3.774.0"
"@aws-sdk/client-sso" "3.758.0"
"@aws-sdk/core" "3.758.0"
"@aws-sdk/token-providers" "3.758.0"
"@aws-sdk/types" "3.734.0"
"@smithy/property-provider" "^4.0.1"
"@smithy/shared-ini-file-loader" "^4.0.1"
"@smithy/types" "^4.1.0"
tslib "^2.6.2"
"@aws-sdk/credential-provider-web-identity@3.774.0":
version "3.774.0"
resolved "https://registry.yarnpkg.com/@aws-sdk/credential-provider-web-identity/-/credential-provider-web-identity-3.774.0.tgz#4063e879ec57357333af542a32a72576908ecd7e"
integrity sha512-kuE5Hdqm9xXdrYBWCU6l2aM3W3HBtZrIBgyf0y41LulJHwld1nvIySus/lILdzbipmUAv9FI07B8TF5y7p/aFA==
"@aws-sdk/credential-provider-web-identity@3.758.0":
version "3.758.0"
resolved "https://registry.yarnpkg.com/@aws-sdk/credential-provider-web-identity/-/credential-provider-web-identity-3.758.0.tgz#ea88729ee0e5de0bf5f31929d60dfd148934b6a5"
integrity sha512-XGguXhBqiCXMXRxcfCAVPlMbm3VyJTou79r/3mxWddHWF0XbhaQiBIbUz6vobVTD25YQRbWSmSch7VA8kI5Lrw==
dependencies:
"@aws-sdk/core" "3.774.0"
"@aws-sdk/nested-clients" "3.774.0"
"@aws-sdk/core" "3.758.0"
"@aws-sdk/nested-clients" "3.758.0"
"@aws-sdk/types" "3.734.0"
"@smithy/property-provider" "^4.0.1"
"@smithy/types" "^4.1.0"
tslib "^2.6.2"
"@aws-sdk/crt-loader@3.774.0":
version "3.774.0"
resolved "https://registry.yarnpkg.com/@aws-sdk/crt-loader/-/crt-loader-3.774.0.tgz#124ad98cce8320153e010b97f665ecddf0608ed1"
integrity sha512-9pZZLebem2Q6rsT29Tzto0/P92IpwOg4c1viZltl2xnEH7kD4nxG+6v6upzPE5L2pm2S88kZXkXi7jZ6HOIBjQ==
"@aws-sdk/crt-loader@3.758.0":
version "3.758.0"
resolved "https://registry.yarnpkg.com/@aws-sdk/crt-loader/-/crt-loader-3.758.0.tgz#ed9372fc887c34af4408e376832d8684316055fc"
integrity sha512-FnLhsDNK3il4rm6Egv7IEuOf8Oiyte5AVeoYkuqgmkCll58tRZCJXYNG/VE+Tket0s3joueVt7rwvHXnMxG0rg==
dependencies:
"@aws-sdk/util-user-agent-node" "3.774.0"
"@aws-sdk/util-user-agent-node" "3.758.0"
aws-crt "^1.24.0"
tslib "^2.6.2"
"@aws-sdk/lib-storage@3.774.0":
version "3.774.0"
resolved "https://registry.yarnpkg.com/@aws-sdk/lib-storage/-/lib-storage-3.774.0.tgz#f198af2fe92a3fe6e3368577ca836f5382c411b8"
integrity sha512-xB3rD+F5pt+JLJaUt5eakCJ3+CUa8PXk9nxgN2VozfpuvuR6A/l3lnxmP5wYLhw1I9hxJLV9AD1/QYcibdBjtQ==
"@aws-sdk/lib-storage@3.758.0":
version "3.758.0"
resolved "https://registry.yarnpkg.com/@aws-sdk/lib-storage/-/lib-storage-3.758.0.tgz#6fe6a128e6a1bc062cc3e4bd920774545ce94933"
integrity sha512-g07y7rA505zaTJNPTmvW4zYJA3gThFDE1be7kBUKhTKAdwv8jVSbOiAy2AhClXs2evSUoQiFFtD1xWxLRXPPRQ==
dependencies:
"@smithy/abort-controller" "^4.0.1"
"@smithy/middleware-endpoint" "^4.0.6"
@@ -375,15 +375,15 @@
"@smithy/types" "^4.1.0"
tslib "^2.6.2"
"@aws-sdk/middleware-flexible-checksums@3.774.0":
version "3.774.0"
resolved "https://registry.yarnpkg.com/@aws-sdk/middleware-flexible-checksums/-/middleware-flexible-checksums-3.774.0.tgz#d0345541dddda11bf8daafb25dc82809f2627c7f"
integrity sha512-S0vs+U7sEZkRRnjf05KCbEHDduyxGgNPq+ZeaiyWbs5yTZ8wzSYrSzMAKcbCqAseNVYQbpGMXDh8tnzx6H/ihw==
"@aws-sdk/middleware-flexible-checksums@3.758.0":
version "3.758.0"
resolved "https://registry.yarnpkg.com/@aws-sdk/middleware-flexible-checksums/-/middleware-flexible-checksums-3.758.0.tgz#50b753e5c83f4fe2ec3578a1768a68336ec86e3c"
integrity sha512-o8Rk71S08YTKLoSobucjnbj97OCGaXgpEDNKXpXaavUM5xLNoHCLSUPRCiEN86Ivqxg1n17Y2nSRhfbsveOXXA==
dependencies:
"@aws-crypto/crc32" "5.2.0"
"@aws-crypto/crc32c" "5.2.0"
"@aws-crypto/util" "5.2.0"
"@aws-sdk/core" "3.774.0"
"@aws-sdk/core" "3.758.0"
"@aws-sdk/types" "3.734.0"
"@smithy/is-array-buffer" "^4.0.0"
"@smithy/node-config-provider" "^4.0.1"
@@ -394,10 +394,10 @@
"@smithy/util-utf8" "^4.0.0"
tslib "^2.6.2"
"@aws-sdk/middleware-host-header@3.774.0":
version "3.774.0"
resolved "https://registry.yarnpkg.com/@aws-sdk/middleware-host-header/-/middleware-host-header-3.774.0.tgz#a71a6884823512f5190b0a56db3234395d0a45ba"
integrity sha512-7QHA0ZyEBVfyJqmIc0FW4MUtPdrWhDsHQudsvBCHFS+mqP5fhpU/o4e5RQ+0M7tQqDE65+8MrZRniRa+Txz3xA==
"@aws-sdk/middleware-host-header@3.734.0":
version "3.734.0"
resolved "https://registry.yarnpkg.com/@aws-sdk/middleware-host-header/-/middleware-host-header-3.734.0.tgz#a9a02c055352f5c435cc925a4e1e79b7ba41b1b5"
integrity sha512-LW7RRgSOHHBzWZnigNsDIzu3AiwtjeI2X66v+Wn1P1u+eXssy1+up4ZY/h+t2sU4LU36UvEf+jrZti9c6vRnFw==
dependencies:
"@aws-sdk/types" "3.734.0"
"@smithy/protocol-http" "^5.0.1"
@@ -422,22 +422,22 @@
"@smithy/types" "^4.1.0"
tslib "^2.6.2"
"@aws-sdk/middleware-recursion-detection@3.772.0":
version "3.772.0"
resolved "https://registry.yarnpkg.com/@aws-sdk/middleware-recursion-detection/-/middleware-recursion-detection-3.772.0.tgz#5f9bf624de8dca8791678fadc5cc905e839b3ca3"
integrity sha512-zg0LjJa4v7fcLzn5QzZvtVS+qyvmsnu7oQnb86l6ckduZpWDCDC9+A0ZzcXTrxblPCJd3JqkoG1+Gzi4S4Ny/Q==
"@aws-sdk/middleware-recursion-detection@3.734.0":
version "3.734.0"
resolved "https://registry.yarnpkg.com/@aws-sdk/middleware-recursion-detection/-/middleware-recursion-detection-3.734.0.tgz#4fa1deb9887455afbb39130f7d9bc89ccee17168"
integrity sha512-CUat2d9ITsFc2XsmeiRQO96iWpxSKYFjxvj27Hc7vo87YUHRnfMfnc8jw1EpxEwMcvBD7LsRa6vDNky6AjcrFA==
dependencies:
"@aws-sdk/types" "3.734.0"
"@smithy/protocol-http" "^5.0.1"
"@smithy/types" "^4.1.0"
tslib "^2.6.2"
"@aws-sdk/middleware-sdk-s3@3.774.0":
version "3.774.0"
resolved "https://registry.yarnpkg.com/@aws-sdk/middleware-sdk-s3/-/middleware-sdk-s3-3.774.0.tgz#e2d078a941550f70abfeed710d966958dd402cf9"
integrity sha512-iMEaOj+S8LZfg7fZaSfXQ8YDtEfOSBiQUllyxzaVhSYlM7IeNDbpBdCWnRi34VrI1J1AuryMdX/foU9JNSTLXg==
"@aws-sdk/middleware-sdk-s3@3.758.0":
version "3.758.0"
resolved "https://registry.yarnpkg.com/@aws-sdk/middleware-sdk-s3/-/middleware-sdk-s3-3.758.0.tgz#75c224a49e47111df880b683debbd8f49f30ca24"
integrity sha512-6mJ2zyyHPYSV6bAcaFpsdoXZJeQlR1QgBnZZ6juY/+dcYiuyWCdyLUbGzSZSE7GTfx6i+9+QWFeoIMlWKgU63A==
dependencies:
"@aws-sdk/core" "3.774.0"
"@aws-sdk/core" "3.758.0"
"@aws-sdk/types" "3.734.0"
"@aws-sdk/util-arn-parser" "3.723.0"
"@smithy/core" "^3.1.5"
@@ -461,12 +461,12 @@
"@smithy/types" "^4.1.0"
tslib "^2.6.2"
"@aws-sdk/middleware-user-agent@3.774.0":
version "3.774.0"
resolved "https://registry.yarnpkg.com/@aws-sdk/middleware-user-agent/-/middleware-user-agent-3.774.0.tgz#dbe66f063cf692de13301a696bb6bc693afd5608"
integrity sha512-SVDeBV6DESgc9zex1Wk5XYbUqRI1tmJYQor47uKqD18r6UaCpvzVOBP4x8l/6hteAYxsWER6ZZmsjBQkenEuFQ==
"@aws-sdk/middleware-user-agent@3.758.0":
version "3.758.0"
resolved "https://registry.yarnpkg.com/@aws-sdk/middleware-user-agent/-/middleware-user-agent-3.758.0.tgz#f3c9d2025aa55fd400acb1d699c1fbd6b4f68f34"
integrity sha512-iNyehQXtQlj69JCgfaOssgZD4HeYGOwxcaKeG6F+40cwBjTAi0+Ph1yfDwqk2qiBPIRWJ/9l2LodZbxiBqgrwg==
dependencies:
"@aws-sdk/core" "3.774.0"
"@aws-sdk/core" "3.758.0"
"@aws-sdk/types" "3.734.0"
"@aws-sdk/util-endpoints" "3.743.0"
"@smithy/core" "^3.1.5"
@@ -474,23 +474,23 @@
"@smithy/types" "^4.1.0"
tslib "^2.6.2"
"@aws-sdk/nested-clients@3.774.0":
version "3.774.0"
resolved "https://registry.yarnpkg.com/@aws-sdk/nested-clients/-/nested-clients-3.774.0.tgz#b46a8ad0f1b106066ba58387fb8977b228186121"
integrity sha512-00+UiYvxiZaDFVzn87kPpiZ/GiEWNaTNzC82C+bIyXt1M9AnAR6PAnnvMErTFwyG+Un6n2ai/I81wvJ1ftFmeQ==
"@aws-sdk/nested-clients@3.758.0":
version "3.758.0"
resolved "https://registry.yarnpkg.com/@aws-sdk/nested-clients/-/nested-clients-3.758.0.tgz#571c853602d38f5e8faa10178347e711e4f0e444"
integrity sha512-YZ5s7PSvyF3Mt2h1EQulCG93uybprNGbBkPmVuy/HMMfbFTt4iL3SbKjxqvOZelm86epFfj7pvK7FliI2WOEcg==
dependencies:
"@aws-crypto/sha256-browser" "5.2.0"
"@aws-crypto/sha256-js" "5.2.0"
"@aws-sdk/core" "3.774.0"
"@aws-sdk/middleware-host-header" "3.774.0"
"@aws-sdk/core" "3.758.0"
"@aws-sdk/middleware-host-header" "3.734.0"
"@aws-sdk/middleware-logger" "3.734.0"
"@aws-sdk/middleware-recursion-detection" "3.772.0"
"@aws-sdk/middleware-user-agent" "3.774.0"
"@aws-sdk/middleware-recursion-detection" "3.734.0"
"@aws-sdk/middleware-user-agent" "3.758.0"
"@aws-sdk/region-config-resolver" "3.734.0"
"@aws-sdk/types" "3.734.0"
"@aws-sdk/util-endpoints" "3.743.0"
"@aws-sdk/util-user-agent-browser" "3.734.0"
"@aws-sdk/util-user-agent-node" "3.774.0"
"@aws-sdk/util-user-agent-node" "3.758.0"
"@smithy/config-resolver" "^4.0.1"
"@smithy/core" "^3.1.5"
"@smithy/fetch-http-handler" "^5.0.1"
@@ -530,12 +530,12 @@
"@smithy/util-middleware" "^4.0.1"
tslib "^2.6.2"
"@aws-sdk/s3-presigned-post@3.774.0":
version "3.774.0"
resolved "https://registry.yarnpkg.com/@aws-sdk/s3-presigned-post/-/s3-presigned-post-3.774.0.tgz#3359884307a2937c70632b6979bd47e6690a47c1"
integrity sha512-JttkojrrhYrTPe/svhGuMWjmoI9sbrIQ6RdXUt6JiNFVFMOqSMj5rpue3L9I4WS0Yb1+n7EiDnjLGNM9cY5/Bw==
"@aws-sdk/s3-presigned-post@3.758.0":
version "3.758.0"
resolved "https://registry.yarnpkg.com/@aws-sdk/s3-presigned-post/-/s3-presigned-post-3.758.0.tgz#d65319c780a251a688c1a4158d9329cce16f6f21"
integrity sha512-x+TWQ6xYD+/i3IlIM0nn1HGAKCmkG12VslKyJSrZAjwWQeVerj6LPVIJvYFcZbNU5lEPWCnlVqKw3S3NgG+N4Q==
dependencies:
"@aws-sdk/client-s3" "3.774.0"
"@aws-sdk/client-s3" "3.758.0"
"@aws-sdk/types" "3.734.0"
"@aws-sdk/util-format-url" "3.734.0"
"@smithy/middleware-endpoint" "^4.0.6"
@@ -545,12 +545,12 @@
"@smithy/util-utf8" "^4.0.0"
tslib "^2.6.2"
"@aws-sdk/s3-request-presigner@3.774.0":
version "3.774.0"
resolved "https://registry.yarnpkg.com/@aws-sdk/s3-request-presigner/-/s3-request-presigner-3.774.0.tgz#b0e8301a38879a1ff03df3a807fadb88c64dac1f"
integrity sha512-vD37Nq7+ChUkXSoDqkNMXu37R8kRDUo13pOfYgesSI4HA970fjXP1T4Mf2131Ms/NuYbBHNn330+3MAkbbYKxg==
"@aws-sdk/s3-request-presigner@3.758.0":
version "3.758.0"
resolved "https://registry.yarnpkg.com/@aws-sdk/s3-request-presigner/-/s3-request-presigner-3.758.0.tgz#e7bbf9251927952584739b5e45464a9f4bdf0739"
integrity sha512-dVyItwu/J1InfJBbCPpHRV9jrsBfI7L0RlDGyS3x/xqBwnm5qpvgNZQasQiyqIl+WJB4f5rZRZHgHuwftqINbA==
dependencies:
"@aws-sdk/signature-v4-multi-region" "3.774.0"
"@aws-sdk/signature-v4-multi-region" "3.758.0"
"@aws-sdk/types" "3.734.0"
"@aws-sdk/util-format-url" "3.734.0"
"@smithy/middleware-endpoint" "^4.0.6"
@@ -559,13 +559,13 @@
"@smithy/types" "^4.1.0"
tslib "^2.6.2"
"@aws-sdk/signature-v4-crt@^3.774.0":
version "3.774.0"
resolved "https://registry.yarnpkg.com/@aws-sdk/signature-v4-crt/-/signature-v4-crt-3.774.0.tgz#22f6c07ac4c96b9128da57a0304f54baa07687bd"
integrity sha512-aXc1Mw+TkDDZqG/8VFexIWqNsYqsArT+auX0QmrCv+x2XgUSpoe++2Ge2CEH4N8ez6/jE9UBqQHLn+0h734X4w==
"@aws-sdk/signature-v4-crt@^3.758.0":
version "3.758.0"
resolved "https://registry.yarnpkg.com/@aws-sdk/signature-v4-crt/-/signature-v4-crt-3.758.0.tgz#a28b376a7d69019a3cb8e1afa11bfbeef9285662"
integrity sha512-DioxfJ8+KenOwydElJvWwMxw0IN8rTD3lbV3AbURwIp+5FBDz8F5ykMO1o1YUQvrGuUNtala8lX3ScE2L7tw9w==
dependencies:
"@aws-sdk/crt-loader" "3.774.0"
"@aws-sdk/signature-v4-multi-region" "3.774.0"
"@aws-sdk/crt-loader" "3.758.0"
"@aws-sdk/signature-v4-multi-region" "3.758.0"
"@aws-sdk/types" "3.734.0"
"@smithy/querystring-parser" "^4.0.1"
"@smithy/signature-v4" "^5.0.1"
@@ -573,24 +573,24 @@
"@smithy/util-middleware" "^4.0.1"
tslib "^2.6.2"
"@aws-sdk/signature-v4-multi-region@3.774.0":
version "3.774.0"
resolved "https://registry.yarnpkg.com/@aws-sdk/signature-v4-multi-region/-/signature-v4-multi-region-3.774.0.tgz#46b2240559560d064d563951af0f23a488336ff9"
integrity sha512-vQwATjZfl5vxfO+BDUH7nUnhfKoIJMnBmOxmUh4N10PWlz3WWwkT/YtH79nVpr+y1eM6GQUSGuNa4Reda6SaFA==
"@aws-sdk/signature-v4-multi-region@3.758.0":
version "3.758.0"
resolved "https://registry.yarnpkg.com/@aws-sdk/signature-v4-multi-region/-/signature-v4-multi-region-3.758.0.tgz#2ccd34e90120dbf6f29e4f621574efd02e463b79"
integrity sha512-0RPCo8fYJcrenJ6bRtiUbFOSgQ1CX/GpvwtLU2Fam1tS9h2klKK8d74caeV6A1mIUvBU7bhyQ0wMGlwMtn3EYw==
dependencies:
"@aws-sdk/middleware-sdk-s3" "3.774.0"
"@aws-sdk/middleware-sdk-s3" "3.758.0"
"@aws-sdk/types" "3.734.0"
"@smithy/protocol-http" "^5.0.1"
"@smithy/signature-v4" "^5.0.1"
"@smithy/types" "^4.1.0"
tslib "^2.6.2"
"@aws-sdk/token-providers@3.774.0":
version "3.774.0"
resolved "https://registry.yarnpkg.com/@aws-sdk/token-providers/-/token-providers-3.774.0.tgz#d0b4b2e6b887bf5b61fbfbb946bfbb863f849d15"
integrity sha512-DDERwCduWFFXj7gx3qvnaB8GlnCUpQ8ZA03qI4QFokWu3EyHNK+hjp3nN5Dg81fI0Z82LRe30Q2uDsLBwNCZDg==
"@aws-sdk/token-providers@3.758.0":
version "3.758.0"
resolved "https://registry.yarnpkg.com/@aws-sdk/token-providers/-/token-providers-3.758.0.tgz#fcab3885ba2b222ff8bb7817448d3c786dc2ddf9"
integrity sha512-ckptN1tNrIfQUaGWm/ayW1ddG+imbKN7HHhjFdS4VfItsP0QQOB0+Ov+tpgb4MoNR4JaUghMIVStjIeHN2ks1w==
dependencies:
"@aws-sdk/nested-clients" "3.774.0"
"@aws-sdk/nested-clients" "3.758.0"
"@aws-sdk/types" "3.734.0"
"@smithy/property-provider" "^4.0.1"
"@smithy/shared-ini-file-loader" "^4.0.1"
@@ -649,12 +649,12 @@
bowser "^2.11.0"
tslib "^2.6.2"
"@aws-sdk/util-user-agent-node@3.774.0":
version "3.774.0"
resolved "https://registry.yarnpkg.com/@aws-sdk/util-user-agent-node/-/util-user-agent-node-3.774.0.tgz#9160dac000b699cbae623a95718fdcb3bf155f0b"
integrity sha512-kFmnK4sf5Wco8mkzO2PszqDXEwtQ5H896tUxqWDQhk67NtOLsHYfg98ymOBWWudth2POaldiIx6KFXtg0DvLLQ==
"@aws-sdk/util-user-agent-node@3.758.0":
version "3.758.0"
resolved "https://registry.yarnpkg.com/@aws-sdk/util-user-agent-node/-/util-user-agent-node-3.758.0.tgz#604ccb02a5d11c9cedaea0bea279641ea9d4194d"
integrity sha512-A5EZw85V6WhoKMV2hbuFRvb9NPlxEErb4HPO6/SPXYY4QrjprIzScHxikqcWv1w4J3apB1wto9LPU3IMsYtfrw==
dependencies:
"@aws-sdk/middleware-user-agent" "3.774.0"
"@aws-sdk/middleware-user-agent" "3.758.0"
"@aws-sdk/types" "3.734.0"
"@smithy/node-config-provider" "^4.0.1"
"@smithy/types" "^4.1.0"
@@ -675,10 +675,10 @@
"@smithy/types" "^4.1.0"
tslib "^2.6.2"
"@babel/cli@^7.27.0":
version "7.27.0"
resolved "https://registry.yarnpkg.com/@babel/cli/-/cli-7.27.0.tgz#076603b25fc7dd88298ea94ab249c8237c7e71cc"
integrity sha512-bZfxn8DRxwiVzDO5CEeV+7IqXeCkzI4yYnrQbpwjT76CUyossQc6RYE7n+xfm0/2k40lPaCpW0FhxYs7EBAetw==
"@babel/cli@^7.26.4":
version "7.26.4"
resolved "https://registry.yarnpkg.com/@babel/cli/-/cli-7.26.4.tgz#4101ff8ee5de8447a6c395397a97921056411d20"
integrity sha512-+mORf3ezU3p3qr+82WvJSnQNE1GAYeoCfEv4fik6B5/2cvKZ75AX8oawWQdXtM9MmndooQj15Jr9kelRFWsuRw==
dependencies:
"@jridgewell/trace-mapping" "^0.3.25"
commander "^6.2.0"
@@ -705,34 +705,34 @@
resolved "https://registry.yarnpkg.com/@babel/compat-data/-/compat-data-7.26.8.tgz#821c1d35641c355284d4a870b8a4a7b0c141e367"
integrity sha512-oH5UPLMWR3L2wEFLnFJ1TZXqHufiTKAiLfqw5zkhS4dKXLJ10yVztfil/twG8EDTA4F/tvVNw9nOl4ZMslB8rQ==
"@babel/core@^7.11.6", "@babel/core@^7.12.3", "@babel/core@^7.20.12", "@babel/core@^7.24.4", "@babel/core@^7.26.10":
version "7.26.10"
resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.26.10.tgz#5c876f83c8c4dcb233ee4b670c0606f2ac3000f9"
integrity sha512-vMqyb7XCDMPvJFFOaT9kxtiRh42GwlZEg1/uIgtZshS5a/8OaduUfCi7kynKgc3Tw/6Uo2D+db9qBttghhmxwQ==
"@babel/core@^7.11.6", "@babel/core@^7.12.3", "@babel/core@^7.20.12", "@babel/core@^7.24.4", "@babel/core@^7.26.9":
version "7.26.9"
resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.26.9.tgz#71838542a4b1e49dfed353d7acbc6eb89f4a76f2"
integrity sha512-lWBYIrF7qK5+GjY5Uy+/hEgp8OJWOD/rpy74GplYRhEauvbHDeFB8t5hPOZxCZ0Oxf4Cc36tK51/l3ymJysrKw==
dependencies:
"@ampproject/remapping" "^2.2.0"
"@babel/code-frame" "^7.26.2"
"@babel/generator" "^7.26.10"
"@babel/generator" "^7.26.9"
"@babel/helper-compilation-targets" "^7.26.5"
"@babel/helper-module-transforms" "^7.26.0"
"@babel/helpers" "^7.26.10"
"@babel/parser" "^7.26.10"
"@babel/helpers" "^7.26.9"
"@babel/parser" "^7.26.9"
"@babel/template" "^7.26.9"
"@babel/traverse" "^7.26.10"
"@babel/types" "^7.26.10"
"@babel/traverse" "^7.26.9"
"@babel/types" "^7.26.9"
convert-source-map "^2.0.0"
debug "^4.1.0"
gensync "^1.0.0-beta.2"
json5 "^2.2.3"
semver "^6.3.1"
"@babel/generator@^7.26.10", "@babel/generator@^7.27.0", "@babel/generator@^7.7.2":
version "7.27.0"
resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.27.0.tgz#764382b5392e5b9aff93cadb190d0745866cbc2c"
integrity sha512-VybsKvpiN1gU1sdMZIp7FcqphVVKEwcuj02x73uvcHE0PTihx1nlBcowYWhDwjpoAXRv43+gDzyggGnn1XZhVw==
"@babel/generator@^7.26.9", "@babel/generator@^7.7.2":
version "7.26.9"
resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.26.9.tgz#75a9482ad3d0cc7188a537aa4910bc59db67cbca"
integrity sha512-kEWdzjOAUMW4hAyrzJ0ZaTOu9OmpyDIQicIh0zg0EEcEkYXZb2TjtBhnHi2ViX7PKwZqF4xwqfAm299/QMP3lg==
dependencies:
"@babel/parser" "^7.27.0"
"@babel/types" "^7.27.0"
"@babel/parser" "^7.26.9"
"@babel/types" "^7.26.9"
"@jridgewell/gen-mapping" "^0.3.5"
"@jridgewell/trace-mapping" "^0.3.25"
jsesc "^3.0.2"
@@ -755,17 +755,17 @@
lru-cache "^5.1.1"
semver "^6.3.1"
"@babel/helper-create-class-features-plugin@^7.25.9", "@babel/helper-create-class-features-plugin@^7.27.0":
version "7.27.0"
resolved "https://registry.yarnpkg.com/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.27.0.tgz#518fad6a307c6a96f44af14912b2c20abe9bfc30"
integrity sha512-vSGCvMecvFCd/BdpGlhpXYNhhC4ccxyvQWpbGL4CWbvfEoLFWUZuSuf7s9Aw70flgQF+6vptvgK2IfOnKlRmBg==
"@babel/helper-create-class-features-plugin@^7.25.9":
version "7.25.9"
resolved "https://registry.yarnpkg.com/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.25.9.tgz#7644147706bb90ff613297d49ed5266bde729f83"
integrity sha512-UTZQMvt0d/rSz6KI+qdu7GQze5TIajwTS++GUozlw8VBJDEOAqSXwm1WvmYEZwqdqSGQshRocPDqrt4HBZB3fQ==
dependencies:
"@babel/helper-annotate-as-pure" "^7.25.9"
"@babel/helper-member-expression-to-functions" "^7.25.9"
"@babel/helper-optimise-call-expression" "^7.25.9"
"@babel/helper-replace-supers" "^7.26.5"
"@babel/helper-replace-supers" "^7.25.9"
"@babel/helper-skip-transparent-expression-wrappers" "^7.25.9"
"@babel/traverse" "^7.27.0"
"@babel/traverse" "^7.25.9"
semver "^6.3.1"
"@babel/helper-create-regexp-features-plugin@^7.18.6", "@babel/helper-create-regexp-features-plugin@^7.25.9":
@@ -848,7 +848,7 @@
"@babel/helper-wrap-function" "^7.25.9"
"@babel/traverse" "^7.25.9"
"@babel/helper-replace-supers@^7.25.9", "@babel/helper-replace-supers@^7.26.5":
"@babel/helper-replace-supers@^7.25.9":
version "7.26.5"
resolved "https://registry.yarnpkg.com/@babel/helper-replace-supers/-/helper-replace-supers-7.26.5.tgz#6cb04e82ae291dae8e72335dfe438b0725f14c8d"
integrity sha512-bJ6iIVdYX1YooY2X7w1q6VITt+LnUILtNk7zT78ykuwStx8BauCzxvFqFaHjOpW1bVnSUM1PN1f0p5P21wHxvg==
@@ -889,20 +889,20 @@
"@babel/traverse" "^7.25.9"
"@babel/types" "^7.25.9"
"@babel/helpers@^7.26.10":
version "7.27.0"
resolved "https://registry.yarnpkg.com/@babel/helpers/-/helpers-7.27.0.tgz#53d156098defa8243eab0f32fa17589075a1b808"
integrity sha512-U5eyP/CTFPuNE3qk+WZMxFkp/4zUzdceQlfzf7DdGdhp+Fezd7HD+i8Y24ZuTMKX3wQBld449jijbGq6OdGNQg==
"@babel/helpers@^7.26.9":
version "7.26.10"
resolved "https://registry.yarnpkg.com/@babel/helpers/-/helpers-7.26.10.tgz#6baea3cd62ec2d0c1068778d63cb1314f6637384"
integrity sha512-UPYc3SauzZ3JGgj87GgZ89JVdC5dj0AoetR5Bw6wj4niittNyFh6+eOGonYvJ1ao6B8lEa3Q3klS7ADZ53bc5g==
dependencies:
"@babel/template" "^7.27.0"
"@babel/types" "^7.27.0"
"@babel/template" "^7.26.9"
"@babel/types" "^7.26.10"
"@babel/parser@^7.1.0", "@babel/parser@^7.14.7", "@babel/parser@^7.26.10", "@babel/parser@^7.27.0", "@babel/parser@^7.7.0":
version "7.27.0"
resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.27.0.tgz#3d7d6ee268e41d2600091cbd4e145ffee85a44ec"
integrity sha512-iaepho73/2Pz7w2eMS0Q5f83+0RKI7i4xmiYeBmDzfRVbQtTOG7Ts0S4HzJVsTMGI9keU8rNfuZr8DKfSt7Yyg==
"@babel/parser@^7.1.0", "@babel/parser@^7.14.7", "@babel/parser@^7.26.9", "@babel/parser@^7.7.0":
version "7.26.9"
resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.26.9.tgz#d9e78bee6dc80f9efd8f2349dcfbbcdace280fd5"
integrity sha512-81NWa1njQblgZbQHxWHpxxCzNsa3ZwvFqpUg7P+NNUU6f3UU2jBEg4OlF/J6rl8+PQGh1q6/zWScd001YwcA5A==
dependencies:
"@babel/types" "^7.27.0"
"@babel/types" "^7.26.9"
"@babel/plugin-bugfix-firefox-class-in-computed-class-key@^7.25.9":
version "7.25.9"
@@ -1263,7 +1263,7 @@
"@babel/helper-module-transforms" "^7.25.9"
"@babel/helper-plugin-utils" "^7.25.9"
"@babel/plugin-transform-modules-commonjs@^7.26.3":
"@babel/plugin-transform-modules-commonjs@^7.25.9", "@babel/plugin-transform-modules-commonjs@^7.26.3":
version "7.26.3"
resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.26.3.tgz#8f011d44b20d02c3de44d8850d971d8497f981fb"
integrity sha512-MgR55l4q9KddUDITEzEFYn5ZsGDXMSsU9E+kh7fjRXTIC3RHqfCo8RPRbyReYJh44HQ/yomFkqbOFohXvDCiIQ==
@@ -1428,12 +1428,12 @@
"@babel/helper-annotate-as-pure" "^7.25.9"
"@babel/helper-plugin-utils" "^7.25.9"
"@babel/plugin-transform-regenerator@^7.25.9", "@babel/plugin-transform-regenerator@^7.27.0":
version "7.27.0"
resolved "https://registry.yarnpkg.com/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.27.0.tgz#822feebef43d6a59a81f696b2512df5b1682db31"
integrity sha512-LX/vCajUJQDqE7Aum/ELUMZAY19+cDpghxrnyt5I1tV6X5PyC86AOoWXWFYFeIvauyeSA6/ktn4tQVn/3ZifsA==
"@babel/plugin-transform-regenerator@^7.25.9":
version "7.25.9"
resolved "https://registry.yarnpkg.com/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.25.9.tgz#03a8a4670d6cebae95305ac6defac81ece77740b"
integrity sha512-vwDcDNsgMPDGP0nMqzahDWE5/MLcX8sv96+wfX7as7LoF/kr97Bo/7fI00lXY4wUXYfVmwIIyG80fGZ1uvt2qg==
dependencies:
"@babel/helper-plugin-utils" "^7.26.5"
"@babel/helper-plugin-utils" "^7.25.9"
regenerator-transform "^0.15.2"
"@babel/plugin-transform-regexp-modifiers@^7.26.0":
@@ -1499,13 +1499,13 @@
dependencies:
"@babel/helper-plugin-utils" "^7.26.5"
"@babel/plugin-transform-typescript@^7.27.0":
version "7.27.0"
resolved "https://registry.yarnpkg.com/@babel/plugin-transform-typescript/-/plugin-transform-typescript-7.27.0.tgz#a29fd3481da85601c7e34091296e9746d2cccba8"
integrity sha512-fRGGjO2UEGPjvEcyAZXRXAS8AfdaQoq7HnxAbJoAoW10B9xOKesmmndJv+Sym2a+9FHWZ9KbyyLCe9s0Sn5jtg==
"@babel/plugin-transform-typescript@^7.25.9":
version "7.26.7"
resolved "https://registry.yarnpkg.com/@babel/plugin-transform-typescript/-/plugin-transform-typescript-7.26.7.tgz#64339515ea3eff610160f62499c3ef437d0ac83d"
integrity sha512-5cJurntg+AT+cgelGP9Bt788DKiAw9gIMSMU2NJrLAilnj0m8WZWUNZPSLOmadYsujHutpgElO+50foX+ib/Wg==
dependencies:
"@babel/helper-annotate-as-pure" "^7.25.9"
"@babel/helper-create-class-features-plugin" "^7.27.0"
"@babel/helper-create-class-features-plugin" "^7.25.9"
"@babel/helper-plugin-utils" "^7.26.5"
"@babel/helper-skip-transparent-expression-wrappers" "^7.25.9"
"@babel/plugin-syntax-typescript" "^7.25.9"
@@ -1637,16 +1637,16 @@
"@babel/plugin-transform-react-jsx-development" "^7.25.9"
"@babel/plugin-transform-react-pure-annotations" "^7.25.9"
"@babel/preset-typescript@^7.27.0":
version "7.27.0"
resolved "https://registry.yarnpkg.com/@babel/preset-typescript/-/preset-typescript-7.27.0.tgz#4dcb8827225975f4290961b0b089f9c694ca50c7"
integrity sha512-vxaPFfJtHhgeOVXRKuHpHPAOgymmy8V8I65T1q53R7GCZlefKeCaTyDs3zOPHTTbmquvNlQYC5klEvWsBAtrBQ==
"@babel/preset-typescript@^7.26.0":
version "7.26.0"
resolved "https://registry.yarnpkg.com/@babel/preset-typescript/-/preset-typescript-7.26.0.tgz#4a570f1b8d104a242d923957ffa1eaff142a106d"
integrity sha512-NMk1IGZ5I/oHhoXEElcm+xUnL/szL6xflkFZmoEU9xj1qSJXpiS7rsspYo92B4DRCDvZn2erT5LdsCeXAKNCkg==
dependencies:
"@babel/helper-plugin-utils" "^7.26.5"
"@babel/helper-plugin-utils" "^7.25.9"
"@babel/helper-validator-option" "^7.25.9"
"@babel/plugin-syntax-jsx" "^7.25.9"
"@babel/plugin-transform-modules-commonjs" "^7.26.3"
"@babel/plugin-transform-typescript" "^7.27.0"
"@babel/plugin-transform-modules-commonjs" "^7.25.9"
"@babel/plugin-transform-typescript" "^7.25.9"
"@babel/runtime@^7.0.0", "@babel/runtime@^7.1.2", "@babel/runtime@^7.11.2", "@babel/runtime@^7.12.13", "@babel/runtime@^7.12.5", "@babel/runtime@^7.13.10", "@babel/runtime@^7.17.8", "@babel/runtime@^7.20.6", "@babel/runtime@^7.21.0", "@babel/runtime@^7.23.2", "@babel/runtime@^7.6.2", "@babel/runtime@^7.8.4", "@babel/runtime@^7.9.2":
version "7.26.10"
@@ -1655,32 +1655,32 @@
dependencies:
regenerator-runtime "^0.14.0"
"@babel/template@^7.25.9", "@babel/template@^7.26.9", "@babel/template@^7.27.0", "@babel/template@^7.3.3":
version "7.27.0"
resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.27.0.tgz#b253e5406cc1df1c57dcd18f11760c2dbf40c0b4"
integrity sha512-2ncevenBqXI6qRMukPlXwHKHchC7RyMuu4xv5JBXRfOGVcTy1mXCD12qrp7Jsoxll1EV3+9sE4GugBVRjT2jFA==
"@babel/template@^7.25.9", "@babel/template@^7.26.9", "@babel/template@^7.3.3":
version "7.26.9"
resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.26.9.tgz#4577ad3ddf43d194528cff4e1fa6b232fa609bb2"
integrity sha512-qyRplbeIpNZhmzOysF/wFMuP9sctmh2cFzRAZOn1YapxBsE1i9bJIY586R/WBLfLcmcBlM8ROBiQURnnNy+zfA==
dependencies:
"@babel/code-frame" "^7.26.2"
"@babel/parser" "^7.27.0"
"@babel/types" "^7.27.0"
"@babel/parser" "^7.26.9"
"@babel/types" "^7.26.9"
"@babel/traverse@^7.13.0", "@babel/traverse@^7.25.9", "@babel/traverse@^7.26.10", "@babel/traverse@^7.26.5", "@babel/traverse@^7.26.8", "@babel/traverse@^7.27.0", "@babel/traverse@^7.4.5", "@babel/traverse@^7.7.0":
version "7.27.0"
resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.27.0.tgz#11d7e644779e166c0442f9a07274d02cd91d4a70"
integrity sha512-19lYZFzYVQkkHkl4Cy4WrAVcqBkgvV2YM2TU3xG6DIwO7O3ecbDPfW3yM3bjAGcqcQHi+CCtjMR3dIEHxsd6bA==
"@babel/traverse@^7.13.0", "@babel/traverse@^7.25.9", "@babel/traverse@^7.26.5", "@babel/traverse@^7.26.8", "@babel/traverse@^7.26.9", "@babel/traverse@^7.4.5", "@babel/traverse@^7.7.0":
version "7.26.9"
resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.26.9.tgz#4398f2394ba66d05d988b2ad13c219a2c857461a"
integrity sha512-ZYW7L+pL8ahU5fXmNbPF+iZFHCv5scFak7MZ9bwaRPLUhHh7QQEMjZUg0HevihoqCM5iSYHN61EyCoZvqC+bxg==
dependencies:
"@babel/code-frame" "^7.26.2"
"@babel/generator" "^7.27.0"
"@babel/parser" "^7.27.0"
"@babel/template" "^7.27.0"
"@babel/types" "^7.27.0"
"@babel/generator" "^7.26.9"
"@babel/parser" "^7.26.9"
"@babel/template" "^7.26.9"
"@babel/types" "^7.26.9"
debug "^4.3.1"
globals "^11.1.0"
"@babel/types@^7.0.0", "@babel/types@^7.25.9", "@babel/types@^7.26.10", "@babel/types@^7.27.0", "@babel/types@^7.3.0", "@babel/types@^7.3.3", "@babel/types@^7.4.4", "@babel/types@^7.7.0":
version "7.27.0"
resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.27.0.tgz#ef9acb6b06c3173f6632d993ecb6d4ae470b4559"
integrity sha512-H45s8fVLYjbhFH62dIJ3WtmJ6RSPt/3DRO0ZcT2SUiYiQyz3BLVb9ADEnLl91m74aQPS3AzzeajZHYOalWe3bg==
"@babel/types@^7.0.0", "@babel/types@^7.25.9", "@babel/types@^7.26.10", "@babel/types@^7.26.9", "@babel/types@^7.3.0", "@babel/types@^7.3.3", "@babel/types@^7.4.4", "@babel/types@^7.7.0":
version "7.26.10"
resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.26.10.tgz#396382f6335bd4feb65741eacfc808218f859259"
integrity sha512-emqcG3vHrpxUKTrxcblR36dcrcoRDvKmnL/dCL6ZsHaShW80qxCAcNhzQZrpeM765VzEos+xOi4s+r4IXzTwdQ==
dependencies:
"@babel/helper-string-parser" "^7.25.9"
"@babel/helper-validator-identifier" "^7.25.9"
@@ -1828,10 +1828,10 @@
enabled "2.0.x"
kuler "^2.0.0"
"@datadog/datadog-api-client@^1.17.0":
version "1.33.1"
resolved "https://registry.yarnpkg.com/@datadog/datadog-api-client/-/datadog-api-client-1.33.1.tgz#7dcdc86383699c3a4d4414c1a3deacb44a6d3262"
integrity sha512-ztX1/uutcuSdRqZLlirKy8tIn1VbMjBE/oLCcNL8PsDlzztaXkjhRzX71V8LTc35iQcuv9XzjjbUfOLGhypwdw==
"@datadog/datadog-api-client@^1.16.0":
version "1.19.0"
resolved "https://registry.yarnpkg.com/@datadog/datadog-api-client/-/datadog-api-client-1.19.0.tgz#3bd7cafa2e83080a0efba836602699ea0441899b"
integrity "sha1-O9fK+i6DCAoO+6g2YCaZ6gRBiZs= sha512-tMkHo7nBFtpDP4dbT/dGIIdittGaTuA6hIY6v4vWb/f+NlJPwnJUf/gBJ9Hwz1HEmlYQMuAnpdFxIQ2P6zjujA=="
dependencies:
"@types/buffer-from" "^1.1.0"
"@types/node" "*"
@@ -1842,6 +1842,7 @@
form-data "^4.0.0"
loglevel "^1.8.1"
pako "^2.0.4"
url-parse "^1.4.3"
"@datadog/libdatadog@^0.5.0":
version "0.5.0"
@@ -5312,10 +5313,10 @@
"@types/node" "*"
form-data "^4.0.0"
"@types/node@*", "@types/node@20.17.27", "@types/node@>=10.0.0", "@types/node@>=13.7.0":
version "20.17.27"
resolved "https://registry.yarnpkg.com/@types/node/-/node-20.17.27.tgz#dbf0f9e6f905e9004045742f94e8413e20bad776"
integrity sha512-U58sbKhDrthHlxHRJw7ZLiLDZGmAUOZUbpw0S6nL27sYUdhvgBLCRu/keSd6qcTsfArd1sRFCCBxzWATGr/0UA==
"@types/node@*", "@types/node@20.17.16", "@types/node@>=10.0.0", "@types/node@>=13.7.0":
version "20.17.16"
resolved "https://registry.yarnpkg.com/@types/node/-/node-20.17.16.tgz#b33b0edc1bf925b27349e494b871ca4451fabab4"
integrity sha512-vOTpLduLkZXePLxHiHsBLp98mHGnl8RptV4YAO3HfKO5UHjDvySGbxKtpYfy8Sx5+WKcgc45qNreJJRVM3L6mw==
dependencies:
undici-types "~6.19.2"
@@ -5817,11 +5818,6 @@ agent-base@6:
dependencies:
debug "4"
agent-base@^7.1.2:
version "7.1.3"
resolved "https://registry.yarnpkg.com/agent-base/-/agent-base-7.1.3.tgz#29435eb821bc4194633a5b89e5bc4703bafc25a1"
integrity sha512-jRR5wdylq8CkOe6hei19GGZnxM6rBGwFl3Bg0YItGDimvjGtAvdZk4Pu6Cl4u4Igsws4a1fd1Vq3ezrhn4KmFw==
aggregate-error@^3.1.0:
version "3.1.0"
resolved "https://registry.yarnpkg.com/aggregate-error/-/aggregate-error-3.1.0.tgz#92670ff50f5359bdb7a3e0d40d0ec30c5737687a"
@@ -7749,12 +7745,12 @@ data-view-byte-offset@^1.0.1:
es-errors "^1.3.0"
is-data-view "^1.0.1"
datadog-metrics@^0.12.1:
version "0.12.1"
resolved "https://registry.yarnpkg.com/datadog-metrics/-/datadog-metrics-0.12.1.tgz#8d3b91d554f9149990520d05199d08975d3edb7a"
integrity sha512-Gy+17ia7m9Uy+nKQHDd7fljdq0fqqfpgkpxlwW0x1oFKI7RcgDV32pMCfHtv4HKychP6fHtncj3Lf4VN/g4G6A==
datadog-metrics@^0.11.2:
version "0.11.2"
resolved "https://registry.yarnpkg.com/datadog-metrics/-/datadog-metrics-0.11.2.tgz#3fadf376773b06da21d5527e8574f5f315aee547"
integrity sha512-gM2Yc9b0fwpsDtcE4Q573Xy0OJw0tp+vsli3ghZ4QRLGKkQtviKj6EFOxRYtFADV5opP+bIIJIclcWmaI76uvg==
dependencies:
"@datadog/datadog-api-client" "^1.17.0"
"@datadog/datadog-api-client" "^1.16.0"
debug "^4.1.0"
date-fns@^2.28.0, date-fns@^2.30.0:
@@ -9758,14 +9754,6 @@ https-proxy-agent@^5.0.1:
agent-base "6"
debug "4"
https-proxy-agent@^7.0.6:
version "7.0.6"
resolved "https://registry.yarnpkg.com/https-proxy-agent/-/https-proxy-agent-7.0.6.tgz#da8dfeac7da130b05c2ba4b59c9b6cd66611a6b9"
integrity sha512-vK9P5/iUfdl95AI+JVyUuIcVtd4ofvtrOr3HNtM2yxC9bnMbEdp3x01OhQNnjb8IJYi38VlTE3mBXwcfvywuSw==
dependencies:
agent-base "^7.1.2"
debug "4"
human-signals@^2.1.0:
version "2.1.0"
resolved "https://registry.yarnpkg.com/human-signals/-/human-signals-2.1.0.tgz#dc91fcba42e4d06e4abaed33b3e7a3c02f514ea0"
@@ -9980,10 +9968,10 @@ invariant@^2.2.2, invariant@^2.2.4:
dependencies:
loose-envify "^1.0.0"
ioredis@^5.3.2, ioredis@^5.6.0:
version "5.6.0"
resolved "https://registry.yarnpkg.com/ioredis/-/ioredis-5.6.0.tgz#faa2a27132f8a05c0ddfef400b01d1326df211a0"
integrity sha512-tBZlIIWbndeWBWCXWZiqtOF/yxf6yZX3tAlTJ7nfo5jhd6dctNxF7QnYlZLZ1a0o0pDoen7CgZqO+zjNaFbJAg==
ioredis@^5.3.2, ioredis@^5.4.1:
version "5.4.1"
resolved "https://registry.yarnpkg.com/ioredis/-/ioredis-5.4.1.tgz#1c56b70b759f01465913887375ed809134296f40"
integrity sha512-2YZsvl7jopIa1gaePkeMtd9rAcSjOOjPtpcLlOeusyO+XH2SK5ZcT+UCrElPP+WVIInh2TzeI4XW9ENaSLVVHA==
dependencies:
"@ioredis/commands" "^1.1.1"
cluster-key-slot "^1.1.0"
@@ -12742,25 +12730,25 @@ pg-cloudflare@^1.1.1:
resolved "https://registry.yarnpkg.com/pg-cloudflare/-/pg-cloudflare-1.1.1.tgz#e6d5833015b170e23ae819e8c5d7eaedb472ca98"
integrity "sha1-5tWDMBWxcOI66Bnoxdfq7bRyypg= sha512-xWPagP/4B6BgFO+EKz3JONXv3YDgvkbVrGw2mTo3D6tVDQRh1e7cqVGvyR3BE+eQgAvx1XhW/iEASj4/jCWl3Q=="
pg-connection-string@^2.6.1, pg-connection-string@^2.7.0:
version "2.7.0"
resolved "https://registry.yarnpkg.com/pg-connection-string/-/pg-connection-string-2.7.0.tgz#f1d3489e427c62ece022dba98d5262efcb168b37"
integrity sha512-PI2W9mv53rXJQEOb8xNR8lH7Hr+EKa6oJa38zsK0S/ky2er16ios1wLKhZyxzD7jUReiWokc9WK5nxSnC7W1TA==
pg-connection-string@^2.6.1, pg-connection-string@^2.6.4:
version "2.6.4"
resolved "https://registry.yarnpkg.com/pg-connection-string/-/pg-connection-string-2.6.4.tgz#f543862adfa49fa4e14bc8a8892d2a84d754246d"
integrity sha512-v+Z7W/0EO707aNMaAEfiGnGL9sxxumwLl2fJvCQtMn9Fxsg+lPpPkdcyBSv/KFgpGdYkMfn+EI1Or2EHjpgLCA==
pg-int8@1.0.1:
version "1.0.1"
resolved "https://registry.yarnpkg.com/pg-int8/-/pg-int8-1.0.1.tgz#943bd463bf5b71b4170115f80f8efc9a0c0eb78c"
integrity "sha1-lDvUY79bcbQXARX4D478mgwOt4w= sha512-WCtabS6t3c8SkpDBUlb1kjOs7l66xsGdKpIPZsg4wR+B3+u9UAum2odSsF9tnvxg80h4ZxLWMy4pRjOsFIqQpw=="
pg-pool@^3.8.0:
version "3.8.0"
resolved "https://registry.yarnpkg.com/pg-pool/-/pg-pool-3.8.0.tgz#e6bce7fc4506a8d6106551363fc5283e5445b776"
integrity sha512-VBw3jiVm6ZOdLBTIcXLNdSotb6Iy3uOCwDGFAksZCXmi10nyRvnP2v3jl4d+IsLYRyXf6o9hIm/ZtUzlByNUdw==
pg-pool@^3.6.2:
version "3.6.2"
resolved "https://registry.yarnpkg.com/pg-pool/-/pg-pool-3.6.2.tgz#3a592370b8ae3f02a7c8130d245bc02fa2c5f3f2"
integrity sha512-Htjbg8BlwXqSBQ9V8Vjtc+vzf/6fVUuak/3/XXKA9oxZprwW3IMDQTGHP+KDmVL7rtd+R1QjbnCFPuTHm3G4hg==
pg-protocol@^1.8.0:
version "1.8.0"
resolved "https://registry.yarnpkg.com/pg-protocol/-/pg-protocol-1.8.0.tgz#c707101dd07813868035a44571488e4b98639d48"
integrity sha512-jvuYlEkL03NRvOoyoRktBK7+qU5kOvlAwvmrH8sr3wbLrOdVWsRxQfz8mMy9sZFsqJ1hEWNfdWKI4SAmoL+j7g==
pg-protocol@^1.6.1:
version "1.6.1"
resolved "https://registry.yarnpkg.com/pg-protocol/-/pg-protocol-1.6.1.tgz#21333e6d83b01faaebfe7a33a7ad6bfd9ed38cb3"
integrity sha512-jPIlvgoD63hrEuihvIg+tJhoGjUsLPn6poJY9N5CnlPd91c2T18T/9zBtLxZSb1EhYxBRoZJtzScCaWlYLtktg==
pg-tsquery@^8.4.2:
version "8.4.2"
@@ -12778,14 +12766,14 @@ pg-types@^2.1.0:
postgres-date "~1.0.4"
postgres-interval "^1.1.0"
pg@^8.14.1:
version "8.14.1"
resolved "https://registry.yarnpkg.com/pg/-/pg-8.14.1.tgz#2e3d1f287b64797cdfc8d1ba000f61a7ff8d66ed"
integrity sha512-0TdbqfjwIun9Fm/r89oB7RFQ0bLgduAhiIqIXOsyKoiC/L54DbuAAzIEN/9Op0f1Po9X7iCPXGoa/Ah+2aI8Xw==
pg@^8.12.0:
version "8.12.0"
resolved "https://registry.yarnpkg.com/pg/-/pg-8.12.0.tgz#9341724db571022490b657908f65aee8db91df79"
integrity sha512-A+LHUSnwnxrnL/tZ+OLfqR1SxLN3c/pgDztZ47Rpbsd4jUytsTtwQo/TLPRzPJMp/1pbhYVhH9cuSZLAajNfjQ==
dependencies:
pg-connection-string "^2.7.0"
pg-pool "^3.8.0"
pg-protocol "^1.8.0"
pg-connection-string "^2.6.4"
pg-pool "^3.6.2"
pg-protocol "^1.6.1"
pg-types "^2.1.0"
pgpass "1.x"
optionalDependencies:
@@ -13062,10 +13050,10 @@ prosemirror-codemark@^0.4.2:
resolved "https://registry.yarnpkg.com/prosemirror-codemark/-/prosemirror-codemark-0.4.2.tgz#b4d0a57c0f1f6c6667e2a1ae7cfb6ba031dfb2e5"
integrity "sha1-tNClfA8fbGZn4qGufPtroDHfsuU= sha512-4n+PnGQToa/vTjn0OiivUvE8/moLtguUAfry8UA4Q8p47MhqT2Qpf2zBLustX5Upi4mSp3z1ZYBqLLovZC6abA=="
prosemirror-commands@^1.7.0:
version "1.7.0"
resolved "https://registry.yarnpkg.com/prosemirror-commands/-/prosemirror-commands-1.7.0.tgz#c0a60c808f51157caa146922494fc59fe257f27c"
integrity sha512-6toodS4R/Aah5pdsrIwnTYPEjW70SlO5a66oo5Kk+CIrgJz3ukOoS+FYDGqvQlAX5PxoGWDX1oD++tn5X3pyRA==
prosemirror-commands@^1.6.2:
version "1.6.2"
resolved "https://registry.yarnpkg.com/prosemirror-commands/-/prosemirror-commands-1.6.2.tgz#d9cf6654912442cff47daa1677eb43ebd0b1f117"
integrity sha512-0nDHH++qcf/BuPLYvmqZTUUsPJUCPBUXt0J1ErTcDIS369CTp773itzLGIgIXG4LJXOlwYCr44+Mh4ii6MP1QA==
dependencies:
prosemirror-model "^1.0.0"
prosemirror-state "^1.0.0"
@@ -13203,7 +13191,7 @@ protobufjs@^7.2.5:
proxy-from-env@^1.1.0:
version "1.1.0"
resolved "https://registry.yarnpkg.com/proxy-from-env/-/proxy-from-env-1.1.0.tgz#e102f16ca355424865755d2c9e8ea4f24d58c3e2"
integrity sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==
integrity "sha1-4QLxbKNVQkhldV0sno6k8k1Yw+I= sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg=="
pseudomap@^1.0.2:
version "1.0.2"
@@ -13920,17 +13908,17 @@ rollup-plugin-node-resolve@^3.0.0:
is-module "^1.0.0"
resolve "^1.1.6"
rollup-plugin-stats@1.3.4:
version "1.3.4"
resolved "https://registry.yarnpkg.com/rollup-plugin-stats/-/rollup-plugin-stats-1.3.4.tgz#772f147bb195f7bd77877b95a7e0baf801aeaf94"
integrity sha512-N6PCNucOrRJxqzeAvpEyK9Wf4bxQlCCuIj5+n0XUB0plFU0u1VwjY0GDM6Z3lvs/KDhzJ2anYwxXUZVfmFw8LA==
rollup-plugin-stats@1.3.2:
version "1.3.2"
resolved "https://registry.yarnpkg.com/rollup-plugin-stats/-/rollup-plugin-stats-1.3.2.tgz#4dd088465cff3c00688e388787e240dff20aeed8"
integrity sha512-VVCNU//OBzroB73gPmGJIm6xkoi25t2MsPoV6LsWUt4BVXbnrKpYAY3CwwnAfiWzM2KL4PN3SeFe/jZ9Ky7WRQ==
rollup-plugin-webpack-stats@^2.0.3:
version "2.0.3"
resolved "https://registry.yarnpkg.com/rollup-plugin-webpack-stats/-/rollup-plugin-webpack-stats-2.0.3.tgz#918dc46aa652a731bb62239c894e487bf8e5365a"
integrity sha512-tJJaYkP3yQctWRoAn7zh47DszOpwXVaDDmxriu48cohi7Nv/87l8Ry0vHnUd8e9MbpXuKZwEGQjqk1BjYLbYww==
rollup-plugin-webpack-stats@^2.0.1:
version "2.0.1"
resolved "https://registry.yarnpkg.com/rollup-plugin-webpack-stats/-/rollup-plugin-webpack-stats-2.0.1.tgz#0ca7913227fc42db34ae51a74fa6742a6e8f5a1e"
integrity sha512-1JALgjz4RDe14SowXJxAsQqJxGnj6JF4TIRo0FistxspFr3TyYIWCpO8B5qaes7vfdKxSNTowJtuQTOlZOobMA==
dependencies:
rollup-plugin-stats "1.3.4"
rollup-plugin-stats "1.3.2"
rollup@^0.41.4, rollup@^2.43.1, rollup@^4.20.0, rollup@^4.5.1:
version "4.5.1"
@@ -15150,7 +15138,7 @@ ttl-set@^1.0.0:
tunnel-agent@^0.6.0:
version "0.6.0"
resolved "https://registry.yarnpkg.com/tunnel-agent/-/tunnel-agent-0.6.0.tgz#27a5dea06b36b04a0a9966774b290868f0fc40fd"
integrity sha512-McnNiV1l8RYeY8tBgEpuodCC1mLUdbSN+CYBL7kJsJNInOP8UjDDEwdk6Mw60vdLLrr5NHKZhMAOSrR2NZuQ+w==
integrity "sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0= sha512-McnNiV1l8RYeY8tBgEpuodCC1mLUdbSN+CYBL7kJsJNInOP8UjDDEwdk6Mw60vdLLrr5NHKZhMAOSrR2NZuQ+w=="
dependencies:
safe-buffer "^5.0.1"
@@ -15442,7 +15430,7 @@ urijs@^1.19.0:
resolved "https://registry.yarnpkg.com/urijs/-/urijs-1.19.11.tgz#204b0d6b605ae80bea54bea39280cdb7c9f923cc"
integrity "sha1-IEsNa2Ba6AvqVL6jkoDNt8n5I8w= sha512-HXgFDgDommxn5/bIv0cnQZsPhHDA90NPHD6+c/v21U5+Sx5hoP8+dP9IZXBU1gIfvdRfhG8cel9QNPeionfcCQ=="
url-parse@^1.5.3:
url-parse@^1.4.3, url-parse@^1.5.3:
version "1.5.10"
resolved "https://registry.yarnpkg.com/url-parse/-/url-parse-1.5.10.tgz#9d3c2f736c1d75dd3bd2be507dcc111f1e2ea9c1"
integrity "sha1-nTwvc2wddd070r5QfcwRHx4uqcE= sha512-WypcfiRhfeUP9vvF0j6rw0J3hrWrw6iZv3+22h6iRMJ/8z1Tj6XfLP4DsUix5MhMPnXpiHDoKyoZ/bdCkwBCiQ=="
@@ -15615,10 +15603,10 @@ vite-plugin-static-copy@^0.17.0:
fs-extra "^11.1.0"
picocolors "^1.0.0"
vite@^5.4.15:
version "5.4.15"
resolved "https://registry.yarnpkg.com/vite/-/vite-5.4.15.tgz#2941547f10ebb4bf9b0fa0da863c06711eb7e5e5"
integrity sha512-6ANcZRivqL/4WtwPGTKNaosuNJr5tWiftOC7liM7G9+rMb8+oeJeyzymDu4rTN93seySBmbjSfsS3Vzr19KNtA==
vite@^5.4.14:
version "5.4.14"
resolved "https://registry.yarnpkg.com/vite/-/vite-5.4.14.tgz#ff8255edb02134df180dcfca1916c37a6abe8408"
integrity sha512-EK5cY7Q1D8JNhSaPKVK4pwBFvaTmZxEnoKXLG/U9gmdDcihQGNzFlgIvaxezFR4glP1LsuiedwMBqCXH3wZccA==
dependencies:
esbuild "^0.21.3"
postcss "^8.4.43"
@@ -16226,7 +16214,7 @@ yocto-queue@^0.1.0:
resolved "https://registry.yarnpkg.com/yocto-queue/-/yocto-queue-0.1.0.tgz#0294eb3dee05028d31ee1a5fa2c556a6aaf10a1b"
integrity "sha1-ApTrPe4FAo0x7hpfosVWpqrxChs= sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q=="
zod@^3.19.1, zod@^3.24.2:
version "3.24.2"
resolved "https://registry.yarnpkg.com/zod/-/zod-3.24.2.tgz#8efa74126287c675e92f46871cfc8d15c34372b3"
integrity sha512-lY7CDW43ECgW9u1TcT3IoXHflywfVqDYze4waEz812jR/bZ8FHDsl7pFQoSZTz5N+2NqRXs8GBwnAwo3ZNxqhQ==
zod@^3.19.1, zod@^3.23.8:
version "3.23.8"
resolved "https://registry.yarnpkg.com/zod/-/zod-3.23.8.tgz#e37b957b5d52079769fb8097099b592f0ef4067d"
integrity sha512-XBx9AXhXktjUqnepgTiE5flcKIYWi/rme0Eaj+5Y0lftuGBq+jyRu/md4WnuxqgP1ubdpNCsYEYPxrzVHD8d6g==