Compare commits

..

3 Commits

Author SHA1 Message Date
pandeymangg
a190213c7c chore: merge with main 2025-12-22 14:27:02 +05:30
Matti Nannt
ad0faf7054 fix: add zod-openapi dependency to packages/types
- Add zod-openapi@4.2.4 to packages/types/package.json to fix linting error
- Update pnpm-lock.yaml with new dependency
- Include formatting changes from pre-commit hooks
2025-12-15 12:26:23 +01:00
Matti Nannt
1830fc044b fix: update V2 API OpenAPI paths to include full prefixes
- Update all management API paths to include /management prefix
- Update all organizations API paths to include /organizations prefix
- Remove path-level server overrides that API clients don't handle properly
- Delete unused managementServer and organizationServer definitions
- Fix circular reference in ZConditionGroup schema for OpenAPI generation

This fixes the issue where API clients were calling /api/v2/responses
instead of /api/v2/management/responses, causing 404 errors.
2025-12-15 12:16:57 +01:00
21 changed files with 1557 additions and 262 deletions

View File

@@ -9,7 +9,6 @@ import {
ZContactAttributeKeyInput,
ZGetContactAttributeKeysFilter,
} from "@/modules/api/v2/management/contact-attribute-keys/types/contact-attribute-keys";
import { managementServer } from "@/modules/api/v2/management/lib/openapi";
import { makePartialSchema, responseWithMetaSchema } from "@/modules/api/v2/types/openapi-response";
export const getContactAttributeKeysEndpoint: ZodOpenApiOperationObject = {
@@ -59,13 +58,11 @@ export const createContactAttributeKeyEndpoint: ZodOpenApiOperationObject = {
};
export const contactAttributeKeyPaths: ZodOpenApiPathsObject = {
"/contact-attribute-keys": {
servers: managementServer,
"/management/contact-attribute-keys": {
get: getContactAttributeKeysEndpoint,
post: createContactAttributeKeyEndpoint,
},
"/contact-attribute-keys/{id}": {
servers: managementServer,
"/management/contact-attribute-keys/{id}": {
get: getContactAttributeKeyEndpoint,
put: updateContactAttributeKeyEndpoint,
delete: deleteContactAttributeKeyEndpoint,

View File

@@ -1,6 +0,0 @@
export const managementServer = [
{
url: `https://app.formbricks.com/api/v2/management`,
description: "Formbricks Management API",
},
];

View File

@@ -1,6 +1,5 @@
import { ZodOpenApiOperationObject, ZodOpenApiPathsObject } from "zod-openapi";
import { ZResponse } from "@formbricks/database/zod/responses";
import { managementServer } from "@/modules/api/v2/management/lib/openapi";
import {
deleteResponseEndpoint,
getResponseEndpoint,
@@ -57,13 +56,11 @@ export const createResponseEndpoint: ZodOpenApiOperationObject = {
};
export const responsePaths: ZodOpenApiPathsObject = {
"/responses": {
servers: managementServer,
"/management/responses": {
get: getResponsesEndpoint,
post: createResponseEndpoint,
},
"/responses/{id}": {
servers: managementServer,
"/management/responses/{id}": {
get: getResponseEndpoint,
put: updateResponseEndpoint,
delete: deleteResponseEndpoint,

View File

@@ -1,10 +1,8 @@
import { ZodOpenApiPathsObject } from "zod-openapi";
import { managementServer } from "@/modules/api/v2/management/lib/openapi";
import { getContactLinksBySegmentEndpoint } from "@/modules/api/v2/management/surveys/[surveyId]/contact-links/segments/[segmentId]/lib/openapi";
export const surveyContactLinksBySegmentPaths: ZodOpenApiPathsObject = {
"/surveys/{surveyId}/contact-links/segments/{segmentId}": {
servers: managementServer,
"/management/surveys/{surveyId}/contact-links/segments/{segmentId}": {
get: getContactLinksBySegmentEndpoint,
},
};

View File

@@ -1,7 +1,6 @@
import { z } from "zod";
import { ZodOpenApiOperationObject, ZodOpenApiPathsObject } from "zod-openapi";
import { ZSurveyWithoutQuestionType } from "@formbricks/database/zod/surveys";
import { managementServer } from "@/modules/api/v2/management/lib/openapi";
import { getPersonalizedSurveyLink } from "@/modules/api/v2/management/surveys/[surveyId]/contact-links/contacts/[contactId]/lib/openapi";
import { ZGetSurveysFilter, ZSurveyInput } from "@/modules/api/v2/management/surveys/types/surveys";
@@ -52,19 +51,16 @@ export const createSurveyEndpoint: ZodOpenApiOperationObject = {
};
export const surveyPaths: ZodOpenApiPathsObject = {
// "/surveys": {
// servers: managementServer,
// "/management/surveys": {
// get: getSurveysEndpoint,
// post: createSurveyEndpoint,
// },
// "/surveys/{id}": {
// servers: managementServer,
// "/management/surveys/{id}": {
// get: getSurveyEndpoint,
// put: updateSurveyEndpoint,
// delete: deleteSurveyEndpoint,
// },
"/surveys/{surveyId}/contact-links/contacts/{contactId}/": {
servers: managementServer,
"/management/surveys/{surveyId}/contact-links/contacts/{contactId}/": {
get: getPersonalizedSurveyLink,
},
};

View File

@@ -1,6 +1,5 @@
import { ZodOpenApiOperationObject, ZodOpenApiPathsObject } from "zod-openapi";
import { ZWebhook } from "@formbricks/database/zod/webhooks";
import { managementServer } from "@/modules/api/v2/management/lib/openapi";
import {
deleteWebhookEndpoint,
getWebhookEndpoint,
@@ -56,13 +55,11 @@ export const createWebhookEndpoint: ZodOpenApiOperationObject = {
};
export const webhookPaths: ZodOpenApiPathsObject = {
"/webhooks": {
servers: managementServer,
"/management/webhooks": {
get: getWebhooksEndpoint,
post: createWebhookEndpoint,
},
"/webhooks/{id}": {
servers: managementServer,
"/management/webhooks/{id}": {
get: getWebhookEndpoint,
put: updateWebhookEndpoint,
delete: deleteWebhookEndpoint,

View File

@@ -7,7 +7,6 @@ import {
ZProjectTeamInput,
} from "@/modules/api/v2/organizations/[organizationId]/project-teams/types/project-teams";
import { ZOrganizationIdSchema } from "@/modules/api/v2/organizations/[organizationId]/types/organizations";
import { organizationServer } from "@/modules/api/v2/organizations/lib/openapi";
import { makePartialSchema, responseWithMetaSchema } from "@/modules/api/v2/types/openapi-response";
export const getProjectTeamsEndpoint: ZodOpenApiOperationObject = {
@@ -119,8 +118,7 @@ export const updateProjectTeamEndpoint: ZodOpenApiOperationObject = {
};
export const projectTeamPaths: ZodOpenApiPathsObject = {
"/{organizationId}/project-teams": {
servers: organizationServer,
"/organizations/{organizationId}/project-teams": {
get: getProjectTeamsEndpoint,
post: createProjectTeamEndpoint,
put: updateProjectTeamEndpoint,

View File

@@ -11,7 +11,6 @@ import {
ZTeamInput,
} from "@/modules/api/v2/organizations/[organizationId]/teams/types/teams";
import { ZOrganizationIdSchema } from "@/modules/api/v2/organizations/[organizationId]/types/organizations";
import { organizationServer } from "@/modules/api/v2/organizations/lib/openapi";
import { makePartialSchema, responseWithMetaSchema } from "@/modules/api/v2/types/openapi-response";
export const getTeamsEndpoint: ZodOpenApiOperationObject = {
@@ -69,13 +68,11 @@ export const createTeamEndpoint: ZodOpenApiOperationObject = {
};
export const teamPaths: ZodOpenApiPathsObject = {
"/{organizationId}/teams": {
servers: organizationServer,
"/organizations/{organizationId}/teams": {
get: getTeamsEndpoint,
post: createTeamEndpoint,
},
"/{organizationId}/teams/{id}": {
servers: organizationServer,
"/organizations/{organizationId}/teams/{id}": {
get: getTeamEndpoint,
put: updateTeamEndpoint,
delete: deleteTeamEndpoint,

View File

@@ -7,7 +7,6 @@ import {
ZUserInput,
ZUserInputPatch,
} from "@/modules/api/v2/organizations/[organizationId]/users/types/users";
import { organizationServer } from "@/modules/api/v2/organizations/lib/openapi";
import { makePartialSchema, responseWithMetaSchema } from "@/modules/api/v2/types/openapi-response";
export const getUsersEndpoint: ZodOpenApiOperationObject = {
@@ -96,8 +95,7 @@ export const updateUserEndpoint: ZodOpenApiOperationObject = {
};
export const userPaths: ZodOpenApiPathsObject = {
"/{organizationId}/users": {
servers: organizationServer,
"/organizations/{organizationId}/users": {
get: getUsersEndpoint,
post: createUserEndpoint,
patch: updateUserEndpoint,

View File

@@ -1,6 +0,0 @@
export const organizationServer = [
{
url: `https://app.formbricks.com/api/v2/organizations`,
description: "Formbricks Organizations API",
},
];

View File

@@ -1,6 +1,5 @@
import { z } from "zod";
import { ZodOpenApiOperationObject, ZodOpenApiPathsObject } from "zod-openapi";
import { managementServer } from "@/modules/api/v2/management/lib/openapi";
import { ZContactBulkUploadRequest } from "@/modules/ee/contacts/types/contact";
const bulkContactEndpoint: ZodOpenApiOperationObject = {
@@ -111,8 +110,7 @@ const bulkContactEndpoint: ZodOpenApiOperationObject = {
};
export const bulkContactPaths: ZodOpenApiPathsObject = {
"/contacts/bulk": {
servers: managementServer,
"/management/contacts/bulk": {
put: bulkContactEndpoint,
},
};

View File

@@ -1,5 +1,4 @@
import { ZodOpenApiOperationObject, ZodOpenApiPathsObject } from "zod-openapi";
import { managementServer } from "@/modules/api/v2/management/lib/openapi";
import { makePartialSchema } from "@/modules/api/v2/types/openapi-response";
import { ZContactCreateRequest, ZContactResponse } from "@/modules/ee/contacts/types/contact";
@@ -54,8 +53,7 @@ export const createContactEndpoint: ZodOpenApiOperationObject = {
};
export const contactPaths: ZodOpenApiPathsObject = {
"/contacts": {
servers: managementServer,
"/management/contacts": {
post: createContactEndpoint,
},
};

File diff suppressed because it is too large Load Diff

View File

@@ -24,7 +24,7 @@
Design Tokens
============================================================================= */
#fbjs {
:root {
/* ---------------------------------------------------------------------------
Base Primitives
These are the foundation tokens used throughout the design system.
@@ -206,27 +206,27 @@
Textarea Scrollbar Styling
Smaller, more subtle scrollbars for textarea elements.
--------------------------------------------------------------------------- */
#fbjs textarea {
textarea {
/* Firefox */
scrollbar-width: thin;
scrollbar-color: hsl(215.4 16.3% 46.9% / 0.3) transparent;
}
/* Chrome, Edge, and Safari */
#fbjs textarea::-webkit-scrollbar {
textarea::-webkit-scrollbar {
width: 4px;
height: 4px;
}
#fbjs textarea::-webkit-scrollbar-track {
textarea::-webkit-scrollbar-track {
background: transparent;
}
#fbjs textarea::-webkit-scrollbar-thumb {
textarea::-webkit-scrollbar-thumb {
background-color: hsl(215.4 16.3% 46.9% / 0.3);
border-radius: 2px;
}
#fbjs textarea::-webkit-scrollbar-thumb:hover {
textarea::-webkit-scrollbar-thumb:hover {
background-color: hsl(215.4 16.3% 46.9% / 0.5);
}

View File

@@ -173,8 +173,7 @@ export function BlockConditional({
}
// For other element types, check if required fields are empty
// CTA elements should not block navigation even if marked required (as they are informational)
if (element.type !== TSurveyElementTypeEnum.CTA && element.required && isEmptyResponse(response)) {
if (element.required && isEmptyResponse(response)) {
form.requestSubmit();
return false;
}

View File

@@ -225,7 +225,7 @@ describe("addCustomThemeToDom", () => {
const getCssVariables = (styleElement: HTMLStyleElement | null): Record<string, string> => {
if (!styleElement || !styleElement.innerHTML) return {};
const cssText = styleElement.innerHTML;
const rootMatch = cssText.match(/#fbjs\s*{\s*([^}]*?)\s*}/);
const rootMatch = cssText.match(/:root\s*{\s*([^}]*?)\s*}/);
if (!rootMatch || !rootMatch[1]) return {};
const variables: Record<string, string> = {};

View File

@@ -78,8 +78,8 @@ export const addCustomThemeToDom = ({ styling }: { styling: TProjectStyling | TS
document.head.appendChild(styleElement);
}
// Start the innerHTML string with #fbjs
let cssVariables = "#fbjs {\n";
// Start the innerHTML string with :root
let cssVariables = ":root {\n";
// Helper function to append the variable if it's not undefined
const appendCssVariable = (variableName: string, value?: string) => {
@@ -179,7 +179,7 @@ export const addCustomThemeToDom = ({ styling }: { styling: TProjectStyling | TS
}
}
// Close the #fbjs block
// Close the :root block
cssVariables += "}";
// Set the innerHTML of the style element

View File

@@ -18,11 +18,11 @@
*/
@layer base {
#fbjs *,
#fbjs ::after,
#fbjs ::before,
#fbjs ::backdrop,
#fbjs ::file-selector-button {
*,
::after,
::before,
::backdrop,
::file-selector-button {
border-color: var(--color-gray-200, currentcolor);
}
}
@@ -56,19 +56,19 @@
}
/* this is for styling the HtmlBody component */
#fbjs .htmlbody {
.htmlbody {
@apply block text-sm font-normal leading-6;
/* need to use !important because in packages/survey-ui/components/editor/styles-editor-frontend.css the color is defined for some classes */
color: var(--fb-subheading-color) !important;
}
/* without this, it wont override the color */
#fbjs p.editor-paragraph {
p.editor-paragraph {
overflow-wrap: break-word;
}
/* theming */
#fbjs {
:root {
--brand-default: #64748b;
--slate-50: rgb(248, 250, 252);
--slate-100: rgb(241 245 249);
@@ -126,7 +126,7 @@
}
}
#fbjs .no-scrollbar {
.no-scrollbar {
-ms-overflow-style: none !important;
/* Internet Explorer 10+ */
scrollbar-width: thin !important;
@@ -145,6 +145,6 @@
}
}
#fbjs .grecaptcha-badge {
.grecaptcha-badge {
visibility: hidden;
}

View File

@@ -11,6 +11,7 @@
"dependencies": {
"@prisma/client": "6.14.0",
"zod": "3.24.4",
"zod-openapi": "4.2.4",
"node-html-parser": "7.0.1"
},
"devDependencies": {

View File

@@ -1,6 +1,9 @@
import { z } from "zod";
import { extendZodWithOpenApi } from "zod-openapi";
import { ZId } from "../common";
extendZodWithOpenApi(z);
// Logic operators
export const ZSurveyLogicConditionsOperator = z.enum([
"equals",
@@ -211,13 +214,15 @@ export const ZSingleConditionDeprecated = z
export type TSingleConditionDeprecated = z.infer<typeof ZSingleConditionDeprecated>;
export const ZConditionGroup: z.ZodType<TConditionGroup> = z.lazy(() =>
z.object({
id: ZId,
connector: ZConnector,
conditions: z.array(z.union([ZSingleCondition, ZConditionGroup])),
})
);
export const ZConditionGroup: z.ZodType<TConditionGroup> = z
.lazy(() =>
z.object({
id: ZId,
connector: ZConnector,
conditions: z.array(z.union([ZSingleCondition, ZConditionGroup])),
})
)
.openapi({ ref: "conditionGroup" });
export interface TConditionGroup {
id: string;

3
pnpm-lock.yaml generated
View File

@@ -992,6 +992,9 @@ importers:
zod:
specifier: 3.24.4
version: 3.24.4
zod-openapi:
specifier: 4.2.4
version: 4.2.4(zod@3.24.4)
devDependencies:
'@formbricks/config-typescript':
specifier: workspace:*