@forumone/throughline-forms 0.0.1 → 0.2.1

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.
Files changed (116) hide show
  1. package/CHANGELOG.md +30 -0
  2. package/LICENSE +21 -0
  3. package/README.md +132 -40
  4. package/dist/destinations.d.ts +26 -0
  5. package/dist/destinations.d.ts.map +1 -0
  6. package/dist/destinations.js +36 -0
  7. package/dist/destinations.js.map +1 -0
  8. package/dist/functions/_shared.d.ts +13 -0
  9. package/dist/functions/_shared.d.ts.map +1 -0
  10. package/dist/functions/_shared.js +44 -0
  11. package/dist/functions/_shared.js.map +1 -0
  12. package/dist/functions/email-destination.d.ts +25 -0
  13. package/dist/functions/email-destination.d.ts.map +1 -0
  14. package/dist/functions/email-destination.js +75 -0
  15. package/dist/functions/email-destination.js.map +1 -0
  16. package/dist/functions/fan-out.d.ts +24 -0
  17. package/dist/functions/fan-out.d.ts.map +1 -0
  18. package/dist/functions/fan-out.js +71 -0
  19. package/dist/functions/fan-out.js.map +1 -0
  20. package/dist/functions/index.d.ts +9 -0
  21. package/dist/functions/index.d.ts.map +1 -0
  22. package/dist/functions/index.js +5 -0
  23. package/dist/functions/index.js.map +1 -0
  24. package/dist/functions/submitter-confirmation.d.ts +25 -0
  25. package/dist/functions/submitter-confirmation.d.ts.map +1 -0
  26. package/dist/functions/submitter-confirmation.js +76 -0
  27. package/dist/functions/submitter-confirmation.js.map +1 -0
  28. package/dist/functions/webhook-destination.d.ts +20 -0
  29. package/dist/functions/webhook-destination.d.ts.map +1 -0
  30. package/dist/functions/webhook-destination.js +74 -0
  31. package/dist/functions/webhook-destination.js.map +1 -0
  32. package/dist/index.d.ts +12 -0
  33. package/dist/index.d.ts.map +1 -0
  34. package/dist/index.js +8 -0
  35. package/dist/index.js.map +1 -0
  36. package/dist/options.d.ts +74 -0
  37. package/dist/options.d.ts.map +1 -0
  38. package/dist/options.js +61 -0
  39. package/dist/options.js.map +1 -0
  40. package/dist/plugin.d.ts +19 -0
  41. package/dist/plugin.d.ts.map +1 -0
  42. package/dist/plugin.js +180 -0
  43. package/dist/plugin.js.map +1 -0
  44. package/dist/policy-fields.d.ts +18 -0
  45. package/dist/policy-fields.d.ts.map +1 -0
  46. package/dist/policy-fields.js +115 -0
  47. package/dist/policy-fields.js.map +1 -0
  48. package/dist/submit/endpoint.d.ts +16 -0
  49. package/dist/submit/endpoint.d.ts.map +1 -0
  50. package/dist/submit/endpoint.js +116 -0
  51. package/dist/submit/endpoint.js.map +1 -0
  52. package/dist/submit/ip.d.ts +20 -0
  53. package/dist/submit/ip.d.ts.map +1 -0
  54. package/dist/submit/ip.js +48 -0
  55. package/dist/submit/ip.js.map +1 -0
  56. package/dist/submit/rate-limit.d.ts +23 -0
  57. package/dist/submit/rate-limit.d.ts.map +1 -0
  58. package/dist/submit/rate-limit.js +27 -0
  59. package/dist/submit/rate-limit.js.map +1 -0
  60. package/dist/submit/spam.d.ts +10 -0
  61. package/dist/submit/spam.d.ts.map +1 -0
  62. package/dist/submit/spam.js +16 -0
  63. package/dist/submit/spam.js.map +1 -0
  64. package/dist/templates/FormSubmission.d.ts +21 -0
  65. package/dist/templates/FormSubmission.d.ts.map +1 -0
  66. package/dist/templates/FormSubmission.js +32 -0
  67. package/dist/templates/FormSubmission.js.map +1 -0
  68. package/dist/templates/SubmitterConfirmation.d.ts +18 -0
  69. package/dist/templates/SubmitterConfirmation.d.ts.map +1 -0
  70. package/dist/templates/SubmitterConfirmation.js +14 -0
  71. package/dist/templates/SubmitterConfirmation.js.map +1 -0
  72. package/dist/templates/_layout.d.ts +14 -0
  73. package/dist/templates/_layout.d.ts.map +1 -0
  74. package/dist/templates/_layout.js +34 -0
  75. package/dist/templates/_layout.js.map +1 -0
  76. package/dist/templates/index.d.ts +7 -0
  77. package/dist/templates/index.d.ts.map +1 -0
  78. package/dist/templates/index.js +4 -0
  79. package/dist/templates/index.js.map +1 -0
  80. package/dist/tools/_field-schema.d.ts +68 -0
  81. package/dist/tools/_field-schema.d.ts.map +1 -0
  82. package/dist/tools/_field-schema.js +62 -0
  83. package/dist/tools/_field-schema.js.map +1 -0
  84. package/dist/tools/access.d.ts +7 -0
  85. package/dist/tools/access.d.ts.map +1 -0
  86. package/dist/tools/access.js +16 -0
  87. package/dist/tools/access.js.map +1 -0
  88. package/dist/tools/create-form.d.ts +138 -0
  89. package/dist/tools/create-form.d.ts.map +1 -0
  90. package/dist/tools/create-form.js +96 -0
  91. package/dist/tools/create-form.js.map +1 -0
  92. package/dist/tools/get-form-submissions.d.ts +27 -0
  93. package/dist/tools/get-form-submissions.d.ts.map +1 -0
  94. package/dist/tools/get-form-submissions.js +47 -0
  95. package/dist/tools/get-form-submissions.js.map +1 -0
  96. package/dist/tools/index.d.ts +14 -0
  97. package/dist/tools/index.d.ts.map +1 -0
  98. package/dist/tools/index.js +8 -0
  99. package/dist/tools/index.js.map +1 -0
  100. package/dist/tools/list-allowed-destinations.d.ts +10 -0
  101. package/dist/tools/list-allowed-destinations.d.ts.map +1 -0
  102. package/dist/tools/list-allowed-destinations.js +14 -0
  103. package/dist/tools/list-allowed-destinations.js.map +1 -0
  104. package/dist/tools/update-form-destinations.d.ts +45 -0
  105. package/dist/tools/update-form-destinations.d.ts.map +1 -0
  106. package/dist/tools/update-form-destinations.js +75 -0
  107. package/dist/tools/update-form-destinations.js.map +1 -0
  108. package/dist/tools/update-form-fields.d.ts +101 -0
  109. package/dist/tools/update-form-fields.d.ts.map +1 -0
  110. package/dist/tools/update-form-fields.js +65 -0
  111. package/dist/tools/update-form-fields.js.map +1 -0
  112. package/dist/tools/validate-form.d.ts +127 -0
  113. package/dist/tools/validate-form.d.ts.map +1 -0
  114. package/dist/tools/validate-form.js +50 -0
  115. package/dist/tools/validate-form.js.map +1 -0
  116. package/package.json +71 -7
@@ -0,0 +1,4 @@
1
+ export { FormsLayout } from './_layout.js';
2
+ export { FormSubmissionEmail } from './FormSubmission.js';
3
+ export { SubmitterConfirmationEmail } from './SubmitterConfirmation.js';
4
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/templates/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,cAAc,CAAA;AAG1C,OAAO,EAAE,mBAAmB,EAAE,MAAM,qBAAqB,CAAA;AAGzD,OAAO,EAAE,0BAA0B,EAAE,MAAM,4BAA4B,CAAA"}
@@ -0,0 +1,68 @@
1
+ import { z } from 'zod';
2
+ declare const FIELD_BLOCK_TYPES: readonly ["text", "textarea", "email", "select", "checkbox", "number"];
3
+ export type FormFieldBlockType = (typeof FIELD_BLOCK_TYPES)[number];
4
+ export declare const FieldSchema: z.ZodObject<{
5
+ blockType: z.ZodEnum<["text", "textarea", "email", "select", "checkbox", "number"]>;
6
+ /**
7
+ * Snake-case identifier. Form Builder's submission rows key on this, so
8
+ * dashes / spaces / unicode would break downstream queries.
9
+ */
10
+ name: z.ZodString;
11
+ /** Visible label. Required — accessibility. */
12
+ label: z.ZodString;
13
+ required: z.ZodDefault<z.ZodBoolean>;
14
+ defaultValue: z.ZodOptional<z.ZodString>;
15
+ options: z.ZodOptional<z.ZodArray<z.ZodObject<{
16
+ label: z.ZodString;
17
+ value: z.ZodString;
18
+ }, "strip", z.ZodTypeAny, {
19
+ label: string;
20
+ value: string;
21
+ }, {
22
+ label: string;
23
+ value: string;
24
+ }>, "many">>;
25
+ }, "strip", z.ZodTypeAny, {
26
+ label: string;
27
+ name: string;
28
+ required: boolean;
29
+ blockType: "number" | "email" | "checkbox" | "select" | "textarea" | "text";
30
+ defaultValue?: string | undefined;
31
+ options?: {
32
+ label: string;
33
+ value: string;
34
+ }[] | undefined;
35
+ }, {
36
+ label: string;
37
+ name: string;
38
+ blockType: "number" | "email" | "checkbox" | "select" | "textarea" | "text";
39
+ defaultValue?: string | undefined;
40
+ required?: boolean | undefined;
41
+ options?: {
42
+ label: string;
43
+ value: string;
44
+ }[] | undefined;
45
+ }>;
46
+ export type FieldDefinition = z.infer<typeof FieldSchema>;
47
+ /**
48
+ * Hard validation that runs after Zod has parsed the input. Catches the
49
+ * cross-field rules that don't fit cleanly in a per-field schema:
50
+ * - select fields must carry options
51
+ * - submitterConfirmation must reference an actual email-typed field
52
+ */
53
+ export declare function validateFieldSet(fields: FieldDefinition[]): {
54
+ ok: boolean;
55
+ reason?: string;
56
+ };
57
+ export interface SubmitterConfirmationConfig {
58
+ enabled: boolean;
59
+ emailFieldName?: string | undefined;
60
+ subject?: string | undefined;
61
+ body?: string | undefined;
62
+ }
63
+ export declare function validateSubmitterConfirmation(config: SubmitterConfirmationConfig | undefined, fields: FieldDefinition[]): {
64
+ ok: boolean;
65
+ reason?: string;
66
+ };
67
+ export {};
68
+ //# sourceMappingURL=_field-schema.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"_field-schema.d.ts","sourceRoot":"","sources":["../../src/tools/_field-schema.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAA;AAEvB,QAAA,MAAM,iBAAiB,wEAAyE,CAAA;AAEhG,MAAM,MAAM,kBAAkB,GAAG,CAAC,OAAO,iBAAiB,CAAC,CAAC,MAAM,CAAC,CAAA;AAEnE,eAAO,MAAM,WAAW;;IAEtB;;;OAGG;;IAEH,+CAA+C;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAQ/C,CAAA;AAEF,MAAM,MAAM,eAAe,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,WAAW,CAAC,CAAA;AAEzD;;;;;GAKG;AACH,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,eAAe,EAAE,GAAG;IAAE,EAAE,EAAE,OAAO,CAAC;IAAC,MAAM,CAAC,EAAE,MAAM,CAAA;CAAE,CAY5F;AAED,MAAM,WAAW,2BAA2B;IAC1C,OAAO,EAAE,OAAO,CAAA;IAChB,cAAc,CAAC,EAAE,MAAM,GAAG,SAAS,CAAA;IACnC,OAAO,CAAC,EAAE,MAAM,GAAG,SAAS,CAAA;IAC5B,IAAI,CAAC,EAAE,MAAM,GAAG,SAAS,CAAA;CAC1B;AAED,wBAAgB,6BAA6B,CAC3C,MAAM,EAAE,2BAA2B,GAAG,SAAS,EAC/C,MAAM,EAAE,eAAe,EAAE,GACxB;IAAE,EAAE,EAAE,OAAO,CAAC;IAAC,MAAM,CAAC,EAAE,MAAM,CAAA;CAAE,CAsBlC"}
@@ -0,0 +1,62 @@
1
+ import { z } from 'zod';
2
+ const FIELD_BLOCK_TYPES = ['text', 'textarea', 'email', 'select', 'checkbox', 'number'];
3
+ export const FieldSchema = z.object({
4
+ blockType: z.enum(FIELD_BLOCK_TYPES),
5
+ /**
6
+ * Snake-case identifier. Form Builder's submission rows key on this, so
7
+ * dashes / spaces / unicode would break downstream queries.
8
+ */
9
+ name: z.string().regex(/^[a-z][a-z0-9_]*$/, 'Field names must be snake_case (a-z, 0-9, _)'),
10
+ /** Visible label. Required — accessibility. */
11
+ label: z.string().min(1, 'Field labels are required for accessibility'),
12
+ required: z.boolean().default(false),
13
+ defaultValue: z.string().optional(),
14
+ options: z
15
+ .array(z.object({ label: z.string(), value: z.string() }))
16
+ .optional()
17
+ .describe('Required for select fields; ignored otherwise'),
18
+ });
19
+ /**
20
+ * Hard validation that runs after Zod has parsed the input. Catches the
21
+ * cross-field rules that don't fit cleanly in a per-field schema:
22
+ * - select fields must carry options
23
+ * - submitterConfirmation must reference an actual email-typed field
24
+ */
25
+ export function validateFieldSet(fields) {
26
+ const seen = new Set();
27
+ for (const field of fields) {
28
+ if (seen.has(field.name)) {
29
+ return { ok: false, reason: `Duplicate field name "${field.name}".` };
30
+ }
31
+ seen.add(field.name);
32
+ if (field.blockType === 'select' && (!field.options || field.options.length === 0)) {
33
+ return { ok: false, reason: `Select field "${field.name}" requires at least one option.` };
34
+ }
35
+ }
36
+ return { ok: true };
37
+ }
38
+ export function validateSubmitterConfirmation(config, fields) {
39
+ if (!config?.enabled)
40
+ return { ok: true };
41
+ if (!config.emailFieldName) {
42
+ return {
43
+ ok: false,
44
+ reason: 'submitterConfirmation.emailFieldName is required when confirmation is enabled.',
45
+ };
46
+ }
47
+ const field = fields.find((f) => f.name === config.emailFieldName);
48
+ if (!field) {
49
+ return {
50
+ ok: false,
51
+ reason: `submitterConfirmation.emailFieldName references "${config.emailFieldName}", which is not in the form's fields.`,
52
+ };
53
+ }
54
+ if (field.blockType !== 'email') {
55
+ return {
56
+ ok: false,
57
+ reason: `submitterConfirmation.emailFieldName must point to a field with blockType="email"; "${field.name}" is "${field.blockType}".`,
58
+ };
59
+ }
60
+ return { ok: true };
61
+ }
62
+ //# sourceMappingURL=_field-schema.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"_field-schema.js","sourceRoot":"","sources":["../../src/tools/_field-schema.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,7 @@
1
+ import type { McpToolContext } from '@forumone/throughline-plugin-contract';
2
+ export declare function isFormsAuthor(ctx: McpToolContext): boolean;
3
+ export declare function isPiiReader(ctx: McpToolContext): boolean;
4
+ export declare function deniedEnvelope(reason: string): {
5
+ error: string;
6
+ };
7
+ //# sourceMappingURL=access.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"access.d.ts","sourceRoot":"","sources":["../../src/tools/access.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,uCAAuC,CAAA;AAE3E,wBAAgB,aAAa,CAAC,GAAG,EAAE,cAAc,GAAG,OAAO,CAI1D;AAED,wBAAgB,WAAW,CAAC,GAAG,EAAE,cAAc,GAAG,OAAO,CAIxD;AAED,wBAAgB,cAAc,CAAC,MAAM,EAAE,MAAM,GAAG;IAAE,KAAK,EAAE,MAAM,CAAA;CAAE,CAEhE"}
@@ -0,0 +1,16 @@
1
+ export function isFormsAuthor(ctx) {
2
+ if (!ctx.user)
3
+ return false;
4
+ const roles = ctx.user.roles;
5
+ return roles.includes('admin') || roles.includes('editor');
6
+ }
7
+ export function isPiiReader(ctx) {
8
+ if (!ctx.user)
9
+ return false;
10
+ const roles = ctx.user.roles;
11
+ return roles.includes('admin') || roles.includes('form-admin');
12
+ }
13
+ export function deniedEnvelope(reason) {
14
+ return { error: reason };
15
+ }
16
+ //# sourceMappingURL=access.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"access.js","sourceRoot":"","sources":["../../src/tools/access.ts"],"names":[],"mappings":"AAEA,MAAM,UAAU,aAAa,CAAC,GAAmB;IAC/C,IAAI,CAAC,GAAG,CAAC,IAAI;QAAE,OAAO,KAAK,CAAA;IAC3B,MAAM,KAAK,GAAG,GAAG,CAAC,IAAI,CAAC,KAAK,CAAA;IAC5B,OAAO,KAAK,CAAC,QAAQ,CAAC,OAAO,CAAC,IAAI,KAAK,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAA;AAC5D,CAAC;AAED,MAAM,UAAU,WAAW,CAAC,GAAmB;IAC7C,IAAI,CAAC,GAAG,CAAC,IAAI;QAAE,OAAO,KAAK,CAAA;IAC3B,MAAM,KAAK,GAAG,GAAG,CAAC,IAAI,CAAC,KAAK,CAAA;IAC5B,OAAO,KAAK,CAAC,QAAQ,CAAC,OAAO,CAAC,IAAI,KAAK,CAAC,QAAQ,CAAC,YAAY,CAAC,CAAA;AAChE,CAAC;AAED,MAAM,UAAU,cAAc,CAAC,MAAc;IAC3C,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,CAAA;AAC1B,CAAC"}
@@ -0,0 +1,138 @@
1
+ import { z } from 'zod';
2
+ import type { Payload } from 'payload';
3
+ import type { McpToolDefinition } from '@forumone/throughline-plugin-contract';
4
+ import type { ResolvedFormsConfig } from '../options.js';
5
+ declare const inputSchema: z.ZodObject<{
6
+ title: z.ZodString;
7
+ intent: z.ZodString;
8
+ fields: z.ZodArray<z.ZodObject<{
9
+ blockType: z.ZodEnum<["text", "textarea", "email", "select", "checkbox", "number"]>;
10
+ name: z.ZodString;
11
+ label: z.ZodString;
12
+ required: z.ZodDefault<z.ZodBoolean>;
13
+ defaultValue: z.ZodOptional<z.ZodString>;
14
+ options: z.ZodOptional<z.ZodArray<z.ZodObject<{
15
+ label: z.ZodString;
16
+ value: z.ZodString;
17
+ }, "strip", z.ZodTypeAny, {
18
+ label: string;
19
+ value: string;
20
+ }, {
21
+ label: string;
22
+ value: string;
23
+ }>, "many">>;
24
+ }, "strip", z.ZodTypeAny, {
25
+ label: string;
26
+ name: string;
27
+ required: boolean;
28
+ blockType: "number" | "email" | "checkbox" | "select" | "textarea" | "text";
29
+ defaultValue?: string | undefined;
30
+ options?: {
31
+ label: string;
32
+ value: string;
33
+ }[] | undefined;
34
+ }, {
35
+ label: string;
36
+ name: string;
37
+ blockType: "number" | "email" | "checkbox" | "select" | "textarea" | "text";
38
+ defaultValue?: string | undefined;
39
+ required?: boolean | undefined;
40
+ options?: {
41
+ label: string;
42
+ value: string;
43
+ }[] | undefined;
44
+ }>, "many">;
45
+ destinationLabels: z.ZodArray<z.ZodString, "many">;
46
+ submitterConfirmation: z.ZodOptional<z.ZodObject<{
47
+ enabled: z.ZodBoolean;
48
+ emailFieldName: z.ZodOptional<z.ZodString>;
49
+ subject: z.ZodOptional<z.ZodString>;
50
+ body: z.ZodOptional<z.ZodString>;
51
+ }, "strip", z.ZodTypeAny, {
52
+ enabled: boolean;
53
+ emailFieldName?: string | undefined;
54
+ subject?: string | undefined;
55
+ body?: string | undefined;
56
+ }, {
57
+ enabled: boolean;
58
+ emailFieldName?: string | undefined;
59
+ subject?: string | undefined;
60
+ body?: string | undefined;
61
+ }>>;
62
+ privacyNoticeOverride: z.ZodOptional<z.ZodString>;
63
+ } & {
64
+ _meta: z.ZodOptional<z.ZodObject<{
65
+ userPrompt: z.ZodOptional<z.ZodString>;
66
+ reasoning: z.ZodOptional<z.ZodString>;
67
+ changesSummary: z.ZodOptional<z.ZodString>;
68
+ }, "strip", z.ZodTypeAny, {
69
+ reasoning?: string | undefined;
70
+ changesSummary?: string | undefined;
71
+ userPrompt?: string | undefined;
72
+ }, {
73
+ reasoning?: string | undefined;
74
+ changesSummary?: string | undefined;
75
+ userPrompt?: string | undefined;
76
+ }>>;
77
+ }, "strip", z.ZodTypeAny, {
78
+ fields: {
79
+ label: string;
80
+ name: string;
81
+ required: boolean;
82
+ blockType: "number" | "email" | "checkbox" | "select" | "textarea" | "text";
83
+ defaultValue?: string | undefined;
84
+ options?: {
85
+ label: string;
86
+ value: string;
87
+ }[] | undefined;
88
+ }[];
89
+ title: string;
90
+ intent: string;
91
+ destinationLabels: string[];
92
+ submitterConfirmation?: {
93
+ enabled: boolean;
94
+ emailFieldName?: string | undefined;
95
+ subject?: string | undefined;
96
+ body?: string | undefined;
97
+ } | undefined;
98
+ privacyNoticeOverride?: string | undefined;
99
+ _meta?: {
100
+ reasoning?: string | undefined;
101
+ changesSummary?: string | undefined;
102
+ userPrompt?: string | undefined;
103
+ } | undefined;
104
+ }, {
105
+ fields: {
106
+ label: string;
107
+ name: string;
108
+ blockType: "number" | "email" | "checkbox" | "select" | "textarea" | "text";
109
+ defaultValue?: string | undefined;
110
+ required?: boolean | undefined;
111
+ options?: {
112
+ label: string;
113
+ value: string;
114
+ }[] | undefined;
115
+ }[];
116
+ title: string;
117
+ intent: string;
118
+ destinationLabels: string[];
119
+ submitterConfirmation?: {
120
+ enabled: boolean;
121
+ emailFieldName?: string | undefined;
122
+ subject?: string | undefined;
123
+ body?: string | undefined;
124
+ } | undefined;
125
+ privacyNoticeOverride?: string | undefined;
126
+ _meta?: {
127
+ reasoning?: string | undefined;
128
+ changesSummary?: string | undefined;
129
+ userPrompt?: string | undefined;
130
+ } | undefined;
131
+ }>;
132
+ export interface CreateFormDeps {
133
+ payload: Payload;
134
+ resolved: ResolvedFormsConfig;
135
+ }
136
+ export declare function createCreateFormTool(deps: CreateFormDeps): McpToolDefinition<typeof inputSchema>;
137
+ export {};
138
+ //# sourceMappingURL=create-form.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"create-form.d.ts","sourceRoot":"","sources":["../../src/tools/create-form.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAA;AACvB,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,SAAS,CAAA;AACtC,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,uCAAuC,CAAA;AAE9E,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,eAAe,CAAA;AASxD,QAAA,MAAM,WAAW;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBAgCe,CAAC;sBAEV,CAAC;kBAEF,CAAC;;iBAAgD,CAAC;sBAA4C,CAAC;kBAAwC,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAb5J,CAAA;AAEF,MAAM,WAAW,cAAc;IAC7B,OAAO,EAAE,OAAO,CAAA;IAChB,QAAQ,EAAE,mBAAmB,CAAA;CAC9B;AAED,wBAAgB,oBAAoB,CAClC,IAAI,EAAE,cAAc,GACnB,iBAAiB,CAAC,OAAO,WAAW,CAAC,CAyEvC"}
@@ -0,0 +1,96 @@
1
+ import { z } from 'zod';
2
+ import { withMeta, getAuditWriter } from '@forumone/throughline-core';
3
+ import { validateDestinationLabel } from '../destinations.js';
4
+ import { FieldSchema, validateFieldSet, validateSubmitterConfirmation, } from './_field-schema.js';
5
+ import { deniedEnvelope, isFormsAuthor } from './access.js';
6
+ const inputSchema = withMeta({
7
+ title: z.string().min(1),
8
+ intent: z
9
+ .string()
10
+ .min(10)
11
+ .describe('Plain-language description of what this form is for. Surfaces in audit + admin.'),
12
+ fields: z.array(FieldSchema).min(1),
13
+ destinationLabels: z
14
+ .array(z.string())
15
+ .min(1)
16
+ .describe('Pre-authorized destination labels. Use list_allowed_destinations first.'),
17
+ submitterConfirmation: z
18
+ .object({
19
+ enabled: z.boolean(),
20
+ emailFieldName: z.string().optional(),
21
+ subject: z.string().optional(),
22
+ body: z.string().optional(),
23
+ })
24
+ .optional(),
25
+ privacyNoticeOverride: z
26
+ .string()
27
+ .optional()
28
+ .describe('Override the plugin-default privacy notice for this form only.'),
29
+ });
30
+ export function createCreateFormTool(deps) {
31
+ return {
32
+ name: 'create_form',
33
+ description: "Creates a form with privacy notice, consent checkbox, and honeypot enabled by default. Destinations must be selected from the allowlist (call list_allowed_destinations first). Field names must be snake_case; every field needs a label (accessibility); submitterConfirmation, if enabled, must point to an existing email-typed field on the form.",
34
+ inputSchema,
35
+ handler: async (input, ctx) => {
36
+ if (!isFormsAuthor(ctx)) {
37
+ return deniedEnvelope('Only admins and editors can create forms.');
38
+ }
39
+ for (const label of input.destinationLabels) {
40
+ const check = validateDestinationLabel(deps.resolved.options, label);
41
+ if (!check.ok)
42
+ return deniedEnvelope(check.reason ?? 'Destination not on the allowlist.');
43
+ }
44
+ const fieldCheck = validateFieldSet(input.fields);
45
+ if (!fieldCheck.ok)
46
+ return deniedEnvelope(fieldCheck.reason);
47
+ const confirmationCheck = validateSubmitterConfirmation(input.submitterConfirmation, input.fields);
48
+ if (!confirmationCheck.ok)
49
+ return deniedEnvelope(confirmationCheck.reason);
50
+ const policy = {
51
+ privacyNoticeText: input.privacyNoticeOverride ?? deps.resolved.defaultPrivacyNotice,
52
+ requiresExplicitConsent: deps.resolved.requireConsentByDefault,
53
+ consentLabel: 'I agree to the processing of my data as described above.',
54
+ spamProtection: { honeypot: true, rateLimit: deps.resolved.rateLimit },
55
+ destinations: input.destinationLabels.map((label) => ({ label, enabled: true })),
56
+ submitterConfirmation: input.submitterConfirmation ?? { enabled: false },
57
+ };
58
+ const created = (await deps.payload.create({
59
+ collection: deps.resolved.formsCollectionSlug,
60
+ data: {
61
+ title: input.title,
62
+ fields: input.fields,
63
+ policy,
64
+ },
65
+ }));
66
+ const auditWriter = getAuditWriter(deps.payload);
67
+ await auditWriter({
68
+ actor: {
69
+ type: 'user',
70
+ ...(ctx.user?.id ? { userId: ctx.user.id } : {}),
71
+ ...(ctx.user?.name ? { userName: ctx.user.name } : {}),
72
+ ...(ctx.apiKeyName ? { apiKeyName: ctx.apiKeyName } : {}),
73
+ },
74
+ action: 'form.created',
75
+ mcpServer: 'forms',
76
+ mcpTool: 'create_form',
77
+ targetCollection: deps.resolved.formsCollectionSlug,
78
+ targetId: String(created['id']),
79
+ targetTitle: input.title,
80
+ ...(input._meta?.userPrompt ? { prompt: input._meta.userPrompt } : {}),
81
+ ...(input._meta?.reasoning ? { reasoning: input._meta.reasoning } : {}),
82
+ changesSummary: `Created form "${input.title}" with ${input.fields.length} fields, destinations: ${input.destinationLabels.join(', ')}.`,
83
+ });
84
+ return {
85
+ formId: String(created['id']),
86
+ title: input.title,
87
+ destinations: input.destinationLabels,
88
+ privacyNotice: 'enabled',
89
+ consent: deps.resolved.requireConsentByDefault,
90
+ honeypot: true,
91
+ submitterConfirmation: input.submitterConfirmation?.enabled ?? false,
92
+ };
93
+ },
94
+ };
95
+ }
96
+ //# sourceMappingURL=create-form.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"create-form.js","sourceRoot":"","sources":["../../src/tools/create-form.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,27 @@
1
+ import { z } from 'zod';
2
+ import type { Payload } from 'payload';
3
+ import type { McpToolDefinition } from '@forumone/throughline-plugin-contract';
4
+ import type { ResolvedFormsConfig } from '../options.js';
5
+ declare const inputSchema: z.ZodObject<{
6
+ formId: z.ZodString;
7
+ limit: z.ZodOptional<z.ZodNumber>;
8
+ since: z.ZodOptional<z.ZodString>;
9
+ includePii: z.ZodOptional<z.ZodBoolean>;
10
+ }, "strip", z.ZodTypeAny, {
11
+ formId: string;
12
+ limit?: number | undefined;
13
+ since?: string | undefined;
14
+ includePii?: boolean | undefined;
15
+ }, {
16
+ formId: string;
17
+ limit?: number | undefined;
18
+ since?: string | undefined;
19
+ includePii?: boolean | undefined;
20
+ }>;
21
+ export interface GetFormSubmissionsDeps {
22
+ payload: Payload;
23
+ resolved: ResolvedFormsConfig;
24
+ }
25
+ export declare function createGetFormSubmissionsTool(deps: GetFormSubmissionsDeps): McpToolDefinition<typeof inputSchema>;
26
+ export {};
27
+ //# sourceMappingURL=get-form-submissions.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"get-form-submissions.d.ts","sourceRoot":"","sources":["../../src/tools/get-form-submissions.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAA;AACvB,OAAO,KAAK,EAAE,OAAO,EAAS,MAAM,SAAS,CAAA;AAC7C,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,uCAAuC,CAAA;AAC9E,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,eAAe,CAAA;AAGxD,QAAA,MAAM,WAAW;;;;;;;;;;;;;;;EAQf,CAAA;AAEF,MAAM,WAAW,sBAAsB;IACrC,OAAO,EAAE,OAAO,CAAA;IAChB,QAAQ,EAAE,mBAAmB,CAAA;CAC9B;AAED,wBAAgB,4BAA4B,CAC1C,IAAI,EAAE,sBAAsB,GAC3B,iBAAiB,CAAC,OAAO,WAAW,CAAC,CAuCvC"}
@@ -0,0 +1,47 @@
1
+ import { z } from 'zod';
2
+ import { deniedEnvelope, isFormsAuthor, isPiiReader } from './access.js';
3
+ const inputSchema = z.object({
4
+ formId: z.string(),
5
+ limit: z.number().int().positive().max(100).optional(),
6
+ since: z.string().datetime().optional().describe('ISO-8601 lower bound on createdAt.'),
7
+ includePii: z
8
+ .boolean()
9
+ .optional()
10
+ .describe('When true, returns the raw submission data. Requires admin or form-admin role.'),
11
+ });
12
+ export function createGetFormSubmissionsTool(deps) {
13
+ return {
14
+ name: 'get_form_submissions',
15
+ description: "Lists submissions for a form. Defaults to redacted output (counts + timestamps). Set includePii=true to read submission data; that requires admin or form-admin role.",
16
+ inputSchema,
17
+ handler: async (input, ctx) => {
18
+ if (!isFormsAuthor(ctx)) {
19
+ return deniedEnvelope('Only admins and editors can view submission counts.');
20
+ }
21
+ if (input.includePii === true && !isPiiReader(ctx)) {
22
+ return deniedEnvelope('Reading raw submission data requires admin or form-admin role; you have neither.');
23
+ }
24
+ const conditions = [{ form: { equals: input.formId } }];
25
+ if (input.since)
26
+ conditions.push({ createdAt: { greater_than_equal: input.since } });
27
+ const result = await deps.payload.find({
28
+ collection: deps.resolved.submissionsCollectionSlug,
29
+ where: { and: conditions },
30
+ sort: '-createdAt',
31
+ limit: input.limit ?? 20,
32
+ });
33
+ return {
34
+ formId: input.formId,
35
+ total: result.totalDocs,
36
+ returned: result.docs.length,
37
+ submissions: result.docs.map((doc) => ({
38
+ id: String(doc['id']),
39
+ receivedAt: typeof doc['createdAt'] === 'string' ? doc['createdAt'] : null,
40
+ consentGivenAt: typeof doc['consentGivenAt'] === 'string' ? doc['consentGivenAt'] : null,
41
+ data: input.includePii ? (doc['submissionData'] ?? null) : '[redacted — set includePii=true]',
42
+ })),
43
+ };
44
+ },
45
+ };
46
+ }
47
+ //# sourceMappingURL=get-form-submissions.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"get-form-submissions.js","sourceRoot":"","sources":["../../src/tools/get-form-submissions.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAA;AAIvB,OAAO,EAAE,cAAc,EAAE,aAAa,EAAE,WAAW,EAAE,MAAM,aAAa,CAAA;AAExE,MAAM,WAAW,GAAG,CAAC,CAAC,MAAM,CAAC;IAC3B,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE;IAClB,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,QAAQ,EAAE,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,QAAQ,EAAE;IACtD,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,oCAAoC,CAAC;IACtF,UAAU,EAAE,CAAC;SACV,OAAO,EAAE;SACT,QAAQ,EAAE;SACV,QAAQ,CAAC,gFAAgF,CAAC;CAC9F,CAAC,CAAA;AAOF,MAAM,UAAU,4BAA4B,CAC1C,IAA4B;IAE5B,OAAO;QACL,IAAI,EAAE,sBAAsB;QAC5B,WAAW,EACT,uKAAuK;QACzK,WAAW;QACX,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,GAAG,EAAE,EAAE;YAC5B,IAAI,CAAC,aAAa,CAAC,GAAG,CAAC,EAAE,CAAC;gBACxB,OAAO,cAAc,CAAC,qDAAqD,CAAC,CAAA;YAC9E,CAAC;YACD,IAAI,KAAK,CAAC,UAAU,KAAK,IAAI,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,EAAE,CAAC;gBACnD,OAAO,cAAc,CACnB,kFAAkF,CACnF,CAAA;YACH,CAAC;YAED,MAAM,UAAU,GAAY,CAAC,EAAE,IAAI,EAAE,EAAE,MAAM,EAAE,KAAK,CAAC,MAAM,EAAE,EAAE,CAAC,CAAA;YAChE,IAAI,KAAK,CAAC,KAAK;gBAAE,UAAU,CAAC,IAAI,CAAC,EAAE,SAAS,EAAE,EAAE,kBAAkB,EAAE,KAAK,CAAC,KAAK,EAAE,EAAE,CAAC,CAAA;YAEpF,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC;gBACrC,UAAU,EAAE,IAAI,CAAC,QAAQ,CAAC,yBAAyB;gBACnD,KAAK,EAAE,EAAE,GAAG,EAAE,UAAU,EAAE;gBAC1B,IAAI,EAAE,YAAY;gBAClB,KAAK,EAAE,KAAK,CAAC,KAAK,IAAI,EAAE;aACzB,CAAC,CAAA;YAEF,OAAO;gBACL,MAAM,EAAE,KAAK,CAAC,MAAM;gBACpB,KAAK,EAAE,MAAM,CAAC,SAAS;gBACvB,QAAQ,EAAE,MAAM,CAAC,IAAI,CAAC,MAAM;gBAC5B,WAAW,EAAG,MAAM,CAAC,IAAuC,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC;oBACzE,EAAE,EAAE,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;oBACrB,UAAU,EAAE,OAAO,GAAG,CAAC,WAAW,CAAC,KAAK,QAAQ,CAAC,CAAC,CAAC,GAAG,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,IAAI;oBAC1E,cAAc,EAAE,OAAO,GAAG,CAAC,gBAAgB,CAAC,KAAK,QAAQ,CAAC,CAAC,CAAC,GAAG,CAAC,gBAAgB,CAAC,CAAC,CAAC,CAAC,IAAI;oBACxF,IAAI,EAAE,KAAK,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,gBAAgB,CAAC,IAAI,IAAI,CAAC,CAAC,CAAC,CAAC,kCAAkC;iBAC9F,CAAC,CAAC;aACJ,CAAA;QACH,CAAC;KACF,CAAA;AACH,CAAC"}
@@ -0,0 +1,14 @@
1
+ export { createCreateFormTool } from './create-form.js';
2
+ export type { CreateFormDeps } from './create-form.js';
3
+ export { createUpdateFormFieldsTool } from './update-form-fields.js';
4
+ export type { UpdateFormFieldsDeps } from './update-form-fields.js';
5
+ export { createUpdateFormDestinationsTool } from './update-form-destinations.js';
6
+ export type { UpdateFormDestinationsDeps } from './update-form-destinations.js';
7
+ export { createGetFormSubmissionsTool } from './get-form-submissions.js';
8
+ export type { GetFormSubmissionsDeps } from './get-form-submissions.js';
9
+ export { createValidateFormTool } from './validate-form.js';
10
+ export type { ValidateFormDeps } from './validate-form.js';
11
+ export { createListAllowedDestinationsTool } from './list-allowed-destinations.js';
12
+ export type { ListAllowedDestinationsDeps } from './list-allowed-destinations.js';
13
+ export { isFormsAuthor, isPiiReader } from './access.js';
14
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/tools/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,oBAAoB,EAAE,MAAM,kBAAkB,CAAA;AACvD,YAAY,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAA;AACtD,OAAO,EAAE,0BAA0B,EAAE,MAAM,yBAAyB,CAAA;AACpE,YAAY,EAAE,oBAAoB,EAAE,MAAM,yBAAyB,CAAA;AACnE,OAAO,EAAE,gCAAgC,EAAE,MAAM,+BAA+B,CAAA;AAChF,YAAY,EAAE,0BAA0B,EAAE,MAAM,+BAA+B,CAAA;AAC/E,OAAO,EAAE,4BAA4B,EAAE,MAAM,2BAA2B,CAAA;AACxE,YAAY,EAAE,sBAAsB,EAAE,MAAM,2BAA2B,CAAA;AACvE,OAAO,EAAE,sBAAsB,EAAE,MAAM,oBAAoB,CAAA;AAC3D,YAAY,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAA;AAC1D,OAAO,EAAE,iCAAiC,EAAE,MAAM,gCAAgC,CAAA;AAClF,YAAY,EAAE,2BAA2B,EAAE,MAAM,gCAAgC,CAAA;AACjF,OAAO,EAAE,aAAa,EAAE,WAAW,EAAE,MAAM,aAAa,CAAA"}
@@ -0,0 +1,8 @@
1
+ export { createCreateFormTool } from './create-form.js';
2
+ export { createUpdateFormFieldsTool } from './update-form-fields.js';
3
+ export { createUpdateFormDestinationsTool } from './update-form-destinations.js';
4
+ export { createGetFormSubmissionsTool } from './get-form-submissions.js';
5
+ export { createValidateFormTool } from './validate-form.js';
6
+ export { createListAllowedDestinationsTool } from './list-allowed-destinations.js';
7
+ export { isFormsAuthor, isPiiReader } from './access.js';
8
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/tools/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,oBAAoB,EAAE,MAAM,kBAAkB,CAAA;AAEvD,OAAO,EAAE,0BAA0B,EAAE,MAAM,yBAAyB,CAAA;AAEpE,OAAO,EAAE,gCAAgC,EAAE,MAAM,+BAA+B,CAAA;AAEhF,OAAO,EAAE,4BAA4B,EAAE,MAAM,2BAA2B,CAAA;AAExE,OAAO,EAAE,sBAAsB,EAAE,MAAM,oBAAoB,CAAA;AAE3D,OAAO,EAAE,iCAAiC,EAAE,MAAM,gCAAgC,CAAA;AAElF,OAAO,EAAE,aAAa,EAAE,WAAW,EAAE,MAAM,aAAa,CAAA"}
@@ -0,0 +1,10 @@
1
+ import { z } from 'zod';
2
+ import type { McpToolDefinition } from '@forumone/throughline-plugin-contract';
3
+ import type { FormsPluginOptions } from '../options.js';
4
+ declare const inputSchema: z.ZodObject<{}, "strict", z.ZodTypeAny, {}, {}>;
5
+ export interface ListAllowedDestinationsDeps {
6
+ options: FormsPluginOptions;
7
+ }
8
+ export declare function createListAllowedDestinationsTool(deps: ListAllowedDestinationsDeps): McpToolDefinition<typeof inputSchema>;
9
+ export {};
10
+ //# sourceMappingURL=list-allowed-destinations.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"list-allowed-destinations.d.ts","sourceRoot":"","sources":["../../src/tools/list-allowed-destinations.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAA;AACvB,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,uCAAuC,CAAA;AAE9E,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,eAAe,CAAA;AAEvD,QAAA,MAAM,WAAW,iDAAwB,CAAA;AAEzC,MAAM,WAAW,2BAA2B;IAC1C,OAAO,EAAE,kBAAkB,CAAA;CAC5B;AAED,wBAAgB,iCAAiC,CAC/C,IAAI,EAAE,2BAA2B,GAChC,iBAAiB,CAAC,OAAO,WAAW,CAAC,CAUvC"}
@@ -0,0 +1,14 @@
1
+ import { z } from 'zod';
2
+ import { listDestinations } from '../destinations.js';
3
+ const inputSchema = z.object({}).strict();
4
+ export function createListAllowedDestinationsTool(deps) {
5
+ return {
6
+ name: 'list_allowed_destinations',
7
+ description: 'Returns the labels of destinations forms can route submissions to in this deployment. Use this before create_form / update_form_destinations to discover what is allowed. Adding a new destination requires editing the plugin config and redeploying — that friction is the security model.',
8
+ inputSchema,
9
+ handler: async () => {
10
+ return { destinations: listDestinations(deps.options) };
11
+ },
12
+ };
13
+ }
14
+ //# sourceMappingURL=list-allowed-destinations.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"list-allowed-destinations.js","sourceRoot":"","sources":["../../src/tools/list-allowed-destinations.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAA;AAEvB,OAAO,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAA;AAGrD,MAAM,WAAW,GAAG,CAAC,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,MAAM,EAAE,CAAA;AAMzC,MAAM,UAAU,iCAAiC,CAC/C,IAAiC;IAEjC,OAAO;QACL,IAAI,EAAE,2BAA2B;QACjC,WAAW,EACT,8RAA8R;QAChS,WAAW;QACX,OAAO,EAAE,KAAK,IAAI,EAAE;YAClB,OAAO,EAAE,YAAY,EAAE,gBAAgB,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,CAAA;QACzD,CAAC;KACF,CAAA;AACH,CAAC"}
@@ -0,0 +1,45 @@
1
+ import { z } from 'zod';
2
+ import type { Payload } from 'payload';
3
+ import type { McpToolDefinition } from '@forumone/throughline-plugin-contract';
4
+ import type { ResolvedFormsConfig } from '../options.js';
5
+ declare const inputSchema: z.ZodObject<{
6
+ formId: z.ZodString;
7
+ destinationLabels: z.ZodArray<z.ZodString, "many">;
8
+ } & {
9
+ _meta: z.ZodOptional<z.ZodObject<{
10
+ userPrompt: z.ZodOptional<z.ZodString>;
11
+ reasoning: z.ZodOptional<z.ZodString>;
12
+ changesSummary: z.ZodOptional<z.ZodString>;
13
+ }, "strip", z.ZodTypeAny, {
14
+ reasoning?: string | undefined;
15
+ changesSummary?: string | undefined;
16
+ userPrompt?: string | undefined;
17
+ }, {
18
+ reasoning?: string | undefined;
19
+ changesSummary?: string | undefined;
20
+ userPrompt?: string | undefined;
21
+ }>>;
22
+ }, "strip", z.ZodTypeAny, {
23
+ formId: string;
24
+ destinationLabels: string[];
25
+ _meta?: {
26
+ reasoning?: string | undefined;
27
+ changesSummary?: string | undefined;
28
+ userPrompt?: string | undefined;
29
+ } | undefined;
30
+ }, {
31
+ formId: string;
32
+ destinationLabels: string[];
33
+ _meta?: {
34
+ reasoning?: string | undefined;
35
+ changesSummary?: string | undefined;
36
+ userPrompt?: string | undefined;
37
+ } | undefined;
38
+ }>;
39
+ export interface UpdateFormDestinationsDeps {
40
+ payload: Payload;
41
+ resolved: ResolvedFormsConfig;
42
+ }
43
+ export declare function createUpdateFormDestinationsTool(deps: UpdateFormDestinationsDeps): McpToolDefinition<typeof inputSchema>;
44
+ export {};
45
+ //# sourceMappingURL=update-form-destinations.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"update-form-destinations.d.ts","sourceRoot":"","sources":["../../src/tools/update-form-destinations.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAA;AACvB,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,SAAS,CAAA;AACtC,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,uCAAuC,CAAA;AAE9E,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,eAAe,CAAA;AAIxD,QAAA,MAAM,WAAW;;;;;;;;;iBAyBqE,CAAC;sBAEzE,CAAA;kBAAwC,CAAC;;iBAC7B,CAAC;sBAA4C,CAAC;kBAGlE,CAAA;;;;;;;;;;;;;;;;;;EA5BJ,CAAA;AAEF,MAAM,WAAW,0BAA0B;IACzC,OAAO,EAAE,OAAO,CAAA;IAChB,QAAQ,EAAE,mBAAmB,CAAA;CAC9B;AAED,wBAAgB,gCAAgC,CAC9C,IAAI,EAAE,0BAA0B,GAC/B,iBAAiB,CAAC,OAAO,WAAW,CAAC,CAoEvC"}