@prenta/core 8.9.1 → 8.10.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/CHANGELOG.md +102 -0
- package/dist/actions.d.ts +31 -0
- package/dist/actions.d.ts.map +1 -1
- package/dist/actions.js +59 -4
- package/dist/actions.js.map +1 -1
- package/dist/ai/batch-links.d.ts +105 -0
- package/dist/ai/batch-links.d.ts.map +1 -0
- package/dist/ai/batch-links.js +667 -0
- package/dist/ai/batch-links.js.map +1 -0
- package/dist/ai/batch-list.d.ts +127 -4
- package/dist/ai/batch-list.d.ts.map +1 -1
- package/dist/ai/batch-list.js +250 -14
- package/dist/ai/batch-list.js.map +1 -1
- package/dist/ai/providers/http.d.ts +4 -0
- package/dist/ai/providers/http.d.ts.map +1 -1
- package/dist/ai/providers/http.js +9 -8
- package/dist/ai/providers/http.js.map +1 -1
- package/dist/ai/tasks/editor-text.d.ts +39 -0
- package/dist/ai/tasks/editor-text.d.ts.map +1 -0
- package/dist/ai/tasks/editor-text.js +45 -0
- package/dist/ai/tasks/editor-text.js.map +1 -0
- package/dist/ai/tasks/link-embeddings.d.ts +22 -0
- package/dist/ai/tasks/link-embeddings.d.ts.map +1 -1
- package/dist/ai/tasks/link-embeddings.js +24 -10
- package/dist/ai/tasks/link-embeddings.js.map +1 -1
- package/dist/ai/usage.d.ts +7 -0
- package/dist/ai/usage.d.ts.map +1 -1
- package/dist/ai/usage.js +11 -0
- package/dist/ai/usage.js.map +1 -1
- package/dist/api/guarded-db.d.ts +6 -0
- package/dist/api/guarded-db.d.ts.map +1 -1
- package/dist/api/guarded-db.js +13 -1
- package/dist/api/guarded-db.js.map +1 -1
- package/dist/api/handlers.d.ts.map +1 -1
- package/dist/api/handlers.js +2 -0
- package/dist/api/handlers.js.map +1 -1
- package/dist/api/openapi.d.ts.map +1 -1
- package/dist/api/openapi.js +47 -0
- package/dist/api/openapi.js.map +1 -1
- package/dist/api/route-helpers/forms.d.ts.map +1 -1
- package/dist/api/route-helpers/forms.js +7 -1
- package/dist/api/route-helpers/forms.js.map +1 -1
- package/dist/api/routes/ai-authoring.d.ts.map +1 -1
- package/dist/api/routes/ai-authoring.js +1 -0
- package/dist/api/routes/ai-authoring.js.map +1 -1
- package/dist/api/routes/ai-seo.d.ts.map +1 -1
- package/dist/api/routes/ai-seo.js +20 -18
- package/dist/api/routes/ai-seo.js.map +1 -1
- package/dist/api/routes/documents.d.ts.map +1 -1
- package/dist/api/routes/documents.js +20 -0
- package/dist/api/routes/documents.js.map +1 -1
- package/dist/api/routes/media.d.ts.map +1 -1
- package/dist/api/routes/media.js +3 -1
- package/dist/api/routes/media.js.map +1 -1
- package/dist/api/routes/scheduling.d.ts.map +1 -1
- package/dist/api/routes/scheduling.js +33 -2
- package/dist/api/routes/scheduling.js.map +1 -1
- package/dist/appearance/color.d.ts +17 -0
- package/dist/appearance/color.d.ts.map +1 -1
- package/dist/appearance/color.js +162 -1
- package/dist/appearance/color.js.map +1 -1
- package/dist/appearance/index.d.ts +3 -3
- package/dist/appearance/index.d.ts.map +1 -1
- package/dist/appearance/index.js +2 -2
- package/dist/appearance/index.js.map +1 -1
- package/dist/appearance/resolve.d.ts.map +1 -1
- package/dist/appearance/resolve.js +4 -2
- package/dist/appearance/resolve.js.map +1 -1
- package/dist/appearance/theme-tokens.d.ts +60 -11
- package/dist/appearance/theme-tokens.d.ts.map +1 -1
- package/dist/appearance/theme-tokens.js +184 -175
- package/dist/appearance/theme-tokens.js.map +1 -1
- package/dist/appearance/types.d.ts +16 -2
- package/dist/appearance/types.d.ts.map +1 -1
- package/dist/astro-site.d.ts +1 -11
- package/dist/astro-site.d.ts.map +1 -1
- package/dist/astro-site.js +4 -0
- package/dist/astro-site.js.map +1 -1
- package/dist/auth/team.d.ts +1 -0
- package/dist/auth/team.d.ts.map +1 -1
- package/dist/auth/team.js +1 -1
- package/dist/auth/team.js.map +1 -1
- package/dist/cache/http.d.ts +20 -0
- package/dist/cache/http.d.ts.map +1 -1
- package/dist/cache/http.js +42 -0
- package/dist/cache/http.js.map +1 -1
- package/dist/chrome/announcement.d.ts +30 -0
- package/dist/chrome/announcement.d.ts.map +1 -0
- package/dist/chrome/announcement.js +190 -0
- package/dist/chrome/announcement.js.map +1 -0
- package/dist/chrome/codegen.d.ts +17 -0
- package/dist/chrome/codegen.d.ts.map +1 -0
- package/dist/chrome/codegen.js +96 -0
- package/dist/chrome/codegen.js.map +1 -0
- package/dist/chrome/contract.d.ts +142 -0
- package/dist/chrome/contract.d.ts.map +1 -0
- package/dist/chrome/contract.js +2 -0
- package/dist/chrome/contract.js.map +1 -0
- package/dist/chrome/memory-store.d.ts +15 -0
- package/dist/chrome/memory-store.d.ts.map +1 -0
- package/dist/chrome/memory-store.js +54 -0
- package/dist/chrome/memory-store.js.map +1 -0
- package/dist/chrome/parse.d.ts +36 -0
- package/dist/chrome/parse.d.ts.map +1 -0
- package/dist/chrome/parse.js +277 -0
- package/dist/chrome/parse.js.map +1 -0
- package/dist/chrome/prisma-store.d.ts +11 -0
- package/dist/chrome/prisma-store.d.ts.map +1 -0
- package/dist/chrome/prisma-store.js +48 -0
- package/dist/chrome/prisma-store.js.map +1 -0
- package/dist/chrome/public.d.ts +22 -0
- package/dist/chrome/public.d.ts.map +1 -0
- package/dist/chrome/public.js +181 -0
- package/dist/chrome/public.js.map +1 -0
- package/dist/chrome/resolve.d.ts +36 -0
- package/dist/chrome/resolve.d.ts.map +1 -0
- package/dist/chrome/resolve.js +165 -0
- package/dist/chrome/resolve.js.map +1 -0
- package/dist/chrome/revalidate.d.ts +9 -0
- package/dist/chrome/revalidate.d.ts.map +1 -0
- package/dist/chrome/revalidate.js +51 -0
- package/dist/chrome/revalidate.js.map +1 -0
- package/dist/chrome/routes.d.ts +14 -0
- package/dist/chrome/routes.d.ts.map +1 -0
- package/dist/chrome/routes.js +306 -0
- package/dist/chrome/routes.js.map +1 -0
- package/dist/chrome/schema.d.ts +231 -0
- package/dist/chrome/schema.d.ts.map +1 -0
- package/dist/chrome/schema.js +73 -0
- package/dist/chrome/schema.js.map +1 -0
- package/dist/chrome/service.d.ts +76 -0
- package/dist/chrome/service.d.ts.map +1 -0
- package/dist/chrome/service.js +286 -0
- package/dist/chrome/service.js.map +1 -0
- package/dist/chrome/settings.d.ts +14 -0
- package/dist/chrome/settings.d.ts.map +1 -0
- package/dist/chrome/settings.js +142 -0
- package/dist/chrome/settings.js.map +1 -0
- package/dist/chrome/store.d.ts +48 -0
- package/dist/chrome/store.d.ts.map +1 -0
- package/dist/chrome/store.js +26 -0
- package/dist/chrome/store.js.map +1 -0
- package/dist/chrome/values.d.ts +98 -0
- package/dist/chrome/values.d.ts.map +1 -0
- package/dist/chrome/values.js +491 -0
- package/dist/chrome/values.js.map +1 -0
- package/dist/config/define.d.ts +2 -0
- package/dist/config/define.d.ts.map +1 -1
- package/dist/config/define.js +2 -0
- package/dist/config/define.js.map +1 -1
- package/dist/db/model-types.d.ts +62 -0
- package/dist/db/model-types.d.ts.map +1 -1
- package/dist/forms/attribution-settings.d.ts +23 -0
- package/dist/forms/attribution-settings.d.ts.map +1 -0
- package/dist/forms/attribution-settings.js +42 -0
- package/dist/forms/attribution-settings.js.map +1 -0
- package/dist/forms/attribution.d.ts +5 -1
- package/dist/forms/attribution.d.ts.map +1 -1
- package/dist/forms/attribution.js +6 -4
- package/dist/forms/attribution.js.map +1 -1
- package/dist/forms/client-validation.d.ts.map +1 -1
- package/dist/forms/client-validation.js +3 -0
- package/dist/forms/client-validation.js.map +1 -1
- package/dist/forms/form-model.d.ts +109 -0
- package/dist/forms/form-model.d.ts.map +1 -0
- package/dist/forms/form-model.js +192 -0
- package/dist/forms/form-model.js.map +1 -0
- package/dist/forms/index.d.ts +2 -2
- package/dist/forms/index.d.ts.map +1 -1
- package/dist/forms/index.js +1 -1
- package/dist/forms/index.js.map +1 -1
- package/dist/forms/service.d.ts +19 -1
- package/dist/forms/service.d.ts.map +1 -1
- package/dist/forms/service.js +152 -0
- package/dist/forms/service.js.map +1 -1
- package/dist/forms/spam.d.ts +0 -12
- package/dist/forms/spam.d.ts.map +1 -1
- package/dist/forms/spam.js +30 -0
- package/dist/forms/spam.js.map +1 -1
- package/dist/forms/submission.d.ts +7 -0
- package/dist/forms/submission.d.ts.map +1 -1
- package/dist/forms/submission.js +33 -0
- package/dist/forms/submission.js.map +1 -1
- package/dist/forms/types.d.ts +26 -1
- package/dist/forms/types.d.ts.map +1 -1
- package/dist/forms/types.js +9 -1
- package/dist/forms/types.js.map +1 -1
- package/dist/generated/browser.d.ts +35 -3
- package/dist/generated/client.d.ts +35 -3
- package/dist/generated/internal/class.d.ts +44 -0
- package/dist/generated/internal/class.js +4 -4
- package/dist/generated/internal/prismaNamespace.d.ts +403 -1
- package/dist/generated/internal/prismaNamespace.js +95 -1
- package/dist/generated/internal/prismaNamespaceBrowser.d.ts +102 -0
- package/dist/generated/internal/prismaNamespaceBrowser.js +95 -1
- package/dist/generated/models/ChromeRegion.d.ts +1203 -0
- package/dist/generated/models/ChromeRegion.js +1 -0
- package/dist/generated/models/Job.d.ts +732 -5
- package/dist/generated/models/JobEvent.d.ts +1339 -0
- package/dist/generated/models/JobEvent.js +1 -0
- package/dist/generated/models/JobReviewItem.d.ts +1470 -0
- package/dist/generated/models/JobReviewItem.js +1 -0
- package/dist/generated/models/SystemSetting.d.ts +952 -0
- package/dist/generated/models/SystemSetting.js +1 -0
- package/dist/generated/models.d.ts +4 -0
- package/dist/index.d.ts +12 -5
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +8 -3
- package/dist/index.js.map +1 -1
- package/dist/jobs/batch-ai.d.ts +53 -0
- package/dist/jobs/batch-ai.d.ts.map +1 -0
- package/dist/jobs/batch-ai.js +314 -0
- package/dist/jobs/batch-ai.js.map +1 -0
- package/dist/jobs/contract.d.ts +186 -0
- package/dist/jobs/contract.d.ts.map +1 -0
- package/dist/jobs/contract.js +2 -0
- package/dist/jobs/contract.js.map +1 -0
- package/dist/jobs/error-text.d.ts +23 -0
- package/dist/jobs/error-text.d.ts.map +1 -0
- package/dist/jobs/error-text.js +110 -0
- package/dist/jobs/error-text.js.map +1 -0
- package/dist/jobs/handlers.d.ts.map +1 -1
- package/dist/jobs/handlers.js +48 -7
- package/dist/jobs/handlers.js.map +1 -1
- package/dist/jobs/memory-store.d.ts +26 -2
- package/dist/jobs/memory-store.d.ts.map +1 -1
- package/dist/jobs/memory-store.js +157 -3
- package/dist/jobs/memory-store.js.map +1 -1
- package/dist/jobs/outcomes.d.ts +46 -0
- package/dist/jobs/outcomes.d.ts.map +1 -0
- package/dist/jobs/outcomes.js +251 -0
- package/dist/jobs/outcomes.js.map +1 -0
- package/dist/jobs/prisma-store.d.ts +14 -2
- package/dist/jobs/prisma-store.d.ts.map +1 -1
- package/dist/jobs/prisma-store.js +257 -15
- package/dist/jobs/prisma-store.js.map +1 -1
- package/dist/jobs/queue.d.ts +62 -2
- package/dist/jobs/queue.d.ts.map +1 -1
- package/dist/jobs/queue.js +412 -36
- package/dist/jobs/queue.js.map +1 -1
- package/dist/jobs/retention.d.ts +11 -0
- package/dist/jobs/retention.d.ts.map +1 -0
- package/dist/jobs/retention.js +18 -0
- package/dist/jobs/retention.js.map +1 -0
- package/dist/jobs/review.d.ts +111 -0
- package/dist/jobs/review.d.ts.map +1 -0
- package/dist/jobs/review.js +461 -0
- package/dist/jobs/review.js.map +1 -0
- package/dist/jobs/routes.d.ts.map +1 -1
- package/dist/jobs/routes.js +491 -16
- package/dist/jobs/routes.js.map +1 -1
- package/dist/jobs/serialize.d.ts +40 -0
- package/dist/jobs/serialize.d.ts.map +1 -0
- package/dist/jobs/serialize.js +270 -0
- package/dist/jobs/serialize.js.map +1 -0
- package/dist/jobs/types.d.ts +141 -2
- package/dist/jobs/types.d.ts.map +1 -1
- package/dist/jobs/worker-status.d.ts +27 -0
- package/dist/jobs/worker-status.d.ts.map +1 -0
- package/dist/jobs/worker-status.js +66 -0
- package/dist/jobs/worker-status.js.map +1 -0
- package/dist/media/optimize.d.ts.map +1 -1
- package/dist/media/optimize.js +4 -2
- package/dist/media/optimize.js.map +1 -1
- package/dist/next-site.d.ts +1 -0
- package/dist/next-site.d.ts.map +1 -1
- package/dist/next-site.js +3 -0
- package/dist/next-site.js.map +1 -1
- package/dist/seo/audit-runner.d.ts.map +1 -1
- package/dist/seo/audit-runner.js +23 -2
- package/dist/seo/audit-runner.js.map +1 -1
- package/dist/seo/issue-fix-link-insert.d.ts +11 -0
- package/dist/seo/issue-fix-link-insert.d.ts.map +1 -1
- package/dist/seo/issue-fix-link-insert.js +122 -8
- package/dist/seo/issue-fix-link-insert.js.map +1 -1
- package/dist/server-site.d.ts.map +1 -1
- package/dist/server-site.js +15 -0
- package/dist/server-site.js.map +1 -1
- package/dist/site.d.ts +8 -0
- package/dist/site.d.ts.map +1 -1
- package/dist/site.js +6 -0
- package/dist/site.js.map +1 -1
- package/dist/webhooks/index.d.ts +3 -1
- package/dist/webhooks/index.d.ts.map +1 -1
- package/dist/webhooks/index.js.map +1 -1
- package/package.json +6 -1
- package/prisma/migrations/0025_job_cancel_review/down.sql +60 -0
- package/prisma/migrations/0025_job_cancel_review/migration.sql +56 -0
- package/prisma/migrations/0026_job_creator_system_settings/down.sql +30 -0
- package/prisma/migrations/0026_job_creator_system_settings/migration.sql +14 -0
- package/prisma/migrations/0027_chrome_regions/down.sql +24 -0
- package/prisma/migrations/0027_chrome_regions/migration.sql +16 -0
- package/prisma/schema.prisma +105 -15
|
@@ -0,0 +1,192 @@
|
|
|
1
|
+
export function migrateFormSettings(input) {
|
|
2
|
+
const notifications = [];
|
|
3
|
+
if ((input.recipients?.length ?? 0) > 0) {
|
|
4
|
+
notifications.push({ kind: 'admin', to: input.recipients });
|
|
5
|
+
}
|
|
6
|
+
if (input.autoresponder) {
|
|
7
|
+
notifications.push({
|
|
8
|
+
kind: 'autoresponder',
|
|
9
|
+
subject: input.autoresponder.subject,
|
|
10
|
+
body: input.autoresponder.body,
|
|
11
|
+
});
|
|
12
|
+
}
|
|
13
|
+
return {
|
|
14
|
+
notifications,
|
|
15
|
+
confirmations: [{ message: input.successMessage, redirectUrl: input.redirectUrl }],
|
|
16
|
+
fields: (input.fields ?? []).map((field) => ({ width: 'full', ...field })),
|
|
17
|
+
};
|
|
18
|
+
}
|
|
19
|
+
export function downgradeFormSettings(input) {
|
|
20
|
+
const admin = input.notifications.find((item) => item.kind === 'admin');
|
|
21
|
+
const auto = input.notifications.find((item) => item.kind === 'autoresponder');
|
|
22
|
+
const confirmation = input.confirmations[0];
|
|
23
|
+
return {
|
|
24
|
+
recipients: admin?.to,
|
|
25
|
+
autoresponder: auto ? { enabled: true, subject: auto.subject, body: auto.body } : null,
|
|
26
|
+
successMessage: confirmation?.message,
|
|
27
|
+
redirectUrl: confirmation?.redirectUrl,
|
|
28
|
+
fields: input.fields.map((field) => {
|
|
29
|
+
const next = { ...field };
|
|
30
|
+
delete next.width;
|
|
31
|
+
return next;
|
|
32
|
+
}),
|
|
33
|
+
};
|
|
34
|
+
}
|
|
35
|
+
const FREE_EMAIL_DOMAINS = new Set([
|
|
36
|
+
'gmail.com',
|
|
37
|
+
'googlemail.com',
|
|
38
|
+
'yahoo.com',
|
|
39
|
+
'hotmail.com',
|
|
40
|
+
'outlook.com',
|
|
41
|
+
'live.com',
|
|
42
|
+
'icloud.com',
|
|
43
|
+
'aol.com',
|
|
44
|
+
]);
|
|
45
|
+
function normalizeDomain(value) {
|
|
46
|
+
return value
|
|
47
|
+
.trim()
|
|
48
|
+
.toLowerCase()
|
|
49
|
+
.replace(/^https?:\/\//, '')
|
|
50
|
+
.replace(/^www\./, '')
|
|
51
|
+
.split('/')[0];
|
|
52
|
+
}
|
|
53
|
+
export function isFreeEmailDomain(email) {
|
|
54
|
+
const domain = email.split('@')[1]?.toLowerCase() ?? '';
|
|
55
|
+
return FREE_EMAIL_DOMAINS.has(domain);
|
|
56
|
+
}
|
|
57
|
+
export function termMatches(text, term) {
|
|
58
|
+
const value = term.value.trim().toLowerCase();
|
|
59
|
+
if (!value)
|
|
60
|
+
return false;
|
|
61
|
+
if (term.kind === 'domain')
|
|
62
|
+
return normalizeDomain(text) === normalizeDomain(value);
|
|
63
|
+
if (term.kind === 'contains')
|
|
64
|
+
return text.toLowerCase().includes(value);
|
|
65
|
+
const pattern = new RegExp(`(?<![\\p{L}\\p{N}_])${escapeRegExp(value)}(?![\\p{L}\\p{N}_])`, 'u');
|
|
66
|
+
return pattern.test(text.toLowerCase());
|
|
67
|
+
}
|
|
68
|
+
function escapeRegExp(value) {
|
|
69
|
+
return value.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
|
|
70
|
+
}
|
|
71
|
+
/**
|
|
72
|
+
* `entryCount` is only consulted when the form has an `entryLimit`; callers
|
|
73
|
+
* that skip it get the schedule check alone.
|
|
74
|
+
*/
|
|
75
|
+
export function formIsClosed(availability, now, entryCount) {
|
|
76
|
+
if (!availability)
|
|
77
|
+
return false;
|
|
78
|
+
if (availability.closed)
|
|
79
|
+
return true;
|
|
80
|
+
if (availability.opensAt && now < new Date(availability.opensAt))
|
|
81
|
+
return true;
|
|
82
|
+
if (availability.closesAt && now >= new Date(availability.closesAt))
|
|
83
|
+
return true;
|
|
84
|
+
if (typeof availability.entryLimit === 'number' &&
|
|
85
|
+
typeof entryCount === 'number' &&
|
|
86
|
+
entryCount >= availability.entryLimit) {
|
|
87
|
+
return true;
|
|
88
|
+
}
|
|
89
|
+
return false;
|
|
90
|
+
}
|
|
91
|
+
export function stepValues(fields, values, step) {
|
|
92
|
+
const errors = fields.filter((field) => field.step === step && field.required && !(values[field.key] ?? '').trim());
|
|
93
|
+
return { ok: errors.length === 0, values: { ...values } };
|
|
94
|
+
}
|
|
95
|
+
function displayFieldTypes() {
|
|
96
|
+
return new Set(['divider', 'heading', 'content', 'pagebreak', 'richtext']);
|
|
97
|
+
}
|
|
98
|
+
export function valuesForEntry(fields, values) {
|
|
99
|
+
const hidden = displayFieldTypes();
|
|
100
|
+
const data = {};
|
|
101
|
+
for (const field of fields) {
|
|
102
|
+
if (hidden.has(field.type))
|
|
103
|
+
continue;
|
|
104
|
+
if (field.key in values)
|
|
105
|
+
data[field.key] = values[field.key];
|
|
106
|
+
}
|
|
107
|
+
return data;
|
|
108
|
+
}
|
|
109
|
+
export function convertPartial(existingId, nextId) {
|
|
110
|
+
if (existingId)
|
|
111
|
+
return { id: existingId, created: false };
|
|
112
|
+
return { id: nextId, created: true };
|
|
113
|
+
}
|
|
114
|
+
export function webhookEntryPayload(entry) {
|
|
115
|
+
return { data: entry.data };
|
|
116
|
+
}
|
|
117
|
+
export function mineCount(entries, userId) {
|
|
118
|
+
return entries.filter((entry) => entry.assigneeId === userId && entry.status !== 'won' && entry.status !== 'lost').length;
|
|
119
|
+
}
|
|
120
|
+
export function planRetention(rows, policy, alreadyDeleted = new Set()) {
|
|
121
|
+
const due = rows.filter((row) => {
|
|
122
|
+
if (alreadyDeleted.has(row.id))
|
|
123
|
+
return false;
|
|
124
|
+
if (row.kind === 'entry' && row.starred)
|
|
125
|
+
return false;
|
|
126
|
+
if (row.kind === 'entry')
|
|
127
|
+
return row.ageDays >= policy.entryDays;
|
|
128
|
+
if (row.kind === 'spam')
|
|
129
|
+
return row.ageDays >= policy.spamDays;
|
|
130
|
+
if (row.kind === 'archived')
|
|
131
|
+
return row.ageDays >= policy.archivedDays;
|
|
132
|
+
if (row.kind === 'delivery')
|
|
133
|
+
return row.ageDays >= policy.deliveryDays;
|
|
134
|
+
return row.ageDays >= policy.partialDays;
|
|
135
|
+
});
|
|
136
|
+
return {
|
|
137
|
+
entries: due.filter((row) => row.kind === 'entry').length,
|
|
138
|
+
spam: due.filter((row) => row.kind === 'spam').length,
|
|
139
|
+
archived: due.filter((row) => row.kind === 'archived').length,
|
|
140
|
+
deliveries: due.filter((row) => row.kind === 'delivery').length,
|
|
141
|
+
files: policy.deleteFiles ? due.filter((row) => row.hasFile).length : 0,
|
|
142
|
+
ids: due.map((row) => row.id),
|
|
143
|
+
};
|
|
144
|
+
}
|
|
145
|
+
const BOUNCE_EXPLANATIONS = {
|
|
146
|
+
'5.1.1': 'The recipient address does not exist.',
|
|
147
|
+
'5.2.2': 'The recipient mailbox is full.',
|
|
148
|
+
'4.2.2': 'The mailbox is full, so delivery was delayed.',
|
|
149
|
+
};
|
|
150
|
+
export function explainDelivery(code) {
|
|
151
|
+
return {
|
|
152
|
+
code,
|
|
153
|
+
explanation: BOUNCE_EXPLANATIONS[code] ?? 'The provider rejected the message.',
|
|
154
|
+
timeline: ['queued', 'attempted', code.startsWith('4') ? 'deferred' : 'bounced'],
|
|
155
|
+
};
|
|
156
|
+
}
|
|
157
|
+
export function resendDelivery(previous) {
|
|
158
|
+
return { submissionId: previous.submissionId, attempt: previous.attempt + 1 };
|
|
159
|
+
}
|
|
160
|
+
export function shouldReviewSpamWithAi(earlierMatched) {
|
|
161
|
+
return !earlierMatched;
|
|
162
|
+
}
|
|
163
|
+
export function aiSpamTimeoutResult() {
|
|
164
|
+
return 'clean';
|
|
165
|
+
}
|
|
166
|
+
export function interpolateSmartTags(template, values) {
|
|
167
|
+
return template.replace(/\{\{?\s*([a-z0-9_]+)\s*\}?\}/gi, (match, key) => {
|
|
168
|
+
if (!(key in values))
|
|
169
|
+
return match;
|
|
170
|
+
return values[key] ?? '';
|
|
171
|
+
});
|
|
172
|
+
}
|
|
173
|
+
export function fieldKeyFromLabel(label, locked, current) {
|
|
174
|
+
if (locked)
|
|
175
|
+
return current;
|
|
176
|
+
const slug = label
|
|
177
|
+
.toLowerCase()
|
|
178
|
+
.replace(/[^a-z0-9]+/g, '_')
|
|
179
|
+
.replace(/^_+|_+$/g, '');
|
|
180
|
+
return slug || 'field';
|
|
181
|
+
}
|
|
182
|
+
export function insertFieldBelow(fields, field, selectedId) {
|
|
183
|
+
if (!selectedId)
|
|
184
|
+
return [...fields, field];
|
|
185
|
+
const index = fields.findIndex((item) => item.id === selectedId);
|
|
186
|
+
if (index < 0)
|
|
187
|
+
return [...fields, field];
|
|
188
|
+
const next = [...fields];
|
|
189
|
+
next.splice(index + 1, 0, field);
|
|
190
|
+
return next;
|
|
191
|
+
}
|
|
192
|
+
//# sourceMappingURL=form-model.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"form-model.js","sourceRoot":"","sources":["../../src/forms/form-model.ts"],"names":[],"mappings":"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"}
|
package/dist/forms/index.d.ts
CHANGED
|
@@ -3,13 +3,13 @@ export type { AttributionData, AttributionChannel, AttributionClickIds, Attribut
|
|
|
3
3
|
export { trackFormStart, trackFormSubmit, trackFormError, pushDataLayerEvent, getDefaultConfirmation, getDefaultAnalyticsConfig, } from './analytics.js';
|
|
4
4
|
export type { FormAnalyticsConfig, FormConfirmation } from './analytics.js';
|
|
5
5
|
export { INPUT_FIELD_TYPES, NON_INPUT_FIELD_TYPES } from './types.js';
|
|
6
|
-
export type { FormFieldType, PiiClassification, FormFieldOption, FieldValidationRules, ConditionalOperator, ConditionalRule, ConditionalLogic, FieldWidth, FormField, FormSchemaVersion, FormWebhookConfig, FormWebhookEvent, FormNotificationSettings, SpamProtectionStrategy, FormSpamSettings, FormEmbedSettings, FormStatus, FormDefinition, SpamStatus, FormSubmissionFile, FormSubmission, FetchFormsParams, FetchFormEntriesParams, FormStats, FormsSidebarCount, EntryCounts, } from './types.js';
|
|
6
|
+
export type { FormFieldType, PiiClassification, FormFieldOption, FieldValidationRules, ConditionalOperator, ConditionalRule, ConditionalLogic, FieldWidth, FormField, FormSchemaVersion, FormWebhookConfig, FormWebhookEvent, FormNotificationSettings, SpamProtectionStrategy, FormSpamSettings, FormEmbedSettings, FormAvailability, FormStatus, FormDefinition, SpamStatus, FormSubmissionFile, FormSubmission, FetchFormsParams, FetchFormEntriesParams, FormStats, FormsSidebarCount, EntryCounts, } from './types.js';
|
|
7
7
|
export * from './service.js';
|
|
8
8
|
export * from './entries.js';
|
|
9
9
|
export { validateAndNormalizeSubmission, type FieldError, type SubmissionValidationResult, } from './validation.js';
|
|
10
10
|
export { scoreSubmissionSpam, type SpamScoreInput, type SpamScoreResult } from './spam.js';
|
|
11
11
|
export { validateSubmissionFiles, persistSubmissionFiles, FORM_UPLOAD_ALLOWED_MIME_TYPES, DEFAULT_MAX_FILE_BYTES, type IncomingFile, type ValidateFilesResult, } from './files.js';
|
|
12
|
-
export { processSubmission, buildPublicForm, runSubmissionSideEffects, SubmissionValidationError, type SubmissionContext, type SubmissionResult, type SubmissionConfirmation, type SubmissionSideEffectInput, type PublicForm, type PublicFormField, } from './submission.js';
|
|
12
|
+
export { processSubmission, buildPublicForm, runSubmissionSideEffects, FormClosedError, SubmissionValidationError, type SubmissionContext, type SubmissionResult, type SubmissionConfirmation, type SubmissionSideEffectInput, type PublicForm, type PublicFormField, } from './submission.js';
|
|
13
13
|
export { buildWebMcpFormMeta, attachWebMcpToPublicForm, slugToWebMcpToolName, isWebMcpEnabledForForms, type WebMcpFormMeta, type BuildWebMcpFormMetaOptions, } from './webmcp.js';
|
|
14
14
|
export { renderPublicFormHtml, type RenderPublicFormHtmlOptions } from './public-html.js';
|
|
15
15
|
export { collectFormSlugsFromSections, prefetchPublicForms } from './prefetch.js';
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/forms/index.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/forms/index.ts"],"names":[],"mappings":"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"}
|
package/dist/forms/index.js
CHANGED
|
@@ -8,7 +8,7 @@ export { validateAndNormalizeSubmission, } from './validation.js';
|
|
|
8
8
|
// `@prenta/core/forms/client` for public-site form components.
|
|
9
9
|
export { scoreSubmissionSpam } from './spam.js';
|
|
10
10
|
export { validateSubmissionFiles, persistSubmissionFiles, FORM_UPLOAD_ALLOWED_MIME_TYPES, DEFAULT_MAX_FILE_BYTES, } from './files.js';
|
|
11
|
-
export { processSubmission, buildPublicForm, runSubmissionSideEffects, SubmissionValidationError, } from './submission.js';
|
|
11
|
+
export { processSubmission, buildPublicForm, runSubmissionSideEffects, FormClosedError, SubmissionValidationError, } from './submission.js';
|
|
12
12
|
export { buildWebMcpFormMeta, attachWebMcpToPublicForm, slugToWebMcpToolName, isWebMcpEnabledForForms, } from './webmcp.js';
|
|
13
13
|
export { renderPublicFormHtml } from './public-html.js';
|
|
14
14
|
export { collectFormSlugsFromSections, prefetchPublicForms } from './prefetch.js';
|
package/dist/forms/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/forms/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,kBAAkB,EAClB,gBAAgB,EAChB,oBAAoB,EACpB,aAAa,EACb,2BAA2B,EAC3B,sBAAsB,EACtB,eAAe,EACf,mBAAmB,EACnB,kBAAkB,EAClB,mBAAmB,EACnB,iBAAiB,GAClB,MAAM,kBAAkB,CAAA;AASzB,OAAO,EACL,cAAc,EACd,eAAe,EACf,cAAc,EACd,kBAAkB,EAClB,sBAAsB,EACtB,yBAAyB,GAC1B,MAAM,gBAAgB,CAAA;AAGvB,OAAO,EAAE,iBAAiB,EAAE,qBAAqB,EAAE,MAAM,YAAY,CAAA;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/forms/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,kBAAkB,EAClB,gBAAgB,EAChB,oBAAoB,EACpB,aAAa,EACb,2BAA2B,EAC3B,sBAAsB,EACtB,eAAe,EACf,mBAAmB,EACnB,kBAAkB,EAClB,mBAAmB,EACnB,iBAAiB,GAClB,MAAM,kBAAkB,CAAA;AASzB,OAAO,EACL,cAAc,EACd,eAAe,EACf,cAAc,EACd,kBAAkB,EAClB,sBAAsB,EACtB,yBAAyB,GAC1B,MAAM,gBAAgB,CAAA;AAGvB,OAAO,EAAE,iBAAiB,EAAE,qBAAqB,EAAE,MAAM,YAAY,CAAA;AA+BrE,cAAc,cAAc,CAAA;AAC5B,cAAc,cAAc,CAAA;AAE5B,OAAO,EACL,8BAA8B,GAG/B,MAAM,iBAAiB,CAAA;AACxB,4EAA4E;AAC5E,+DAA+D;AAE/D,OAAO,EAAE,mBAAmB,EAA6C,MAAM,WAAW,CAAA;AAC1F,OAAO,EACL,uBAAuB,EACvB,sBAAsB,EACtB,8BAA8B,EAC9B,sBAAsB,GAGvB,MAAM,YAAY,CAAA;AACnB,OAAO,EACL,iBAAiB,EACjB,eAAe,EACf,wBAAwB,EACxB,eAAe,EACf,yBAAyB,GAO1B,MAAM,iBAAiB,CAAA;AAExB,OAAO,EACL,mBAAmB,EACnB,wBAAwB,EACxB,oBAAoB,EACpB,uBAAuB,GAGxB,MAAM,aAAa,CAAA;AAEpB,OAAO,EAAE,oBAAoB,EAAoC,MAAM,kBAAkB,CAAA;AAEzF,OAAO,EAAE,4BAA4B,EAAE,mBAAmB,EAAE,MAAM,eAAe,CAAA;AAEjF,OAAO,EACL,qBAAqB,EACrB,yBAAyB,EACzB,sBAAsB,EACtB,uBAAuB,EACvB,4BAA4B,GAI7B,MAAM,aAAa,CAAA;AAEpB,OAAO,EACL,qBAAqB,EACrB,mBAAmB,EACnB,mBAAmB,EACnB,mBAAmB,EACnB,kBAAkB,EAClB,iBAAiB,EACjB,0BAA0B,EAC1B,yBAAyB,EACzB,iBAAiB,GAOlB,MAAM,eAAe,CAAA;AAEtB,OAAO,EACL,iBAAiB,EACjB,gBAAgB,EAChB,cAAc,EACd,iBAAiB,EACjB,iBAAiB,EACjB,oBAAoB,EACpB,sBAAsB,EACtB,eAAe,EACf,gBAAgB,EAChB,mBAAmB,GAKpB,MAAM,eAAe,CAAA"}
|
package/dist/forms/service.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { type ActionContext } from '../actions.js';
|
|
2
|
-
import { type FetchFormsParams, type FormDefinition, type FormEmbedSettings, type FormField, type FormNotificationSettings, type FormSchemaVersion, type FormSpamSettings, type FormStats, type FormStatus, type FormsSidebarCount } from './types.js';
|
|
2
|
+
import { type FetchFormsParams, type FormAvailability, type FormDefinition, type FormEmbedSettings, type FormField, type FormNotificationSettings, type FormSchemaVersion, type FormSpamSettings, type FormStats, type FormStatus, type FormsSidebarCount } from './types.js';
|
|
3
3
|
import type { FormAnalyticsConfig } from './analytics.js';
|
|
4
4
|
/**
|
|
5
5
|
* Coerce an untrusted value into a clean `FormAnalyticsConfig`, or `undefined`
|
|
@@ -8,6 +8,21 @@ import type { FormAnalyticsConfig } from './analytics.js';
|
|
|
8
8
|
* ever persisted or exposed on the public schema.
|
|
9
9
|
*/
|
|
10
10
|
export declare function normalizeAnalyticsConfig(value: unknown): FormAnalyticsConfig | undefined;
|
|
11
|
+
/**
|
|
12
|
+
* Coerce an untrusted value into a clean `FormAvailability`, or `undefined`
|
|
13
|
+
* when it holds nothing usable. Like `normalizeAnalyticsConfig`, this runs on
|
|
14
|
+
* read (legacy documents have no `availability`, and a malformed one must
|
|
15
|
+
* never throw) and on write, so only known keys are persisted. Timestamps are
|
|
16
|
+
* stored as canonical ISO strings.
|
|
17
|
+
*/
|
|
18
|
+
export declare function normalizeFormAvailability(value: unknown): FormAvailability | undefined;
|
|
19
|
+
/**
|
|
20
|
+
* Validate an `availability` value from an API body. `null` clears it, and so
|
|
21
|
+
* does `null` on a single date; `''` is rejected like any other non-ISO value.
|
|
22
|
+
* Unknown keys are rejected rather than normalized away, so a client sending
|
|
23
|
+
* the kit's `FormAccess` shape gets an error instead of a silent no-op.
|
|
24
|
+
*/
|
|
25
|
+
export declare function validateFormAvailability(value: unknown): string[];
|
|
11
26
|
/** Parse a raw `forms` document row into the typed `FormDefinition` shape. */
|
|
12
27
|
export declare function parseFormDefinition(doc: any): FormDefinition;
|
|
13
28
|
export interface SchemaValidationResult {
|
|
@@ -38,6 +53,7 @@ export interface CreateFormInput {
|
|
|
38
53
|
notificationSettings?: FormNotificationSettings;
|
|
39
54
|
embedSettings?: FormEmbedSettings;
|
|
40
55
|
spamSettings?: FormSpamSettings;
|
|
56
|
+
availability?: FormAvailability | null;
|
|
41
57
|
successMessage?: string;
|
|
42
58
|
redirectUrl?: string;
|
|
43
59
|
analytics?: FormAnalyticsConfig;
|
|
@@ -51,6 +67,8 @@ export interface UpdateFormInput {
|
|
|
51
67
|
redirectUrl?: string;
|
|
52
68
|
spamSettings?: FormSpamSettings;
|
|
53
69
|
embedSettings?: FormEmbedSettings;
|
|
70
|
+
/** Replaces the stored value; `null` clears it. */
|
|
71
|
+
availability?: FormAvailability | null;
|
|
54
72
|
analytics?: FormAnalyticsConfig;
|
|
55
73
|
}
|
|
56
74
|
export declare function updateForm(ctx: ActionContext, id: string, patch: UpdateFormInput): Promise<FormDefinition>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"service.d.ts","sourceRoot":"","sources":["../../src/forms/service.ts"],"names":[],"mappings":"AAcA,OAAO,EAAkD,KAAK,aAAa,EAAE,MAAM,eAAe,CAAA;AAGlG,OAAO,EAGL,KAAK,gBAAgB,EACrB,KAAK,cAAc,EACnB,KAAK,iBAAiB,EACtB,KAAK,SAAS,EAEd,KAAK,wBAAwB,EAC7B,KAAK,iBAAiB,EACtB,KAAK,gBAAgB,EACrB,KAAK,SAAS,EACd,KAAK,UAAU,EACf,KAAK,iBAAiB,EACvB,MAAM,YAAY,CAAA;AAEnB,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,gBAAgB,CAAA;AAoCzD;;;;;GAKG;AACH,wBAAgB,wBAAwB,CAAC,KAAK,EAAE,OAAO,GAAG,mBAAmB,GAAG,SAAS,CA8BxF;AAED,8EAA8E;AAC9E,wBAAgB,mBAAmB,CAAC,GAAG,EAAE,GAAG,GAAG,cAAc,
|
|
1
|
+
{"version":3,"file":"service.d.ts","sourceRoot":"","sources":["../../src/forms/service.ts"],"names":[],"mappings":"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"}
|
package/dist/forms/service.js
CHANGED
|
@@ -80,6 +80,130 @@ export function normalizeAnalyticsConfig(value) {
|
|
|
80
80
|
out.customParameters = cleanParams;
|
|
81
81
|
return out;
|
|
82
82
|
}
|
|
83
|
+
/**
|
|
84
|
+
* Lenient, for READ: anything `Date` can parse becomes a canonical ISO string,
|
|
85
|
+
* so legacy values never throw. Writes are checked with `isIsoDateTime` first.
|
|
86
|
+
*/
|
|
87
|
+
function toIsoTimestamp(value) {
|
|
88
|
+
if (typeof value !== 'string' || !value.trim())
|
|
89
|
+
return null;
|
|
90
|
+
const date = new Date(value.trim());
|
|
91
|
+
return Number.isNaN(date.getTime()) ? null : date.toISOString();
|
|
92
|
+
}
|
|
93
|
+
/**
|
|
94
|
+
* ISO 8601 date-time: `YYYY-MM-DDThh:mm`, then optional seconds and fraction,
|
|
95
|
+
* then an optional `Z` or `±hh:mm` offset. Date-only values are rejected: the
|
|
96
|
+
* contract's `opens`/`closes` are date-times.
|
|
97
|
+
*/
|
|
98
|
+
const ISO_DATE_TIME = /^(?<year>\d{4})-(?<month>\d{2})-(?<day>\d{2})T(?<hour>\d{2}):(?<minute>\d{2})(?::(?<second>\d{2})(?:\.\d{1,9})?)?(?:Z|[+-](?<offsetHour>\d{2}):(?<offsetMinute>\d{2}))?$/;
|
|
99
|
+
/**
|
|
100
|
+
* Strict, for WRITE. `new Date()` alone accepts "1" or "11/01/2026" and rolls
|
|
101
|
+
* "2026-02-30" over into March, so the calendar fields are checked too. A value
|
|
102
|
+
* without an offset is read in the server's time zone.
|
|
103
|
+
*/
|
|
104
|
+
function isIsoDateTime(value) {
|
|
105
|
+
if (typeof value !== 'string')
|
|
106
|
+
return false;
|
|
107
|
+
const groups = ISO_DATE_TIME.exec(value)?.groups;
|
|
108
|
+
if (!groups)
|
|
109
|
+
return false;
|
|
110
|
+
const part = (key) => Number(groups[key] ?? 0);
|
|
111
|
+
const calendar = new Date(0);
|
|
112
|
+
calendar.setUTCFullYear(part('year'), part('month') - 1, part('day'));
|
|
113
|
+
if (calendar.getUTCMonth() !== part('month') - 1 || calendar.getUTCDate() !== part('day')) {
|
|
114
|
+
return false;
|
|
115
|
+
}
|
|
116
|
+
if (part('hour') > 23 || part('minute') > 59 || part('second') > 59)
|
|
117
|
+
return false;
|
|
118
|
+
if (part('offsetHour') > 23 || part('offsetMinute') > 59)
|
|
119
|
+
return false;
|
|
120
|
+
return !Number.isNaN(Date.parse(value));
|
|
121
|
+
}
|
|
122
|
+
function isEntryLimit(value) {
|
|
123
|
+
return typeof value === 'number' && Number.isInteger(value) && value >= 1;
|
|
124
|
+
}
|
|
125
|
+
const AVAILABILITY_KEYS = new Set(['closed', 'opensAt', 'closesAt', 'entryLimit', 'closedMessage']);
|
|
126
|
+
/**
|
|
127
|
+
* Coerce an untrusted value into a clean `FormAvailability`, or `undefined`
|
|
128
|
+
* when it holds nothing usable. Like `normalizeAnalyticsConfig`, this runs on
|
|
129
|
+
* read (legacy documents have no `availability`, and a malformed one must
|
|
130
|
+
* never throw) and on write, so only known keys are persisted. Timestamps are
|
|
131
|
+
* stored as canonical ISO strings.
|
|
132
|
+
*/
|
|
133
|
+
export function normalizeFormAvailability(value) {
|
|
134
|
+
const raw = asRecord(value);
|
|
135
|
+
const out = {};
|
|
136
|
+
if (raw.closed === true)
|
|
137
|
+
out.closed = true;
|
|
138
|
+
const opensAt = toIsoTimestamp(raw.opensAt);
|
|
139
|
+
if (opensAt)
|
|
140
|
+
out.opensAt = opensAt;
|
|
141
|
+
const closesAt = toIsoTimestamp(raw.closesAt);
|
|
142
|
+
if (closesAt)
|
|
143
|
+
out.closesAt = closesAt;
|
|
144
|
+
if (isEntryLimit(raw.entryLimit))
|
|
145
|
+
out.entryLimit = raw.entryLimit;
|
|
146
|
+
if (typeof raw.closedMessage === 'string' && raw.closedMessage.trim()) {
|
|
147
|
+
out.closedMessage = raw.closedMessage.trim();
|
|
148
|
+
}
|
|
149
|
+
return Object.keys(out).length > 0 ? out : undefined;
|
|
150
|
+
}
|
|
151
|
+
/**
|
|
152
|
+
* Validate an `availability` value from an API body. `null` clears it, and so
|
|
153
|
+
* does `null` on a single date; `''` is rejected like any other non-ISO value.
|
|
154
|
+
* Unknown keys are rejected rather than normalized away, so a client sending
|
|
155
|
+
* the kit's `FormAccess` shape gets an error instead of a silent no-op.
|
|
156
|
+
*/
|
|
157
|
+
export function validateFormAvailability(value) {
|
|
158
|
+
if (value === null)
|
|
159
|
+
return [];
|
|
160
|
+
if (!value || typeof value !== 'object' || Array.isArray(value)) {
|
|
161
|
+
return ['Availability must be an object or null.'];
|
|
162
|
+
}
|
|
163
|
+
const raw = value;
|
|
164
|
+
const errors = [];
|
|
165
|
+
for (const key of Object.keys(raw)) {
|
|
166
|
+
if (!AVAILABILITY_KEYS.has(key))
|
|
167
|
+
errors.push(`Unknown availability setting "${key}".`);
|
|
168
|
+
}
|
|
169
|
+
if (raw.closed != null && typeof raw.closed !== 'boolean') {
|
|
170
|
+
errors.push('Availability "closed" must be true or false.');
|
|
171
|
+
}
|
|
172
|
+
for (const key of ['opensAt', 'closesAt']) {
|
|
173
|
+
if (raw[key] != null && !isIsoDateTime(raw[key])) {
|
|
174
|
+
errors.push(`Availability "${key}" must be an ISO 8601 date-time (e.g. 2026-11-01T09:00:00Z) or null.`);
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
if (raw.entryLimit != null && !isEntryLimit(raw.entryLimit)) {
|
|
178
|
+
errors.push('Availability "entryLimit" must be a whole number of at least 1.');
|
|
179
|
+
}
|
|
180
|
+
if (raw.closedMessage != null && typeof raw.closedMessage !== 'string') {
|
|
181
|
+
errors.push('Availability "closedMessage" must be a string.');
|
|
182
|
+
}
|
|
183
|
+
if (isIsoDateTime(raw.opensAt) &&
|
|
184
|
+
isIsoDateTime(raw.closesAt) &&
|
|
185
|
+
Date.parse(raw.closesAt) <= Date.parse(raw.opensAt)) {
|
|
186
|
+
errors.push('Availability "closesAt" must be after "opensAt".');
|
|
187
|
+
}
|
|
188
|
+
return errors;
|
|
189
|
+
}
|
|
190
|
+
/**
|
|
191
|
+
* The source's availability, made safe to write onto a duplicate. Every
|
|
192
|
+
* setting is copied, but stored data predates write validation: a legacy
|
|
193
|
+
* window that closes before it opens is dropped (the copy starts as a draft,
|
|
194
|
+
* so nothing goes live with it) instead of failing the duplicate.
|
|
195
|
+
*/
|
|
196
|
+
function availabilityForCopy(value) {
|
|
197
|
+
const copy = normalizeFormAvailability(value);
|
|
198
|
+
if (!copy)
|
|
199
|
+
return null;
|
|
200
|
+
if (validateFormAvailability(copy).length === 0)
|
|
201
|
+
return copy;
|
|
202
|
+
const unscheduled = normalizeFormAvailability({ ...copy, opensAt: null, closesAt: null });
|
|
203
|
+
if (!unscheduled || validateFormAvailability(unscheduled).length > 0)
|
|
204
|
+
return null;
|
|
205
|
+
return unscheduled;
|
|
206
|
+
}
|
|
83
207
|
/** Parse a raw `forms` document row into the typed `FormDefinition` shape. */
|
|
84
208
|
export function parseFormDefinition(doc) {
|
|
85
209
|
const data = asRecord(doc?.data);
|
|
@@ -98,6 +222,7 @@ export function parseFormDefinition(doc) {
|
|
|
98
222
|
: undefined,
|
|
99
223
|
embedSettings: data.embedSettings ? data.embedSettings : undefined,
|
|
100
224
|
spamSettings: data.spamSettings ? data.spamSettings : undefined,
|
|
225
|
+
availability: normalizeFormAvailability(data.availability),
|
|
101
226
|
successMessage: typeof data.successMessage === 'string' ? data.successMessage : undefined,
|
|
102
227
|
redirectUrl: typeof data.redirectUrl === 'string' ? data.redirectUrl : undefined,
|
|
103
228
|
analytics: normalizeAnalyticsConfig(data.analytics),
|
|
@@ -144,6 +269,20 @@ export function validateFormSchema(fields) {
|
|
|
144
269
|
(!Array.isArray(raw.options) || raw.options.length === 0)) {
|
|
145
270
|
errors.push(`Field "${key ?? ''}" of type ${raw.type} requires at least one option.`);
|
|
146
271
|
}
|
|
272
|
+
const rules = [
|
|
273
|
+
...(raw?.conditionalLogic?.show ?? []),
|
|
274
|
+
...(raw?.conditionalLogic?.require ?? []),
|
|
275
|
+
];
|
|
276
|
+
const index = fields.indexOf(raw);
|
|
277
|
+
for (const rule of rules) {
|
|
278
|
+
if (rule.fieldKey === key) {
|
|
279
|
+
errors.push(`Field "${key ?? ''}" cannot reference itself.`);
|
|
280
|
+
}
|
|
281
|
+
const target = fields.findIndex((field) => field.key === rule.fieldKey);
|
|
282
|
+
if (target > index) {
|
|
283
|
+
errors.push(`Field "${key ?? ''}" cannot reference a later field.`);
|
|
284
|
+
}
|
|
285
|
+
}
|
|
147
286
|
}
|
|
148
287
|
return { valid: errors.length === 0, errors };
|
|
149
288
|
}
|
|
@@ -354,6 +493,11 @@ export async function createForm(ctx, input) {
|
|
|
354
493
|
if (!validation.valid) {
|
|
355
494
|
throw new FormValidationError(validation.errors);
|
|
356
495
|
}
|
|
496
|
+
if (input.availability !== undefined) {
|
|
497
|
+
const availabilityErrors = validateFormAvailability(input.availability);
|
|
498
|
+
if (availabilityErrors.length > 0)
|
|
499
|
+
throw new FormValidationError(availabilityErrors);
|
|
500
|
+
}
|
|
357
501
|
let slug = input.slug?.trim() ? slugify(input.slug) : slugify(input.name);
|
|
358
502
|
if (!slug)
|
|
359
503
|
slug = `form-${Date.now()}`;
|
|
@@ -369,6 +513,7 @@ export async function createForm(ctx, input) {
|
|
|
369
513
|
notificationSettings: input.notificationSettings ?? { enabled: false, recipients: [] },
|
|
370
514
|
embedSettings: input.embedSettings ?? {},
|
|
371
515
|
spamSettings: input.spamSettings ?? {},
|
|
516
|
+
availability: normalizeFormAvailability(input.availability) ?? null,
|
|
372
517
|
successMessage: input.successMessage ?? getPrentaConfig()?.forms?.defaultSuccessMessage,
|
|
373
518
|
redirectUrl: input.redirectUrl,
|
|
374
519
|
analytics: normalizeAnalyticsConfig(input.analytics) ?? { enabled: false },
|
|
@@ -406,6 +551,12 @@ export async function updateForm(ctx, id, patch) {
|
|
|
406
551
|
data.spamSettings = patch.spamSettings;
|
|
407
552
|
if (patch.embedSettings !== undefined)
|
|
408
553
|
data.embedSettings = patch.embedSettings;
|
|
554
|
+
if (patch.availability !== undefined) {
|
|
555
|
+
const availabilityErrors = validateFormAvailability(patch.availability);
|
|
556
|
+
if (availabilityErrors.length > 0)
|
|
557
|
+
throw new FormValidationError(availabilityErrors);
|
|
558
|
+
data.availability = normalizeFormAvailability(patch.availability) ?? null;
|
|
559
|
+
}
|
|
409
560
|
if (patch.analytics !== undefined) {
|
|
410
561
|
data.analytics = normalizeAnalyticsConfig(patch.analytics) ?? { enabled: false };
|
|
411
562
|
}
|
|
@@ -450,6 +601,7 @@ export async function duplicateForm(ctx, id) {
|
|
|
450
601
|
notificationSettings: source.notificationSettings,
|
|
451
602
|
embedSettings: {},
|
|
452
603
|
spamSettings: source.spamSettings,
|
|
604
|
+
availability: availabilityForCopy(source.availability),
|
|
453
605
|
successMessage: source.successMessage,
|
|
454
606
|
redirectUrl: source.redirectUrl,
|
|
455
607
|
analytics: source.analytics,
|