@crvouga/mockingbird-service-formbricks 0.2.0 → 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/cli.js CHANGED
@@ -3,14 +3,14 @@ import {
3
3
  runCli,
4
4
  serveCommand,
5
5
  serveTarget
6
- } from "./chunk-2FV4RSDZ.js";
7
- import "./chunk-FZI2QHRQ.js";
6
+ } from "./chunk-RITQFAWR.js";
7
+ import "./chunk-ZFDC3GHV.js";
8
8
 
9
9
  // src/cli.ts
10
10
  var code = await runCli(
11
11
  {
12
12
  bin: "mockingbird-formbricks",
13
- description: "stateful Formbricks (Geviti fork) mock",
13
+ description: "stateful Formbricks mock",
14
14
  commands: { serve: serveCommand(serveTarget) }
15
15
  },
16
16
  process.argv.slice(2)
package/dist/cli.js.map CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../src/cli.ts"],
4
- "sourcesContent": ["#!/usr/bin/env node\n/// <reference types=\"node\" />\nimport { runCli, serveCommand } from \"@crvouga/mockingbird-adapter-node\"\nimport { serveTarget } from \"./server.js\"\n\nconst code = await runCli(\n {\n bin: \"mockingbird-formbricks\",\n description: \"stateful Formbricks (Geviti fork) mock\",\n commands: { serve: serveCommand(serveTarget) },\n },\n process.argv.slice(2),\n)\nif (code !== 0) process.exitCode = code\n"],
4
+ "sourcesContent": ["#!/usr/bin/env node\n/// <reference types=\"node\" />\nimport { runCli, serveCommand } from \"@crvouga/mockingbird-adapter-node\"\nimport { serveTarget } from \"./server.js\"\n\nconst code = await runCli(\n {\n bin: \"mockingbird-formbricks\",\n description: \"stateful Formbricks mock\",\n commands: { serve: serveCommand(serveTarget) },\n },\n process.argv.slice(2),\n)\nif (code !== 0) process.exitCode = code\n"],
5
5
  "mappings": ";;;;;;;;;AAKA,IAAM,OAAO,MAAM;AAAA,EACjB;AAAA,IACE,KAAK;AAAA,IACL,aAAa;AAAA,IACb,UAAU,EAAE,OAAO,aAAa,WAAW,EAAE;AAAA,EAC/C;AAAA,EACA,QAAQ,KAAK,MAAM,CAAC;AACtB;AACA,IAAI,SAAS,EAAG,SAAQ,WAAW;",
6
6
  "names": []
7
7
  }
package/dist/index.d.ts CHANGED
@@ -832,14 +832,20 @@ interface SqliteClient {
832
832
  transaction<T>(fn: () => T): T;
833
833
  }
834
834
 
835
- /** A survey definition, passed through as Formbricks serves it (blocks, elements, logic, …). */
835
+ /** A survey definition, passed through as Formbricks serves it (blocks, elements, endings, …). */
836
836
  type Survey = Record<string, unknown> & {
837
837
  id: string;
838
838
  name: string;
839
839
  type: string;
840
840
  status: string;
841
- /** `null` for the shared fixture surveys, which every configured environment serves. */
842
- environmentId?: string | null;
841
+ /** `null` for the shared corpus surveys, which every configured workspace serves. */
842
+ workspaceId?: string | null;
843
+ };
844
+ /** A contact (`PUT /__admin/contacts`); `attributes.userId` becomes the response's `contact.userId`. */
845
+ type Contact = {
846
+ id: string;
847
+ workspaceId: string | null;
848
+ attributes: Record<string, string>;
843
849
  };
844
850
  /** One stored response, in Formbricks' `TResponse` shape. */
845
851
  type ResponseRecord = {
@@ -847,11 +853,11 @@ type ResponseRecord = {
847
853
  createdAt: string;
848
854
  updatedAt: string;
849
855
  surveyId: string;
850
- environmentId: string;
856
+ workspaceId: string;
851
857
  displayId: string | null;
852
858
  contact: {
853
859
  id: string;
854
- userId: string;
860
+ userId?: string;
855
861
  } | null;
856
862
  contactAttributes: Record<string, string> | null;
857
863
  finished: boolean;
@@ -866,34 +872,29 @@ type ResponseRecord = {
866
872
  };
867
873
  /** Per-namespace knobs, set through `PUT /__admin/settings`; cleared on reset. */
868
874
  type Settings = {
869
- /** Environment ids that serve the shared fixture surveys. */
870
- environments: string[];
875
+ /** Workspace ids that exist and serve the shared corpus surveys. */
876
+ workspaces: string[];
877
+ /** Pre-Formbricks-5 environment ids, each an alias of a workspace (`{envId: workspaceId}`). */
878
+ legacyEnvironmentIds: Record<string, string>;
871
879
  /** Accepted management API keys; empty means any non-empty `x-api-key` works. */
872
880
  apiKeys: string[];
873
881
  /** The `webhookId` put in webhook bodies. */
874
882
  webhookId: string;
875
- /** Whether a `userId` on a response finds-or-creates a contact (the fork's behaviour). */
883
+ /** Contacts are an Enterprise feature: when off, a response with a `contactId` is 403. */
876
884
  contactsEnabled: boolean;
877
885
  };
878
- /** Our member-app production and development Formbricks environments. */
879
- declare const PRODUCTION_ENVIRONMENT_ID = "cmlhiza9j0009lj01my5c1g0q";
880
- declare const DEVELOPMENT_ENVIRONMENT_ID = "cmlhiza9c0004lj01jbuhp0nz";
886
+ /** The default workspace every namespace starts with. */
887
+ declare const WORKSPACE_ID = "cworkspace000000000000001";
888
+ /** A legacy environment id that resolves to {@link WORKSPACE_ID} (older SDKs still send one). */
889
+ declare const ENVIRONMENT_ID = "cenvironment0000000000001";
881
890
  declare const DEFAULT_SETTINGS: Settings;
882
- /**
883
- * The committed clone of our production survey definitions
884
- * (`packages/forms-fixtures/formbricks/prod-clone.json` in geviti-monorepo).
885
- */
886
- declare const PROD_CLONE_SURVEYS: readonly Survey[];
887
- declare const PROD_CLONE_EXPORTED_AT: string;
891
+ /** The synthetic survey corpus every namespace is seeded with (`src/corpus/surveys.json`). */
892
+ declare const CORPUS_SURVEYS: readonly Survey[];
888
893
  declare class FormbricksState {
889
894
  private readonly seed;
890
895
  readonly surveys: Collection<Survey>;
891
896
  readonly responses: Collection<ResponseRecord>;
892
- readonly contacts: Collection<{
893
- id: string;
894
- environmentId: string;
895
- userId: string;
896
- }>;
897
+ readonly contacts: Collection<Contact>;
897
898
  readonly settings: Collection<Settings>;
898
899
  readonly ids: IdSequence;
899
900
  constructor(sqlite: SqliteClient, namespace: string, seed: {
@@ -905,17 +906,20 @@ declare class FormbricksState {
905
906
  update(patch: Partial<Settings>): Settings;
906
907
  /** Formbricks ids are cuid2: lower-case alphanumerics starting with a letter, 25 long. */
907
908
  nextId(): string;
908
- knownEnvironment(environmentId: string): boolean;
909
+ /**
910
+ * `resolveClientApiIds`: a workspace id, or a legacy environment id, to its workspace id
911
+ * (`undefined` when neither is known).
912
+ */
913
+ resolveWorkspace(id: string): string | undefined;
914
+ /** The v1 `environmentId` of a workspace: its legacy environment id, else its own id. */
915
+ legacyEnvironmentId(workspaceId: string): string;
909
916
  allSurveys(): Survey[];
910
- /** Surveys an environment serves: its own, plus the shared fixture when it is configured. */
911
- surveysOf(environmentId: string): Survey[];
912
- /** Whether a survey belongs to an environment (the fork's `survey.environmentId` check). */
913
- belongsTo(survey: Survey, environmentId: string): boolean;
914
- /** The fork's find-or-create contact for a response `userId` (the member's email). */
915
- contactFor(environmentId: string, userId: string): {
916
- id: string;
917
- userId: string;
918
- };
917
+ /** Surveys a workspace serves: its own, plus the shared corpus when it is configured. */
918
+ surveysOf(workspaceId: string): Survey[];
919
+ /** Whether a survey belongs to a workspace (`survey.workspaceId !== workspaceId` check). */
920
+ belongsTo(survey: Survey, workspaceId: string): boolean;
921
+ /** `getContact(contactId, workspaceId)`: a contact of that workspace (or a shared one). */
922
+ contactOf(contactId: string, workspaceId: string): Contact | undefined;
919
923
  }
920
924
 
921
925
  /**
@@ -1090,20 +1094,21 @@ declare const operationIds: readonly ["GetEnvironmentState", "CreateClientRespon
1090
1094
  declare const supportedOperationIds: readonly ["GetEnvironmentState", "CreateClientResponse", "ListResponses", "GetResponse", "ListSurveys", "CreateSurvey", "GetSurvey", "GetWidgetScript"];
1091
1095
 
1092
1096
  /**
1093
- * The fork's response validation (`modules/api/lib/validation.ts` → `validateBlockResponses`
1094
- * in `packages/surveys/src/lib/validation/evaluator.ts`), trimmed to what our surveys use:
1095
- * required elements, and the implicit email / url / phone rules of openText elements. When the
1096
- * response is finished every element is checked (including ones logic would skip); when it is
1097
- * not, only the elements present in `data`.
1097
+ * Formbricks' response validation (`validateResponseData` in `apps/web/modules/api/lib/validation.ts`
1098
+ * → `validateBlockResponses` in `packages/surveys/src/lib/validation/evaluator.ts`), trimmed to the
1099
+ * structural checks: required elements, choice membership for choice elements without an "other"
1100
+ * option, and the implicit email / url / phone rules of openText elements. Only the elements
1101
+ * present in `data` are checked, finished or not (upstream never checks absent elements).
1102
+ * Custom `validation.rules` are not evaluated.
1098
1103
  */
1099
1104
 
1100
1105
  /** `{<elementId>: [messages]}`, or `null` when the response passes. */
1101
- declare const validateResponseData: (survey: Survey, data: Record<string, unknown>, finished: boolean) => Record<string, string[]> | null;
1106
+ declare const validateResponseData: (survey: Survey, data: Record<string, unknown>, language?: string) => Record<string, string[]> | null;
1102
1107
 
1103
- /** Where our backend receives the webhook (`onboarding-tasks.controller.ts`; `?token=` checked). */
1104
- declare const WEBHOOK_PATH = "/onboarding-tasks/formbricks-webhook";
1108
+ /** A conventional path for the consumer app's webhook receiver (examples and the CLI help use it). */
1109
+ declare const WEBHOOK_PATH = "/webhooks/formbricks";
1105
1110
  /**
1106
- * Every named Formbricks misbehaviour our consumers branch on, switched on with
1111
+ * Every named Formbricks misbehaviour a consumer app may branch on, switched on with
1107
1112
  * `POST /__admin/faults {"preset": "<name>"}` (add `count` to limit it).
1108
1113
  */
1109
1114
  declare const FORMBRICKS_PRESETS: Record<string, FaultPreset>;
@@ -1120,8 +1125,8 @@ type FormbricksRuntimeOptions = {
1120
1125
  surveys?: readonly Survey[];
1121
1126
  settings?: Partial<Settings>;
1122
1127
  /**
1123
- * Where webhooks go: `url` carries our `?token=<FORMBRICKS_WEBHOOK_SECRET>`; `secret` (a
1124
- * `whsec_…` Standard Webhooks key) signs `webhook-signature`; `events` defaults to
1128
+ * Where webhooks go: `url` (any query, e.g. a `?token=` your receiver checks, is kept); `secret`
1129
+ * (a `whsec_…` Standard Webhooks key) signs `webhook-signature`; `events` defaults to
1125
1130
  * `["responseFinished"]` (add `"responseCreated"` for both).
1126
1131
  */
1127
1132
  webhooks?: Omit<WebhookEndpoint, "id"> & WebhookHubOptionsSubset;
@@ -1130,22 +1135,22 @@ type FormbricksRuntime = ServiceRuntime<FormbricksAPI> & {
1130
1135
  readonly webhooks: WebhookHub;
1131
1136
  };
1132
1137
  /**
1133
- * The namespace carrier for the client API is the environment id in the path (the member app's
1134
- * fetch cannot add headers); the management API's is its `x-api-key`.
1138
+ * The namespace carrier for the client API is the workspace (or legacy environment) id in the
1139
+ * path (the SDK cannot add headers); the management API's is its `x-api-key`.
1135
1140
  */
1136
1141
  declare const formbricksCredential: (request: Request) => string | undefined;
1137
1142
  /**
1138
1143
  * The Formbricks mock with Mockingbird's full service contract: `/health`, `/__admin/*`,
1139
- * namespaces by header, by `/ns/<name>` prefix on `FORMBRICKS_APP_URL`, or by environment id /
1140
- * API key (`PUT /__admin/credentials {"credentials": {"<env id or key>": "<namespace>"}}`),
1144
+ * namespaces by header, by `/ns/<name>` prefix on the app URL, or by workspace id / API key
1145
+ * (`PUT /__admin/credentials {"credentials": {"<workspace id or key>": "<namespace>"}}`),
1141
1146
  * clock control, fault presets, and Standard-Webhooks-signed `responseFinished` webhooks.
1142
1147
  */
1143
1148
  declare const createRuntime: (options?: FormbricksRuntimeOptions) => FormbricksRuntime;
1144
1149
 
1145
1150
  declare const FORMBRICKS_NAMESPACE = "formbricks";
1146
1151
  /** The response as the API (and the webhook) renders it: `TResponse`. */
1147
- type ApiResponse = Omit<ResponseRecord, "environmentId">;
1148
- /** The body Formbricks' pipeline posts to a webhook (`app/api/(internal)/pipeline/route.ts`). */
1152
+ type ApiResponse = Omit<ResponseRecord, "workspaceId">;
1153
+ /** The body Formbricks' response pipeline posts to a webhook (`process-response-pipeline-job.ts`). */
1149
1154
  type FormbricksWebhook = {
1150
1155
  webhookId: string;
1151
1156
  event: "responseCreated" | "responseFinished";
@@ -1160,18 +1165,21 @@ type FormbricksWebhook = {
1160
1165
  };
1161
1166
  };
1162
1167
  type FormbricksAPIOptions = APIOptions & {
1163
- /** Surveys every namespace starts with. Default: our production clone. */
1168
+ /** Surveys every namespace starts with. Default: the synthetic corpus (`CORPUS_SURVEYS`). */
1164
1169
  surveys?: readonly Survey[];
1165
1170
  settings?: Partial<Settings>;
1166
1171
  /** Called for every pipeline event; the runtime signs and delivers it. */
1167
1172
  onWebhook?: (event: FormbricksWebhook) => void;
1168
1173
  };
1169
- type ErrorCode = "not_found" | "bad_request" | "internal_server_error" | "not_authenticated" | "forbidden" | "too_many_requests";
1170
- /** The fork's error envelope (`app/lib/api/response.ts`), with its CORS/no-store headers. */
1171
- declare const formbricksError: (status: number, code: ErrorCode, message: string, details?: Record<string, unknown>) => Response;
1174
+ type ErrorCode = "not_found" | "bad_request" | "internal_server_error" | "unauthorized" | "not_authenticated" | "forbidden" | "too_many_requests";
1172
1175
  /**
1173
- * Stateful mock of Formbricks (our fork): environment state and response creation for the
1174
- * client SDK / member app, the v1 management API, and the `responseFinished` webhook.
1176
+ * Formbricks' v1 error envelope (`apps/web/app/lib/api/response.ts`): `{code, message, details}`,
1177
+ * `Cache-Control: private, no-store`, and the CORS headers on the routes that pass `cors`.
1178
+ */
1179
+ declare const formbricksError: (status: number, code: ErrorCode, message: string, details?: Record<string, unknown>, cors?: boolean) => Response;
1180
+ /**
1181
+ * Stateful mock of open-source Formbricks: the client environment state and response creation
1182
+ * the JS SDK uses, the v1 management API, and the response pipeline's webhooks.
1175
1183
  */
1176
1184
  declare class FormbricksAPI implements FetchAPI$1 {
1177
1185
  readonly app: Hono;
@@ -1184,17 +1192,23 @@ declare class FormbricksAPI implements FetchAPI$1 {
1184
1192
  fetch(request: Request): Promise<Response>;
1185
1193
  reset(): Promise<void>;
1186
1194
  private iso;
1187
- /** A survey as the API serves it (no internal `environmentId: null`). */
1188
- private wireSurvey;
1195
+ /**
1196
+ * A survey as the v1 management API serves it: `questions` derived from `blocks`, the owning
1197
+ * `workspaceId` and its legacy `environmentId`, and `projectOverwrites`. Shared corpus surveys
1198
+ * are reported under the first configured workspace.
1199
+ */
1200
+ wireSurvey(survey: Survey): Survey;
1189
1201
  render(record: ResponseRecord, context?: OperationContext): ApiResponse;
1190
1202
  private environmentState;
1191
1203
  private createResponse;
1192
- /** Emit a pipeline event for a stored response (also used by `/__admin/responses/:id/finish`). */
1204
+ /** Emit a pipeline event (`responseCreated` / `responseFinished`) for a stored response. */
1193
1205
  pipeline(event: FormbricksWebhook["event"], record: ResponseRecord, survey: Survey): void;
1194
1206
  private listResponses;
1207
+ /** `getSurveys(workspaceIds, limit, offset)`: newest `updatedAt` first. */
1208
+ private listSurveys;
1195
1209
  private createSurvey;
1196
1210
  responses(): ApiResponse[];
1197
1211
  }
1198
1212
 
1199
- export { DEFAULT_SETTINGS, DEVELOPMENT_ENVIRONMENT_ID, FORMBRICKS_NAMESPACE, FORMBRICKS_PRESETS, FormbricksAPI, PRODUCTION_ENVIRONMENT_ID, PROD_CLONE_EXPORTED_AT, PROD_CLONE_SURVEYS, WEBHOOK_PATH, createRuntime, document, formbricksCredential, formbricksError, operationIds, supportedOperationIds, validateResponseData };
1200
- export type { ApiResponse, FetchAPI$1 as FetchAPI, FormbricksAPIOptions, FormbricksRuntime, FormbricksRuntimeOptions, FormbricksWebhook, OperationId, ResponseRecord, Settings, SqliteClient, SupportedOperationId, Survey };
1213
+ export { CORPUS_SURVEYS, DEFAULT_SETTINGS, ENVIRONMENT_ID, FORMBRICKS_NAMESPACE, FORMBRICKS_PRESETS, FormbricksAPI, WEBHOOK_PATH, WORKSPACE_ID, createRuntime, document, formbricksCredential, formbricksError, operationIds, supportedOperationIds, validateResponseData };
1214
+ export type { ApiResponse, Contact, FetchAPI$1 as FetchAPI, FormbricksAPIOptions, FormbricksRuntime, FormbricksRuntimeOptions, FormbricksWebhook, OperationId, ResponseRecord, Settings, SqliteClient, SupportedOperationId, Survey };
package/dist/index.js CHANGED
@@ -1,13 +1,12 @@
1
1
  import {
2
+ CORPUS_SURVEYS,
2
3
  DEFAULT_SETTINGS,
3
- DEVELOPMENT_ENVIRONMENT_ID,
4
+ ENVIRONMENT_ID,
4
5
  FORMBRICKS_NAMESPACE,
5
6
  FORMBRICKS_PRESETS,
6
7
  FormbricksAPI,
7
- PRODUCTION_ENVIRONMENT_ID,
8
- PROD_CLONE_EXPORTED_AT,
9
- PROD_CLONE_SURVEYS,
10
8
  WEBHOOK_PATH,
9
+ WORKSPACE_ID,
11
10
  createRuntime,
12
11
  document,
13
12
  formbricksCredential,
@@ -15,17 +14,16 @@ import {
15
14
  operationIds,
16
15
  supportedOperationIds,
17
16
  validateResponseData
18
- } from "./chunk-FZI2QHRQ.js";
17
+ } from "./chunk-ZFDC3GHV.js";
19
18
  export {
19
+ CORPUS_SURVEYS,
20
20
  DEFAULT_SETTINGS,
21
- DEVELOPMENT_ENVIRONMENT_ID,
21
+ ENVIRONMENT_ID,
22
22
  FORMBRICKS_NAMESPACE,
23
23
  FORMBRICKS_PRESETS,
24
24
  FormbricksAPI,
25
- PRODUCTION_ENVIRONMENT_ID,
26
- PROD_CLONE_EXPORTED_AT,
27
- PROD_CLONE_SURVEYS,
28
25
  WEBHOOK_PATH,
26
+ WORKSPACE_ID,
29
27
  createRuntime,
30
28
  document,
31
29
  formbricksCredential,
package/dist/server.d.ts CHANGED
@@ -1342,14 +1342,20 @@ interface FetchAPI {
1342
1342
  fetch(request: Request): Promise<Response>;
1343
1343
  }
1344
1344
 
1345
- /** A survey definition, passed through as Formbricks serves it (blocks, elements, logic, …). */
1345
+ /** A survey definition, passed through as Formbricks serves it (blocks, elements, endings, …). */
1346
1346
  type Survey = Record<string, unknown> & {
1347
1347
  id: string;
1348
1348
  name: string;
1349
1349
  type: string;
1350
1350
  status: string;
1351
- /** `null` for the shared fixture surveys, which every configured environment serves. */
1352
- environmentId?: string | null;
1351
+ /** `null` for the shared corpus surveys, which every configured workspace serves. */
1352
+ workspaceId?: string | null;
1353
+ };
1354
+ /** A contact (`PUT /__admin/contacts`); `attributes.userId` becomes the response's `contact.userId`. */
1355
+ type Contact = {
1356
+ id: string;
1357
+ workspaceId: string | null;
1358
+ attributes: Record<string, string>;
1353
1359
  };
1354
1360
  /** One stored response, in Formbricks' `TResponse` shape. */
1355
1361
  type ResponseRecord = {
@@ -1357,11 +1363,11 @@ type ResponseRecord = {
1357
1363
  createdAt: string;
1358
1364
  updatedAt: string;
1359
1365
  surveyId: string;
1360
- environmentId: string;
1366
+ workspaceId: string;
1361
1367
  displayId: string | null;
1362
1368
  contact: {
1363
1369
  id: string;
1364
- userId: string;
1370
+ userId?: string;
1365
1371
  } | null;
1366
1372
  contactAttributes: Record<string, string> | null;
1367
1373
  finished: boolean;
@@ -1376,24 +1382,22 @@ type ResponseRecord = {
1376
1382
  };
1377
1383
  /** Per-namespace knobs, set through `PUT /__admin/settings`; cleared on reset. */
1378
1384
  type Settings = {
1379
- /** Environment ids that serve the shared fixture surveys. */
1380
- environments: string[];
1385
+ /** Workspace ids that exist and serve the shared corpus surveys. */
1386
+ workspaces: string[];
1387
+ /** Pre-Formbricks-5 environment ids, each an alias of a workspace (`{envId: workspaceId}`). */
1388
+ legacyEnvironmentIds: Record<string, string>;
1381
1389
  /** Accepted management API keys; empty means any non-empty `x-api-key` works. */
1382
1390
  apiKeys: string[];
1383
1391
  /** The `webhookId` put in webhook bodies. */
1384
1392
  webhookId: string;
1385
- /** Whether a `userId` on a response finds-or-creates a contact (the fork's behaviour). */
1393
+ /** Contacts are an Enterprise feature: when off, a response with a `contactId` is 403. */
1386
1394
  contactsEnabled: boolean;
1387
1395
  };
1388
1396
  declare class FormbricksState {
1389
1397
  private readonly seed;
1390
1398
  readonly surveys: Collection<Survey>;
1391
1399
  readonly responses: Collection<ResponseRecord>;
1392
- readonly contacts: Collection<{
1393
- id: string;
1394
- environmentId: string;
1395
- userId: string;
1396
- }>;
1400
+ readonly contacts: Collection<Contact>;
1397
1401
  readonly settings: Collection<Settings>;
1398
1402
  readonly ids: IdSequence;
1399
1403
  constructor(sqlite: SqliteClient, namespace: string, seed: {
@@ -1405,22 +1409,25 @@ declare class FormbricksState {
1405
1409
  update(patch: Partial<Settings>): Settings;
1406
1410
  /** Formbricks ids are cuid2: lower-case alphanumerics starting with a letter, 25 long. */
1407
1411
  nextId(): string;
1408
- knownEnvironment(environmentId: string): boolean;
1412
+ /**
1413
+ * `resolveClientApiIds`: a workspace id, or a legacy environment id, to its workspace id
1414
+ * (`undefined` when neither is known).
1415
+ */
1416
+ resolveWorkspace(id: string): string | undefined;
1417
+ /** The v1 `environmentId` of a workspace: its legacy environment id, else its own id. */
1418
+ legacyEnvironmentId(workspaceId: string): string;
1409
1419
  allSurveys(): Survey[];
1410
- /** Surveys an environment serves: its own, plus the shared fixture when it is configured. */
1411
- surveysOf(environmentId: string): Survey[];
1412
- /** Whether a survey belongs to an environment (the fork's `survey.environmentId` check). */
1413
- belongsTo(survey: Survey, environmentId: string): boolean;
1414
- /** The fork's find-or-create contact for a response `userId` (the member's email). */
1415
- contactFor(environmentId: string, userId: string): {
1416
- id: string;
1417
- userId: string;
1418
- };
1420
+ /** Surveys a workspace serves: its own, plus the shared corpus when it is configured. */
1421
+ surveysOf(workspaceId: string): Survey[];
1422
+ /** Whether a survey belongs to a workspace (`survey.workspaceId !== workspaceId` check). */
1423
+ belongsTo(survey: Survey, workspaceId: string): boolean;
1424
+ /** `getContact(contactId, workspaceId)`: a contact of that workspace (or a shared one). */
1425
+ contactOf(contactId: string, workspaceId: string): Contact | undefined;
1419
1426
  }
1420
1427
 
1421
1428
  /** The response as the API (and the webhook) renders it: `TResponse`. */
1422
- type ApiResponse = Omit<ResponseRecord, "environmentId">;
1423
- /** The body Formbricks' pipeline posts to a webhook (`app/api/(internal)/pipeline/route.ts`). */
1429
+ type ApiResponse = Omit<ResponseRecord, "workspaceId">;
1430
+ /** The body Formbricks' response pipeline posts to a webhook (`process-response-pipeline-job.ts`). */
1424
1431
  type FormbricksWebhook = {
1425
1432
  webhookId: string;
1426
1433
  event: "responseCreated" | "responseFinished";
@@ -1435,15 +1442,15 @@ type FormbricksWebhook = {
1435
1442
  };
1436
1443
  };
1437
1444
  type FormbricksAPIOptions = APIOptions & {
1438
- /** Surveys every namespace starts with. Default: our production clone. */
1445
+ /** Surveys every namespace starts with. Default: the synthetic corpus (`CORPUS_SURVEYS`). */
1439
1446
  surveys?: readonly Survey[];
1440
1447
  settings?: Partial<Settings>;
1441
1448
  /** Called for every pipeline event; the runtime signs and delivers it. */
1442
1449
  onWebhook?: (event: FormbricksWebhook) => void;
1443
1450
  };
1444
1451
  /**
1445
- * Stateful mock of Formbricks (our fork): environment state and response creation for the
1446
- * client SDK / member app, the v1 management API, and the `responseFinished` webhook.
1452
+ * Stateful mock of open-source Formbricks: the client environment state and response creation
1453
+ * the JS SDK uses, the v1 management API, and the response pipeline's webhooks.
1447
1454
  */
1448
1455
  declare class FormbricksAPI implements FetchAPI {
1449
1456
  readonly app: Hono;
@@ -1456,14 +1463,20 @@ declare class FormbricksAPI implements FetchAPI {
1456
1463
  fetch(request: Request): Promise<Response>;
1457
1464
  reset(): Promise<void>;
1458
1465
  private iso;
1459
- /** A survey as the API serves it (no internal `environmentId: null`). */
1460
- private wireSurvey;
1466
+ /**
1467
+ * A survey as the v1 management API serves it: `questions` derived from `blocks`, the owning
1468
+ * `workspaceId` and its legacy `environmentId`, and `projectOverwrites`. Shared corpus surveys
1469
+ * are reported under the first configured workspace.
1470
+ */
1471
+ wireSurvey(survey: Survey): Survey;
1461
1472
  render(record: ResponseRecord, context?: OperationContext): ApiResponse;
1462
1473
  private environmentState;
1463
1474
  private createResponse;
1464
- /** Emit a pipeline event for a stored response (also used by `/__admin/responses/:id/finish`). */
1475
+ /** Emit a pipeline event (`responseCreated` / `responseFinished`) for a stored response. */
1465
1476
  pipeline(event: FormbricksWebhook["event"], record: ResponseRecord, survey: Survey): void;
1466
1477
  private listResponses;
1478
+ /** `getSurveys(workspaceIds, limit, offset)`: newest `updatedAt` first. */
1479
+ private listSurveys;
1467
1480
  private createSurvey;
1468
1481
  responses(): ApiResponse[];
1469
1482
  }
@@ -1481,8 +1494,8 @@ type FormbricksRuntimeOptions = {
1481
1494
  surveys?: readonly Survey[];
1482
1495
  settings?: Partial<Settings>;
1483
1496
  /**
1484
- * Where webhooks go: `url` carries our `?token=<FORMBRICKS_WEBHOOK_SECRET>`; `secret` (a
1485
- * `whsec_…` Standard Webhooks key) signs `webhook-signature`; `events` defaults to
1497
+ * Where webhooks go: `url` (any query, e.g. a `?token=` your receiver checks, is kept); `secret`
1498
+ * (a `whsec_…` Standard Webhooks key) signs `webhook-signature`; `events` defaults to
1486
1499
  * `["responseFinished"]` (add `"responseCreated"` for both).
1487
1500
  */
1488
1501
  webhooks?: Omit<WebhookEndpoint, "id"> & WebhookHubOptionsSubset;
package/dist/server.js CHANGED
@@ -2,8 +2,8 @@ import {
2
2
  DEFAULT_PORT,
3
3
  createServer,
4
4
  serveTarget
5
- } from "./chunk-2FV4RSDZ.js";
6
- import "./chunk-FZI2QHRQ.js";
5
+ } from "./chunk-RITQFAWR.js";
6
+ import "./chunk-ZFDC3GHV.js";
7
7
  export {
8
8
  DEFAULT_PORT,
9
9
  createServer,
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@crvouga/mockingbird-service-formbricks",
3
- "version": "0.2.0",
4
- "description": "Stateful mock of Formbricks (Geviti fork): client environment state seeded from our production survey clone, response creation with the fork's validation errors, the v1 management API, the widget script, and responseFinished webhooks.",
3
+ "version": "1.0.0",
4
+ "description": "Stateful mock of open-source Formbricks: the client environment state (seeded with a synthetic survey corpus), response creation with upstream's validation and {code, message, details} errors, the v1 management API, the widget script, and signed response webhooks.",
5
5
  "license": "MIT",
6
6
  "type": "module",
7
7
  "sideEffects": false,
@@ -52,6 +52,10 @@
52
52
  "layer": "service",
53
53
  "category": "productivity",
54
54
  "displayName": "Formbricks",
55
+ "vendor": {
56
+ "website": "https://formbricks.com",
57
+ "docs": "https://formbricks.com/docs"
58
+ },
55
59
  "status": "wip"
56
60
  },
57
61
  "scripts": {
@@ -67,7 +71,7 @@
67
71
  "pack:check": "bun ../../../scripts/pack-check.ts"
68
72
  },
69
73
  "dependencies": {
70
- "@crvouga/mockingbird-service-sqlite": "0.3.0",
74
+ "@crvouga/mockingbird-service-sqlite": "1.0.0",
71
75
  "hono": "4.11.9"
72
76
  },
73
77
  "devDependencies": {