mirror of
https://github.com/formbricks/formbricks.git
synced 2026-04-20 19:30:41 -05:00
perf: decouple constants from zod and add bundle analyzer (#7101)
This commit is contained in:
@@ -62,3 +62,4 @@ branch.json
|
||||
packages/ios/FormbricksSDK/FormbricksSDK.xcodeproj/project.xcworkspace/xcuserdata
|
||||
.cursorrules
|
||||
i18n.cache
|
||||
stats.html
|
||||
|
||||
@@ -28,6 +28,7 @@
|
||||
"scripts": {
|
||||
"dev": "vite build --watch --mode dev",
|
||||
"build": "tsc && vite build",
|
||||
"build:analyze": "tsc && ANALYZE=true vite build",
|
||||
"build:dev": "tsc && vite build --mode dev",
|
||||
"go": "vite build --watch --mode dev",
|
||||
"lint": "eslint src --fix --ext .ts,.js,.tsx,.jsx",
|
||||
@@ -58,6 +59,7 @@
|
||||
"autoprefixer": "10.4.21",
|
||||
"concurrently": "9.1.2",
|
||||
"postcss": "8.5.3",
|
||||
"rollup-plugin-visualizer": "6.0.5",
|
||||
"tailwindcss": "4.1.17",
|
||||
"terser": "5.39.1",
|
||||
"vite": "6.4.1",
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
import { useState } from "preact/hooks";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { OpenText } from "@formbricks/survey-ui";
|
||||
import { ZEmail, ZUrl } from "@formbricks/types/common";
|
||||
import { type TResponseData, type TResponseTtc } from "@formbricks/types/responses";
|
||||
import type { TSurveyOpenTextElement } from "@formbricks/types/surveys/elements";
|
||||
import { getLocalizedValue } from "@/lib/i18n";
|
||||
import { getUpdatedTtc, useTtc } from "@/lib/ttc";
|
||||
import { validateEmail, validatePhone, validateUrl } from "@/lib/validation";
|
||||
|
||||
interface OpenTextElementProps {
|
||||
element: TSurveyOpenTextElement;
|
||||
@@ -50,27 +50,24 @@ export function OpenTextElement({
|
||||
return true;
|
||||
};
|
||||
|
||||
const validateEmail = (): boolean => {
|
||||
if (!ZEmail.safeParse(value).success) {
|
||||
const checkEmail = (): boolean => {
|
||||
if (!validateEmail(value)) {
|
||||
setErrorMessage(t("errors.please_enter_a_valid_email_address"));
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
};
|
||||
|
||||
const validateUrl = (): boolean => {
|
||||
if (!ZUrl.safeParse(value).success) {
|
||||
const checkUrl = (): boolean => {
|
||||
if (!validateUrl(value)) {
|
||||
setErrorMessage(t("errors.please_enter_a_valid_url"));
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
};
|
||||
|
||||
const validatePhone = (): boolean => {
|
||||
// Match the same pattern: must start with digit or +, end with digit
|
||||
// Allows digits, +, -, and spaces in between
|
||||
const phoneRegex = /^[0-9+][0-9+\- ]*[0-9]$/;
|
||||
if (!phoneRegex.test(value)) {
|
||||
const checkPhone = (): boolean => {
|
||||
if (!validatePhone(value)) {
|
||||
setErrorMessage(t("errors.please_enter_a_valid_phone_number"));
|
||||
return false;
|
||||
}
|
||||
@@ -81,13 +78,13 @@ export function OpenTextElement({
|
||||
if (!value || value.trim() === "") return true;
|
||||
|
||||
if (element.inputType === "email") {
|
||||
return validateEmail();
|
||||
return checkEmail();
|
||||
}
|
||||
if (element.inputType === "url") {
|
||||
return validateUrl();
|
||||
return checkUrl();
|
||||
}
|
||||
if (element.inputType === "phone") {
|
||||
return validatePhone();
|
||||
return checkPhone();
|
||||
}
|
||||
return true;
|
||||
};
|
||||
|
||||
@@ -2,12 +2,12 @@ import { useEffect, useRef, useState } from "preact/hooks";
|
||||
import { type TJsFileUploadParams } from "@formbricks/types/js";
|
||||
import { type TResponseData, TResponseDataValue, type TResponseTtc } from "@formbricks/types/responses";
|
||||
import { type TUploadFileConfig } from "@formbricks/types/storage";
|
||||
import { TSurveyBlock } from "@formbricks/types/surveys/blocks";
|
||||
import { type TSurveyBlock } from "@formbricks/types/surveys/blocks";
|
||||
import { TSurveyElementTypeEnum } from "@formbricks/types/surveys/constants";
|
||||
import {
|
||||
TSurveyElement,
|
||||
TSurveyElementTypeEnum,
|
||||
TSurveyMatrixElement,
|
||||
TSurveyRankingElement,
|
||||
type TSurveyElement,
|
||||
type TSurveyMatrixElement,
|
||||
type TSurveyRankingElement,
|
||||
} from "@formbricks/types/surveys/elements";
|
||||
import { BackButton } from "@/components/buttons/back-button";
|
||||
import { SubmitButton } from "@/components/buttons/submit-button";
|
||||
|
||||
@@ -2,11 +2,8 @@ import { useEffect, useRef } from "preact/hooks";
|
||||
import { type TJsFileUploadParams } from "@formbricks/types/js";
|
||||
import { type TResponseData, type TResponseDataValue, type TResponseTtc } from "@formbricks/types/responses";
|
||||
import { type TUploadFileConfig } from "@formbricks/types/storage";
|
||||
import {
|
||||
TSurveyElement,
|
||||
TSurveyElementChoice,
|
||||
TSurveyElementTypeEnum,
|
||||
} from "@formbricks/types/surveys/elements";
|
||||
import { TSurveyElementTypeEnum } from "@formbricks/types/surveys/constants";
|
||||
import { type TSurveyElement, type TSurveyElementChoice } from "@formbricks/types/surveys/elements";
|
||||
import { AddressElement } from "@/components/elements/address-element";
|
||||
import { CalElement } from "@/components/elements/cal-element";
|
||||
import { ConsentElement } from "@/components/elements/consent-element";
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
import { describe, expect, test, vi } from "vitest";
|
||||
import { TJsEnvironmentStateSurvey } from "@formbricks/types/js";
|
||||
import { TResponseData, TResponseVariables } from "@formbricks/types/responses";
|
||||
import { TSurveyBlockLogicAction } from "@formbricks/types/surveys/blocks";
|
||||
import { TSurveyElementTypeEnum } from "@formbricks/types/surveys/elements";
|
||||
import { TConditionGroup, TSingleCondition } from "@formbricks/types/surveys/logic";
|
||||
import { TSurveyVariable } from "@formbricks/types/surveys/types";
|
||||
import { type TJsEnvironmentStateSurvey } from "@formbricks/types/js";
|
||||
import { type TResponseData, type TResponseVariables } from "@formbricks/types/responses";
|
||||
import { type TSurveyBlockLogicAction } from "@formbricks/types/surveys/blocks";
|
||||
import { TSurveyElementTypeEnum } from "@formbricks/types/surveys/constants";
|
||||
import { type TConditionGroup, type TSingleCondition } from "@formbricks/types/surveys/logic";
|
||||
import { type TSurveyVariable } from "@formbricks/types/surveys/types";
|
||||
import { evaluateLogic, isConditionGroup, performActions } from "./logic";
|
||||
|
||||
// Mock the imported function
|
||||
|
||||
@@ -1,9 +1,10 @@
|
||||
import { TJsEnvironmentStateSurvey } from "@formbricks/types/js";
|
||||
import { TResponseData, TResponseVariables } from "@formbricks/types/responses";
|
||||
import { TActionCalculate, TSurveyBlockLogicAction } from "@formbricks/types/surveys/blocks";
|
||||
import { TSurveyElement, TSurveyElementTypeEnum } from "@formbricks/types/surveys/elements";
|
||||
import { TConditionGroup, TSingleCondition } from "@formbricks/types/surveys/logic";
|
||||
import { TSurveyVariable } from "@formbricks/types/surveys/types";
|
||||
import { type TJsEnvironmentStateSurvey } from "@formbricks/types/js";
|
||||
import { type TResponseData, type TResponseVariables } from "@formbricks/types/responses";
|
||||
import { type TActionCalculate, type TSurveyBlockLogicAction } from "@formbricks/types/surveys/blocks";
|
||||
import { TSurveyElementTypeEnum } from "@formbricks/types/surveys/constants";
|
||||
import type { TSurveyElement } from "@formbricks/types/surveys/elements";
|
||||
import { type TConditionGroup, type TSingleCondition } from "@formbricks/types/surveys/logic";
|
||||
import { type TSurveyVariable } from "@formbricks/types/surveys/types";
|
||||
import { getLocalizedValue } from "@/lib/i18n";
|
||||
import { getElementsFromSurveyBlocks } from "./utils";
|
||||
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import { describe, expect, test, vi } from "vitest";
|
||||
import { type TResponseData, type TResponseVariables } from "@formbricks/types/responses";
|
||||
import { TSurveyElementTypeEnum, type TSurveyOpenTextElement } from "@formbricks/types/surveys/elements";
|
||||
import { TSurveyElementTypeEnum } from "@formbricks/types/surveys/constants";
|
||||
import { type TSurveyOpenTextElement } from "@formbricks/types/surveys/elements";
|
||||
import { parseRecallInformation, replaceRecallInfo } from "./recall";
|
||||
|
||||
// Mock getLocalizedValue (assuming path and simple behavior)
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import { type TResponseData, type TResponseVariables } from "@formbricks/types/responses";
|
||||
import { TSurveyElement, TSurveyElementTypeEnum } from "@formbricks/types/surveys/elements";
|
||||
import { TSurveyElementTypeEnum } from "@formbricks/types/surveys/constants";
|
||||
import { type TSurveyElement } from "@formbricks/types/surveys/elements";
|
||||
import { formatDateWithOrdinal, isValidDateString } from "@/lib/date-time";
|
||||
import { getLocalizedValue } from "@/lib/i18n";
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { beforeEach, describe, expect, test, vi } from "vitest";
|
||||
import { TSurveyElementTypeEnum } from "@formbricks/types/surveys/constants";
|
||||
import type { TJsEnvironmentStateSurvey } from "../../../types/js";
|
||||
import { type TAllowedFileExtension, mimeTypes } from "../../../types/storage";
|
||||
import { TSurveyElementTypeEnum } from "../../../types/surveys/elements";
|
||||
import type { TSurveyLanguage } from "../../../types/surveys/types";
|
||||
import {
|
||||
findBlockByElementId,
|
||||
|
||||
@@ -1,9 +1,13 @@
|
||||
import { type Result, err, ok, wrapThrowsAsync } from "@formbricks/types/error-handlers";
|
||||
import { type ApiErrorResponse } from "@formbricks/types/errors";
|
||||
import { type TJsEnvironmentStateSurvey } from "@formbricks/types/js";
|
||||
import { TAllowedFileExtension, mimeTypes } from "@formbricks/types/storage";
|
||||
import { TSurveyBlock, TSurveyBlockLogic, TSurveyBlockLogicAction } from "@formbricks/types/surveys/blocks";
|
||||
import { type TSurveyElement, TSurveyElementChoice } from "@formbricks/types/surveys/elements";
|
||||
import { type TAllowedFileExtension } from "@formbricks/types/storage";
|
||||
import {
|
||||
type TSurveyBlock,
|
||||
type TSurveyBlockLogic,
|
||||
type TSurveyBlockLogicAction,
|
||||
} from "@formbricks/types/surveys/blocks";
|
||||
import { type TSurveyElement, type TSurveyElementChoice } from "@formbricks/types/surveys/elements";
|
||||
import { type TShuffleOption } from "@formbricks/types/surveys/types";
|
||||
import { ApiResponse, ApiSuccessResponse } from "@/types/api";
|
||||
|
||||
@@ -177,7 +181,36 @@ export const getDefaultLanguageCode = (survey: TJsEnvironmentStateSurvey): strin
|
||||
if (defaultSurveyLanguage) return defaultSurveyLanguage.language.code;
|
||||
};
|
||||
|
||||
// Function to convert file extension to its MIME type
|
||||
// Inlined from @formbricks/types/storage.ts to avoid Zod dependency
|
||||
const mimeTypes: Record<string, string> = {
|
||||
heic: "image/heic",
|
||||
png: "image/png",
|
||||
jpeg: "image/jpeg",
|
||||
jpg: "image/jpeg",
|
||||
webp: "image/webp",
|
||||
ico: "image/x-icon",
|
||||
pdf: "application/pdf",
|
||||
eml: "message/rfc822",
|
||||
doc: "application/msword",
|
||||
docx: "application/vnd.openxmlformats-officedocument.wordprocessingml.document",
|
||||
xls: "application/vnd.ms-excel",
|
||||
xlsx: "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
|
||||
ppt: "application/vnd.ms-powerpoint",
|
||||
pptx: "application/vnd.openxmlformats-officedocument.presentationml.presentation",
|
||||
txt: "text/plain",
|
||||
csv: "text/csv",
|
||||
mp4: "video/mp4",
|
||||
mov: "video/quicktime",
|
||||
avi: "video/x-msvideo",
|
||||
mkv: "video/x-matroska",
|
||||
webm: "video/webm",
|
||||
zip: "application/zip",
|
||||
rar: "application/vnd.rar",
|
||||
"7z": "application/x-7z-compressed",
|
||||
tar: "application/x-tar",
|
||||
mp3: "audio/mpeg",
|
||||
};
|
||||
|
||||
export const getMimeType = (extension: TAllowedFileExtension): string => mimeTypes[extension];
|
||||
|
||||
/**
|
||||
|
||||
@@ -0,0 +1,79 @@
|
||||
import { describe, expect, it } from "vitest";
|
||||
import { z } from "zod";
|
||||
// Used for parity check in tests only
|
||||
import { validateEmail, validatePhone, validateUrl } from "./validation";
|
||||
|
||||
describe("Validation Logic Parity", () => {
|
||||
describe("Email Validation", () => {
|
||||
const zodEmail = z.string().email();
|
||||
|
||||
const testCases = [
|
||||
"test@example.com",
|
||||
"user.name+tag@example.co.uk",
|
||||
"invalid-email",
|
||||
"no-at-sign.com",
|
||||
"@domain.com",
|
||||
"user@",
|
||||
"user@domain", // Zod might accept this or not depending on TLD requirement. Our regex requires TLD {2,}.
|
||||
"user@domain.c", // Our regex requires 2 chars TLD.
|
||||
];
|
||||
|
||||
testCases.forEach((email) => {
|
||||
it(`should match Zod behavior for email: "${email}"`, () => {
|
||||
const zodResult = zodEmail.safeParse(email).success;
|
||||
const myResult = validateEmail(email);
|
||||
|
||||
// We aim for parity with Zod's default email validator.
|
||||
// Our custom ReDoS-safe regex handles standard email formats correctly.
|
||||
expect(myResult).toBe(zodResult);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe("URL Validation", () => {
|
||||
const zodUrl = z.string().url();
|
||||
|
||||
const testCases = [
|
||||
"https://example.com",
|
||||
"http://localhost:3000",
|
||||
"ftp://files.com",
|
||||
"invalid-url",
|
||||
"examples",
|
||||
"https://",
|
||||
];
|
||||
|
||||
testCases.forEach((url) => {
|
||||
it(`should match Zod behavior for URL: "${url}"`, () => {
|
||||
const zodResult = zodUrl.safeParse(url).success;
|
||||
const myResult = validateUrl(url);
|
||||
|
||||
if (zodResult) {
|
||||
expect(myResult).toBe(true);
|
||||
} else {
|
||||
expect(myResult).toBe(false);
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
// Note: Phone validation in the component used a custom regex, not Zod's default.
|
||||
// The original component code had: const phoneRegex = /^[0-9+][0-9+\- ]*[0-9]$/;
|
||||
// So we just test that function directly.
|
||||
describe("Phone Validation", () => {
|
||||
const testCases = [
|
||||
{ input: "+1234567890", expected: true },
|
||||
{ input: "123-456-7890", expected: true },
|
||||
{ input: "123 456 7890", expected: true },
|
||||
{ input: "invalid", expected: false },
|
||||
{ input: "123-", expected: false }, // ends with separator
|
||||
{ input: "-123", expected: false }, // starts with separator
|
||||
{ input: "+", expected: false },
|
||||
];
|
||||
|
||||
testCases.forEach(({ input, expected }) => {
|
||||
it(`should validate phone "${input}" as ${expected}`, () => {
|
||||
expect(validatePhone(input)).toBe(expected);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,24 @@
|
||||
export const validateEmail = (email: string): boolean => {
|
||||
// ReDoS-safe email validation regex that closely matches Zod's/HTML5's permissive behavior.
|
||||
// This avoids "super-linear runtime" warnings by sticking to specific allowed characters
|
||||
// rather than negated character classes where possible, and avoiding nested quantifiers.
|
||||
const emailRegex = /^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$/;
|
||||
return emailRegex.test(email);
|
||||
};
|
||||
|
||||
export const validateUrl = (url: string): boolean => {
|
||||
try {
|
||||
// Use URL constructor for validation
|
||||
new URL(url);
|
||||
return true;
|
||||
} catch {
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
export const validatePhone = (phone: string): boolean => {
|
||||
// Match the same pattern: must start with digit or +, end with digit
|
||||
// ReDoS safe: Avoids nested repetition.
|
||||
const phoneRegex = /^[0-9+][0-9+\- ]*[0-9]$/;
|
||||
return phoneRegex.test(phone);
|
||||
};
|
||||
@@ -6,6 +6,7 @@ import dts from "vite-plugin-dts";
|
||||
import tsconfigPaths from "vite-tsconfig-paths";
|
||||
import { defineConfig } from "vitest/config";
|
||||
import { copyCompiledAssetsPlugin } from "../vite-plugins/copy-compiled-assets";
|
||||
import { visualizer } from "rollup-plugin-visualizer";
|
||||
|
||||
const __filename = fileURLToPath(import.meta.url);
|
||||
const __dirname = dirname(__filename);
|
||||
@@ -74,6 +75,7 @@ const config = ({ mode }) => {
|
||||
dts({ rollupTypes: true }),
|
||||
tsconfigPaths(),
|
||||
copyCompiledAssetsPlugin({ filename: "surveys", distDir: resolve(__dirname, "dist") }),
|
||||
process.env.ANALYZE === "true" && visualizer({ filename: resolve(__dirname, "stats.html"), open: false, gzipSize: true, brotliSize: true }),
|
||||
],
|
||||
});
|
||||
};
|
||||
|
||||
@@ -0,0 +1,18 @@
|
||||
// Element Type Enum (same as question types)
|
||||
export enum TSurveyElementTypeEnum {
|
||||
FileUpload = "fileUpload",
|
||||
OpenText = "openText",
|
||||
MultipleChoiceSingle = "multipleChoiceSingle",
|
||||
MultipleChoiceMulti = "multipleChoiceMulti",
|
||||
NPS = "nps",
|
||||
CTA = "cta",
|
||||
Rating = "rating",
|
||||
Consent = "consent",
|
||||
PictureSelection = "pictureSelection",
|
||||
Cal = "cal",
|
||||
Date = "date",
|
||||
Matrix = "matrix",
|
||||
Address = "address",
|
||||
Ranking = "ranking",
|
||||
ContactInfo = "contactInfo",
|
||||
}
|
||||
@@ -2,26 +2,19 @@ import { z } from "zod";
|
||||
import { ZUrl } from "../common";
|
||||
import { ZI18nString } from "../i18n";
|
||||
import { ZAllowedFileExtension } from "../storage";
|
||||
import { TSurveyElementTypeEnum } from "./constants";
|
||||
import { FORBIDDEN_IDS } from "./validation";
|
||||
|
||||
// Element Type Enum (same as question types)
|
||||
export enum TSurveyElementTypeEnum {
|
||||
FileUpload = "fileUpload",
|
||||
OpenText = "openText",
|
||||
MultipleChoiceSingle = "multipleChoiceSingle",
|
||||
MultipleChoiceMulti = "multipleChoiceMulti",
|
||||
NPS = "nps",
|
||||
CTA = "cta",
|
||||
Rating = "rating",
|
||||
Consent = "consent",
|
||||
PictureSelection = "pictureSelection",
|
||||
Cal = "cal",
|
||||
Date = "date",
|
||||
Matrix = "matrix",
|
||||
Address = "address",
|
||||
Ranking = "ranking",
|
||||
ContactInfo = "contactInfo",
|
||||
}
|
||||
/**
|
||||
* RE-EXPORTING FOR BACKWARDS COMPATIBILITY AND CONVENIENCE
|
||||
*
|
||||
* TSurveyElementTypeEnum is defined in `constants.ts` to avoid circular dependencies
|
||||
* and ensure that the Zod library is not included in bundles that only need the Enum value.
|
||||
*
|
||||
* However, we re-export it here so that most consumers (who also need the Zod schemas)
|
||||
* can import everything from a single file (`elements.ts`).
|
||||
*/
|
||||
export { TSurveyElementTypeEnum };
|
||||
|
||||
// Element ID validation (same rules as questions - USER EDITABLE)
|
||||
export const ZSurveyElementId = z.string().superRefine((id, ctx) => {
|
||||
|
||||
@@ -3190,7 +3190,7 @@ const validateBlockConditions = (
|
||||
path: ["blocks", blockIndex, "logic", logicIndex, "conditions"],
|
||||
});
|
||||
} else {
|
||||
const validElementTypes = [TSurveyElementTypeEnum.OpenText];
|
||||
const validElementTypes: TSurveyElementTypeEnum[] = [TSurveyElementTypeEnum.OpenText];
|
||||
|
||||
if (element.inputType === "number") {
|
||||
validElementTypes.push(...[TSurveyElementTypeEnum.Rating, TSurveyElementTypeEnum.NPS]);
|
||||
@@ -3397,7 +3397,10 @@ const validateBlockConditions = (
|
||||
path: ["blocks", blockIndex, "logic", logicIndex, "conditions"],
|
||||
});
|
||||
} else {
|
||||
const validElementTypes = [TSurveyElementTypeEnum.OpenText, TSurveyElementTypeEnum.Date];
|
||||
const validElementTypes: TSurveyElementTypeEnum[] = [
|
||||
TSurveyElementTypeEnum.OpenText,
|
||||
TSurveyElementTypeEnum.Date,
|
||||
];
|
||||
if (!validElementTypes.includes(elem.data.type)) {
|
||||
issues.push({
|
||||
code: z.ZodIssueCode.custom,
|
||||
@@ -3587,7 +3590,7 @@ const validateBlockActions = (
|
||||
|
||||
if (variable.type === "text") {
|
||||
if (action.value.type === "element") {
|
||||
const allowedElements = [
|
||||
const allowedElements: TSurveyElementTypeEnum[] = [
|
||||
TSurveyElementTypeEnum.OpenText,
|
||||
TSurveyElementTypeEnum.MultipleChoiceSingle,
|
||||
TSurveyElementTypeEnum.Rating,
|
||||
@@ -3610,7 +3613,10 @@ const validateBlockActions = (
|
||||
}
|
||||
|
||||
if (action.value.type === "element") {
|
||||
const allowedElements = [TSurveyElementTypeEnum.Rating, TSurveyElementTypeEnum.NPS];
|
||||
const allowedElements: TSurveyElementTypeEnum[] = [
|
||||
TSurveyElementTypeEnum.Rating,
|
||||
TSurveyElementTypeEnum.NPS,
|
||||
];
|
||||
|
||||
const selectedElement = allElements.get(action.value.value);
|
||||
|
||||
|
||||
Generated
+59
@@ -1011,6 +1011,9 @@ importers:
|
||||
postcss:
|
||||
specifier: 8.5.3
|
||||
version: 8.5.3
|
||||
rollup-plugin-visualizer:
|
||||
specifier: 6.0.5
|
||||
version: 6.0.5(rollup@4.54.0)
|
||||
tailwindcss:
|
||||
specifier: 4.1.17
|
||||
version: 4.1.17
|
||||
@@ -3231,12 +3234,15 @@ packages:
|
||||
|
||||
'@otplib/plugin-crypto@12.0.1':
|
||||
resolution: {integrity: sha512-qPuhN3QrT7ZZLcLCyKOSNhuijUi9G5guMRVrxq63r9YNOxxQjPm59gVxLM+7xGnHnM6cimY57tuKsjK7y9LM1g==}
|
||||
deprecated: Please upgrade to v13 of otplib. Refer to otplib docs for migration paths
|
||||
|
||||
'@otplib/plugin-thirty-two@12.0.1':
|
||||
resolution: {integrity: sha512-MtT+uqRso909UkbrrYpJ6XFjj9D+x2Py7KjTO9JDPhL0bJUYVu5kFP4TFZW4NFAywrAtFRxOVY261u0qwb93gA==}
|
||||
deprecated: Please upgrade to v13 of otplib. Refer to otplib docs for migration paths
|
||||
|
||||
'@otplib/preset-default@12.0.1':
|
||||
resolution: {integrity: sha512-xf1v9oOJRyXfluBhMdpOkr+bsE+Irt+0D5uHtvg6x1eosfmHCsCC6ej/m7FXiWqdo0+ZUI6xSKDhJwc8yfiOPQ==}
|
||||
deprecated: Please upgrade to v13 of otplib. Refer to otplib docs for migration paths
|
||||
|
||||
'@otplib/preset-v11@12.0.1':
|
||||
resolution: {integrity: sha512-9hSetMI7ECqbFiKICrNa4w70deTUfArtwXykPUvSHWOdzOlfa9ajglu7mNCntlvxycTiOAXkQGwjQCzzDEMRMg==}
|
||||
@@ -6648,6 +6654,10 @@ packages:
|
||||
resolution: {integrity: sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==}
|
||||
engines: {node: '>= 0.4'}
|
||||
|
||||
define-lazy-prop@2.0.0:
|
||||
resolution: {integrity: sha512-Ds09qNh8yw3khSjiJjiUInaGX9xlqZDY7JVryGxdxV7NPeuqQfplOpQ66yJFZut3jLa5zOwkXw1g9EI2uKh4Og==}
|
||||
engines: {node: '>=8'}
|
||||
|
||||
define-lazy-prop@3.0.0:
|
||||
resolution: {integrity: sha512-N+MeXYoqr3pOgn8xfyRPREN7gHakLYjhsHhWGT3fWAiL4IkAt0iDw14QiiEm2bE30c5XX5q0FtAA3CK5f9/BUg==}
|
||||
engines: {node: '>=12'}
|
||||
@@ -7777,6 +7787,11 @@ packages:
|
||||
resolution: {integrity: sha512-PwwhEakHVKTdRNVOw+/Gyh0+MzlCl4R6qKvkhuvLtPMggI1WAHt9sOwZxQLSGpUaDnrdyDsomoRgNnCfKNSXXg==}
|
||||
engines: {node: '>= 0.4'}
|
||||
|
||||
is-docker@2.2.1:
|
||||
resolution: {integrity: sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ==}
|
||||
engines: {node: '>=8'}
|
||||
hasBin: true
|
||||
|
||||
is-docker@3.0.0:
|
||||
resolution: {integrity: sha512-eljcgEDlEns/7AXFosB5K/2nCM4P7FQPkGc/DWLy5rmFEWvZayGrik1d9/QIY5nJ4f9YsVvBkA6kJpHn9rISdQ==}
|
||||
engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0}
|
||||
@@ -7914,6 +7929,10 @@ packages:
|
||||
resolution: {integrity: sha512-ZhMwEosbFJkA0YhFnNDgTM4ZxDRsS6HqTo7qsZM08fehyRYIYa0yHu5R6mgo1n/8MgaPBXiPimPD77baVFYg+A==}
|
||||
engines: {node: '>=12.13'}
|
||||
|
||||
is-wsl@2.2.0:
|
||||
resolution: {integrity: sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww==}
|
||||
engines: {node: '>=8'}
|
||||
|
||||
is-wsl@3.1.0:
|
||||
resolution: {integrity: sha512-UcVfVfaK4Sc4m7X3dUSoHoozQGBEFeDC+zVo06t98xe8CzHSZZBekNXH+tu0NalHolcJ/QAGqS46Hef7QXBIMw==}
|
||||
engines: {node: '>=16'}
|
||||
@@ -8839,6 +8858,10 @@ packages:
|
||||
resolution: {integrity: sha512-YgBpdJHPyQ2UE5x+hlSXcnejzAvD0b22U2OuAP+8OnlJT+PjWPxtgmGqKKc+RgTM63U9gN0YzrYc71R2WT/hTA==}
|
||||
engines: {node: '>=18'}
|
||||
|
||||
open@8.4.2:
|
||||
resolution: {integrity: sha512-7x81NCL719oNbsq/3mh+hVrAWmFuEYUqrq/Iw3kUzH8ReypT9QQ0BLoJS7/G9k6N81XjW4qHWtjWwe/9eLy1EQ==}
|
||||
engines: {node: '>=12'}
|
||||
|
||||
openid-client@5.7.1:
|
||||
resolution: {integrity: sha512-jDBPgSVfTnkIh71Hg9pRvtJc6wTwqjRkN88+gCFtYWrlP4Yx2Dsrow8uPi3qLr/aeymPF3o2+dS+wOpglK04ew==}
|
||||
|
||||
@@ -9638,6 +9661,19 @@ packages:
|
||||
ripemd160@2.0.2:
|
||||
resolution: {integrity: sha512-ii4iagi25WusVoiC4B4lq7pbXfAp3D9v5CwfkY33vffw2+pkDjY1D8GaN7spsxvCSx8dkPqOZCEZyfxcmJG2IA==}
|
||||
|
||||
rollup-plugin-visualizer@6.0.5:
|
||||
resolution: {integrity: sha512-9+HlNgKCVbJDs8tVtjQ43US12eqaiHyyiLMdBwQ7vSZPiHMysGNo2E88TAp1si5wx8NAoYriI2A5kuKfIakmJg==}
|
||||
engines: {node: '>=18'}
|
||||
hasBin: true
|
||||
peerDependencies:
|
||||
rolldown: 1.x || ^1.0.0-beta
|
||||
rollup: 2.x || 3.x || 4.x
|
||||
peerDependenciesMeta:
|
||||
rolldown:
|
||||
optional: true
|
||||
rollup:
|
||||
optional: true
|
||||
|
||||
rollup@4.54.0:
|
||||
resolution: {integrity: sha512-3nk8Y3a9Ea8szgKhinMlGMhGMw89mqule3KWczxhIzqudyHdCIOHw8WJlj/r329fACjKLEh13ZSk7oE22kyeIw==}
|
||||
engines: {node: '>=18.0.0', npm: '>=8.0.0'}
|
||||
@@ -17957,6 +17993,8 @@ snapshots:
|
||||
es-errors: 1.3.0
|
||||
gopd: 1.2.0
|
||||
|
||||
define-lazy-prop@2.0.0: {}
|
||||
|
||||
define-lazy-prop@3.0.0: {}
|
||||
|
||||
define-properties@1.2.1:
|
||||
@@ -19381,6 +19419,8 @@ snapshots:
|
||||
call-bound: 1.0.4
|
||||
has-tostringtag: 1.0.2
|
||||
|
||||
is-docker@2.2.1: {}
|
||||
|
||||
is-docker@3.0.0: {}
|
||||
|
||||
is-extglob@2.1.1: {}
|
||||
@@ -19492,6 +19532,10 @@ snapshots:
|
||||
|
||||
is-what@4.1.16: {}
|
||||
|
||||
is-wsl@2.2.0:
|
||||
dependencies:
|
||||
is-docker: 2.2.1
|
||||
|
||||
is-wsl@3.1.0:
|
||||
dependencies:
|
||||
is-inside-container: 1.0.0
|
||||
@@ -20441,6 +20485,12 @@ snapshots:
|
||||
is-inside-container: 1.0.0
|
||||
wsl-utils: 0.1.0
|
||||
|
||||
open@8.4.2:
|
||||
dependencies:
|
||||
define-lazy-prop: 2.0.0
|
||||
is-docker: 2.2.1
|
||||
is-wsl: 2.2.0
|
||||
|
||||
openid-client@5.7.1:
|
||||
dependencies:
|
||||
jose: 4.15.9
|
||||
@@ -21283,6 +21333,15 @@ snapshots:
|
||||
hash-base: 3.1.2
|
||||
inherits: 2.0.4
|
||||
|
||||
rollup-plugin-visualizer@6.0.5(rollup@4.54.0):
|
||||
dependencies:
|
||||
open: 8.4.2
|
||||
picomatch: 4.0.3
|
||||
source-map: 0.7.6
|
||||
yargs: 17.7.2
|
||||
optionalDependencies:
|
||||
rollup: 4.54.0
|
||||
|
||||
rollup@4.54.0:
|
||||
dependencies:
|
||||
'@types/estree': 1.0.8
|
||||
|
||||
Reference in New Issue
Block a user