@kelpie/server 0.8.0 → 0.9.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/lib/ids.d.ts +11 -0
- package/dist/lib/ids.d.ts.map +1 -1
- package/dist/lib/ids.js +11 -0
- package/dist/lib/ids.js.map +1 -1
- package/dist/modules/activities/repository.d.ts.map +1 -1
- package/dist/modules/activities/repository.js +19 -20
- package/dist/modules/activities/repository.js.map +1 -1
- package/dist/modules/activities/wording.d.ts +12 -0
- package/dist/modules/activities/wording.d.ts.map +1 -1
- package/dist/modules/activities/wording.js +16 -0
- package/dist/modules/activities/wording.js.map +1 -1
- package/dist/modules/agent-tasks/catalog.d.ts.map +1 -1
- package/dist/modules/agent-tasks/catalog.js +62 -0
- package/dist/modules/agent-tasks/catalog.js.map +1 -1
- package/dist/modules/agent-tasks/resolve.d.ts.map +1 -1
- package/dist/modules/agent-tasks/resolve.js +42 -9
- package/dist/modules/agent-tasks/resolve.js.map +1 -1
- package/dist/modules/agent-tasks/routes.d.ts +2 -0
- package/dist/modules/agent-tasks/routes.d.ts.map +1 -1
- package/dist/modules/attachedRecords.d.ts +6 -1
- package/dist/modules/attachedRecords.d.ts.map +1 -1
- package/dist/modules/attachedRecords.js +15 -1
- package/dist/modules/attachedRecords.js.map +1 -1
- package/dist/modules/companies/index.d.ts.map +1 -1
- package/dist/modules/companies/index.js +3 -1
- package/dist/modules/companies/index.js.map +1 -1
- package/dist/modules/companies/routes.d.ts +14 -0
- package/dist/modules/companies/routes.d.ts.map +1 -1
- package/dist/modules/companies/routes.js +7 -0
- package/dist/modules/companies/routes.js.map +1 -1
- package/dist/modules/companies/schema.d.ts +20 -0
- package/dist/modules/companies/schema.d.ts.map +1 -1
- package/dist/modules/companies/schema.js +6 -1
- package/dist/modules/companies/schema.js.map +1 -1
- package/dist/modules/companies/service.d.ts +5 -0
- package/dist/modules/companies/service.d.ts.map +1 -1
- package/dist/modules/companies/service.js +24 -12
- package/dist/modules/companies/service.js.map +1 -1
- package/dist/modules/consent-purposes/capabilities.d.ts +7 -0
- package/dist/modules/consent-purposes/capabilities.d.ts.map +1 -0
- package/dist/modules/consent-purposes/capabilities.js +10 -0
- package/dist/modules/consent-purposes/capabilities.js.map +1 -0
- package/dist/modules/consent-purposes/events.d.ts +38 -0
- package/dist/modules/consent-purposes/events.d.ts.map +1 -0
- package/dist/modules/consent-purposes/events.js +17 -0
- package/dist/modules/consent-purposes/events.js.map +1 -0
- package/dist/modules/consent-purposes/index.d.ts +13 -0
- package/dist/modules/consent-purposes/index.d.ts.map +1 -0
- package/dist/modules/consent-purposes/index.js +41 -0
- package/dist/modules/consent-purposes/index.js.map +1 -0
- package/dist/modules/consent-purposes/repository.d.ts +21 -0
- package/dist/modules/consent-purposes/repository.d.ts.map +1 -0
- package/dist/modules/consent-purposes/repository.js +98 -0
- package/dist/modules/consent-purposes/repository.js.map +1 -0
- package/dist/modules/consent-purposes/routes.d.ts +39 -0
- package/dist/modules/consent-purposes/routes.d.ts.map +1 -0
- package/dist/modules/consent-purposes/routes.js +79 -0
- package/dist/modules/consent-purposes/routes.js.map +1 -0
- package/dist/modules/consent-purposes/schema.d.ts +175 -0
- package/dist/modules/consent-purposes/schema.d.ts.map +1 -0
- package/dist/modules/consent-purposes/schema.js +35 -0
- package/dist/modules/consent-purposes/schema.js.map +1 -0
- package/dist/modules/consent-purposes/service.d.ts +50 -0
- package/dist/modules/consent-purposes/service.d.ts.map +1 -0
- package/dist/modules/consent-purposes/service.js +263 -0
- package/dist/modules/consent-purposes/service.js.map +1 -0
- package/dist/modules/consent-purposes/starters.d.ts +17 -0
- package/dist/modules/consent-purposes/starters.d.ts.map +1 -0
- package/dist/modules/consent-purposes/starters.js +15 -0
- package/dist/modules/consent-purposes/starters.js.map +1 -0
- package/dist/modules/consent-purposes/tools.d.ts +4 -0
- package/dist/modules/consent-purposes/tools.d.ts.map +1 -0
- package/dist/modules/consent-purposes/tools.js +29 -0
- package/dist/modules/consent-purposes/tools.js.map +1 -0
- package/dist/modules/core.d.ts.map +1 -1
- package/dist/modules/core.js +10 -0
- package/dist/modules/core.js.map +1 -1
- package/dist/modules/custom-fields/capabilities.d.ts +12 -0
- package/dist/modules/custom-fields/capabilities.d.ts.map +1 -0
- package/dist/modules/custom-fields/capabilities.js +15 -0
- package/dist/modules/custom-fields/capabilities.js.map +1 -0
- package/dist/modules/custom-fields/events.d.ts +49 -0
- package/dist/modules/custom-fields/events.d.ts.map +1 -0
- package/dist/modules/custom-fields/events.js +25 -0
- package/dist/modules/custom-fields/events.js.map +1 -0
- package/dist/modules/custom-fields/index.d.ts +19 -0
- package/dist/modules/custom-fields/index.d.ts.map +1 -0
- package/dist/modules/custom-fields/index.js +46 -0
- package/dist/modules/custom-fields/index.js.map +1 -0
- package/dist/modules/custom-fields/repository.d.ts +37 -0
- package/dist/modules/custom-fields/repository.d.ts.map +1 -0
- package/dist/modules/custom-fields/repository.js +144 -0
- package/dist/modules/custom-fields/repository.js.map +1 -0
- package/dist/modules/custom-fields/routes.d.ts +44 -0
- package/dist/modules/custom-fields/routes.d.ts.map +1 -0
- package/dist/modules/custom-fields/routes.js +103 -0
- package/dist/modules/custom-fields/routes.js.map +1 -0
- package/dist/modules/custom-fields/schema.d.ts +215 -0
- package/dist/modules/custom-fields/schema.d.ts.map +1 -0
- package/dist/modules/custom-fields/schema.js +43 -0
- package/dist/modules/custom-fields/schema.js.map +1 -0
- package/dist/modules/custom-fields/service.d.ts +57 -0
- package/dist/modules/custom-fields/service.d.ts.map +1 -0
- package/dist/modules/custom-fields/service.js +273 -0
- package/dist/modules/custom-fields/service.js.map +1 -0
- package/dist/modules/custom-fields/tools.d.ts +4 -0
- package/dist/modules/custom-fields/tools.d.ts.map +1 -0
- package/dist/modules/custom-fields/tools.js +38 -0
- package/dist/modules/custom-fields/tools.js.map +1 -0
- package/dist/modules/custom-fields/values.d.ts +49 -0
- package/dist/modules/custom-fields/values.d.ts.map +1 -0
- package/dist/modules/custom-fields/values.js +249 -0
- package/dist/modules/custom-fields/values.js.map +1 -0
- package/dist/modules/custom-fields/wire.d.ts +12 -0
- package/dist/modules/custom-fields/wire.d.ts.map +1 -0
- package/dist/modules/custom-fields/wire.js +30 -0
- package/dist/modules/custom-fields/wire.js.map +1 -0
- package/dist/modules/dashboard/repository.d.ts.map +1 -1
- package/dist/modules/dashboard/repository.js +4 -3
- package/dist/modules/dashboard/repository.js.map +1 -1
- package/dist/modules/deals/index.d.ts +2 -1
- package/dist/modules/deals/index.d.ts.map +1 -1
- package/dist/modules/deals/index.js +5 -2
- package/dist/modules/deals/index.js.map +1 -1
- package/dist/modules/deals/repository.d.ts +0 -16
- package/dist/modules/deals/repository.d.ts.map +1 -1
- package/dist/modules/deals/repository.js +6 -76
- package/dist/modules/deals/repository.js.map +1 -1
- package/dist/modules/deals/routes.d.ts +14 -0
- package/dist/modules/deals/routes.d.ts.map +1 -1
- package/dist/modules/deals/routes.js +7 -0
- package/dist/modules/deals/routes.js.map +1 -1
- package/dist/modules/deals/schema.d.ts +20 -42
- package/dist/modules/deals/schema.d.ts.map +1 -1
- package/dist/modules/deals/schema.js +6 -11
- package/dist/modules/deals/schema.js.map +1 -1
- package/dist/modules/deals/service.d.ts +13 -2
- package/dist/modules/deals/service.d.ts.map +1 -1
- package/dist/modules/deals/service.js +43 -20
- package/dist/modules/deals/service.js.map +1 -1
- package/dist/modules/decisions/repository.d.ts.map +1 -1
- package/dist/modules/decisions/repository.js +2 -0
- package/dist/modules/decisions/repository.js.map +1 -1
- package/dist/modules/decisions/routes.d.ts +1 -0
- package/dist/modules/decisions/routes.d.ts.map +1 -1
- package/dist/modules/enquiries/events.d.ts +44 -0
- package/dist/modules/enquiries/events.d.ts.map +1 -0
- package/dist/modules/enquiries/events.js +19 -0
- package/dist/modules/enquiries/events.js.map +1 -0
- package/dist/modules/enquiries/index.d.ts +13 -0
- package/dist/modules/enquiries/index.d.ts.map +1 -0
- package/dist/modules/enquiries/index.js +44 -0
- package/dist/modules/enquiries/index.js.map +1 -0
- package/dist/modules/enquiries/repository.d.ts +30 -0
- package/dist/modules/enquiries/repository.d.ts.map +1 -0
- package/dist/modules/enquiries/repository.js +94 -0
- package/dist/modules/enquiries/repository.js.map +1 -0
- package/dist/modules/enquiries/routes.d.ts +52 -0
- package/dist/modules/enquiries/routes.d.ts.map +1 -0
- package/dist/modules/enquiries/routes.js +127 -0
- package/dist/modules/enquiries/routes.js.map +1 -0
- package/dist/modules/enquiries/schema.d.ts +290 -0
- package/dist/modules/enquiries/schema.d.ts.map +1 -0
- package/dist/modules/enquiries/schema.js +52 -0
- package/dist/modules/enquiries/schema.js.map +1 -0
- package/dist/modules/enquiries/service.d.ts +85 -0
- package/dist/modules/enquiries/service.d.ts.map +1 -0
- package/dist/modules/enquiries/service.js +370 -0
- package/dist/modules/enquiries/service.js.map +1 -0
- package/dist/modules/enquiries/tools.d.ts +4 -0
- package/dist/modules/enquiries/tools.d.ts.map +1 -0
- package/dist/modules/enquiries/tools.js +50 -0
- package/dist/modules/enquiries/tools.js.map +1 -0
- package/dist/modules/eventCatalogs.d.ts +3 -0
- package/dist/modules/eventCatalogs.d.ts.map +1 -1
- package/dist/modules/eventCatalogs.js +3 -0
- package/dist/modules/eventCatalogs.js.map +1 -1
- package/dist/modules/forms/embed.d.ts +20 -6
- package/dist/modules/forms/embed.d.ts.map +1 -1
- package/dist/modules/forms/embed.js +359 -43
- package/dist/modules/forms/embed.js.map +1 -1
- package/dist/modules/forms/events.d.ts +20 -7
- package/dist/modules/forms/events.d.ts.map +1 -1
- package/dist/modules/forms/events.js +20 -2
- package/dist/modules/forms/events.js.map +1 -1
- package/dist/modules/forms/fields.d.ts +14 -1
- package/dist/modules/forms/fields.d.ts.map +1 -1
- package/dist/modules/forms/fields.js +87 -3
- package/dist/modules/forms/fields.js.map +1 -1
- package/dist/modules/forms/index.d.ts.map +1 -1
- package/dist/modules/forms/index.js +12 -1
- package/dist/modules/forms/index.js.map +1 -1
- package/dist/modules/forms/mapping.d.ts +62 -5
- package/dist/modules/forms/mapping.d.ts.map +1 -1
- package/dist/modules/forms/mapping.js +139 -5
- package/dist/modules/forms/mapping.js.map +1 -1
- package/dist/modules/forms/publicRoutes.d.ts.map +1 -1
- package/dist/modules/forms/publicRoutes.js +29 -1
- package/dist/modules/forms/publicRoutes.js.map +1 -1
- package/dist/modules/forms/repository.d.ts +31 -0
- package/dist/modules/forms/repository.d.ts.map +1 -1
- package/dist/modules/forms/repository.js +90 -1
- package/dist/modules/forms/repository.js.map +1 -1
- package/dist/modules/forms/routes.d.ts +83 -1
- package/dist/modules/forms/routes.d.ts.map +1 -1
- package/dist/modules/forms/routes.js +185 -2
- package/dist/modules/forms/routes.js.map +1 -1
- package/dist/modules/forms/schema.d.ts +672 -1
- package/dist/modules/forms/schema.d.ts.map +1 -1
- package/dist/modules/forms/schema.js +146 -3
- package/dist/modules/forms/schema.js.map +1 -1
- package/dist/modules/forms/service.d.ts +54 -1
- package/dist/modules/forms/service.d.ts.map +1 -1
- package/dist/modules/forms/service.js +338 -28
- package/dist/modules/forms/service.js.map +1 -1
- package/dist/modules/forms/submission.d.ts +15 -0
- package/dist/modules/forms/submission.d.ts.map +1 -1
- package/dist/modules/forms/submission.js +418 -40
- package/dist/modules/forms/submission.js.map +1 -1
- package/dist/modules/import-export/drafts.d.ts +10 -0
- package/dist/modules/import-export/drafts.d.ts.map +1 -1
- package/dist/modules/import-export/drafts.js +16 -2
- package/dist/modules/import-export/drafts.js.map +1 -1
- package/dist/modules/import-export/exportRows.d.ts +7 -4
- package/dist/modules/import-export/exportRows.d.ts.map +1 -1
- package/dist/modules/import-export/exportRows.js +20 -5
- package/dist/modules/import-export/exportRows.js.map +1 -1
- package/dist/modules/import-export/plan.d.ts +12 -1
- package/dist/modules/import-export/plan.d.ts.map +1 -1
- package/dist/modules/import-export/plan.js +29 -2
- package/dist/modules/import-export/plan.js.map +1 -1
- package/dist/modules/import-export/presets.d.ts.map +1 -1
- package/dist/modules/import-export/presets.js +10 -0
- package/dist/modules/import-export/presets.js.map +1 -1
- package/dist/modules/import-export/repository.d.ts +11 -1
- package/dist/modules/import-export/repository.d.ts.map +1 -1
- package/dist/modules/import-export/repository.js +42 -9
- package/dist/modules/import-export/repository.js.map +1 -1
- package/dist/modules/import-export/routes.d.ts.map +1 -1
- package/dist/modules/import-export/routes.js +4 -0
- package/dist/modules/import-export/routes.js.map +1 -1
- package/dist/modules/import-export/schema.d.ts +17 -0
- package/dist/modules/import-export/schema.d.ts.map +1 -1
- package/dist/modules/import-export/schema.js +11 -0
- package/dist/modules/import-export/schema.js.map +1 -1
- package/dist/modules/import-export/service.d.ts +6 -0
- package/dist/modules/import-export/service.d.ts.map +1 -1
- package/dist/modules/import-export/service.js +14 -2
- package/dist/modules/import-export/service.js.map +1 -1
- package/dist/modules/import-export/streams.d.ts.map +1 -1
- package/dist/modules/import-export/streams.js +3 -3
- package/dist/modules/import-export/streams.js.map +1 -1
- package/dist/modules/import-export/tools.d.ts.map +1 -1
- package/dist/modules/import-export/tools.js +8 -0
- package/dist/modules/import-export/tools.js.map +1 -1
- package/dist/modules/import-export/validation.d.ts.map +1 -1
- package/dist/modules/import-export/validation.js +22 -1
- package/dist/modules/import-export/validation.js.map +1 -1
- package/dist/modules/import-export/writes.d.ts.map +1 -1
- package/dist/modules/import-export/writes.js +37 -4
- package/dist/modules/import-export/writes.js.map +1 -1
- package/dist/modules/lists/repository.d.ts +11 -0
- package/dist/modules/lists/repository.d.ts.map +1 -1
- package/dist/modules/lists/repository.js +13 -0
- package/dist/modules/lists/repository.js.map +1 -1
- package/dist/modules/lists/routes.d.ts +4 -0
- package/dist/modules/lists/routes.d.ts.map +1 -1
- package/dist/modules/lists/routes.js +8 -0
- package/dist/modules/lists/routes.js.map +1 -1
- package/dist/modules/lists/schema.d.ts +17 -0
- package/dist/modules/lists/schema.d.ts.map +1 -1
- package/dist/modules/lists/schema.js +10 -0
- package/dist/modules/lists/schema.js.map +1 -1
- package/dist/modules/lists/service.d.ts +14 -2
- package/dist/modules/lists/service.d.ts.map +1 -1
- package/dist/modules/lists/service.js +55 -7
- package/dist/modules/lists/service.js.map +1 -1
- package/dist/modules/mcp/index.d.ts.map +1 -1
- package/dist/modules/mcp/index.js +5 -0
- package/dist/modules/mcp/index.js.map +1 -1
- package/dist/modules/notes/routes.d.ts +1 -0
- package/dist/modules/notes/routes.d.ts.map +1 -1
- package/dist/modules/opportunities/index.d.ts.map +1 -1
- package/dist/modules/opportunities/index.js +3 -1
- package/dist/modules/opportunities/index.js.map +1 -1
- package/dist/modules/opportunities/repository.d.ts +2 -0
- package/dist/modules/opportunities/repository.d.ts.map +1 -1
- package/dist/modules/opportunities/repository.js +4 -0
- package/dist/modules/opportunities/repository.js.map +1 -1
- package/dist/modules/opportunities/routes.d.ts +16 -0
- package/dist/modules/opportunities/routes.d.ts.map +1 -1
- package/dist/modules/opportunities/routes.js +13 -0
- package/dist/modules/opportunities/routes.js.map +1 -1
- package/dist/modules/opportunities/schema.d.ts +20 -0
- package/dist/modules/opportunities/schema.d.ts.map +1 -1
- package/dist/modules/opportunities/schema.js +6 -1
- package/dist/modules/opportunities/schema.js.map +1 -1
- package/dist/modules/opportunities/service.d.ts +20 -3
- package/dist/modules/opportunities/service.d.ts.map +1 -1
- package/dist/modules/opportunities/service.js +99 -18
- package/dist/modules/opportunities/service.js.map +1 -1
- package/dist/modules/opportunities/tools.d.ts.map +1 -1
- package/dist/modules/opportunities/tools.js +2 -0
- package/dist/modules/opportunities/tools.js.map +1 -1
- package/dist/modules/partnerships/index.d.ts.map +1 -1
- package/dist/modules/partnerships/index.js +3 -1
- package/dist/modules/partnerships/index.js.map +1 -1
- package/dist/modules/partnerships/repository.d.ts +0 -17
- package/dist/modules/partnerships/repository.d.ts.map +1 -1
- package/dist/modules/partnerships/repository.js +6 -82
- package/dist/modules/partnerships/repository.js.map +1 -1
- package/dist/modules/partnerships/routes.d.ts +14 -0
- package/dist/modules/partnerships/routes.d.ts.map +1 -1
- package/dist/modules/partnerships/routes.js +7 -0
- package/dist/modules/partnerships/routes.js.map +1 -1
- package/dist/modules/partnerships/schema.d.ts +20 -41
- package/dist/modules/partnerships/schema.d.ts.map +1 -1
- package/dist/modules/partnerships/schema.js +6 -10
- package/dist/modules/partnerships/schema.js.map +1 -1
- package/dist/modules/partnerships/service.d.ts +11 -1
- package/dist/modules/partnerships/service.d.ts.map +1 -1
- package/dist/modules/partnerships/service.js +43 -20
- package/dist/modules/partnerships/service.js.map +1 -1
- package/dist/modules/people/consentHydration.d.ts +26 -0
- package/dist/modules/people/consentHydration.d.ts.map +1 -0
- package/dist/modules/people/consentHydration.js +100 -0
- package/dist/modules/people/consentHydration.js.map +1 -0
- package/dist/modules/people/index.d.ts.map +1 -1
- package/dist/modules/people/index.js +3 -1
- package/dist/modules/people/index.js.map +1 -1
- package/dist/modules/people/personConsentWrites.d.ts +40 -0
- package/dist/modules/people/personConsentWrites.d.ts.map +1 -0
- package/dist/modules/people/personConsentWrites.js +98 -0
- package/dist/modules/people/personConsentWrites.js.map +1 -0
- package/dist/modules/people/repository.d.ts.map +1 -1
- package/dist/modules/people/repository.js +5 -1
- package/dist/modules/people/repository.js.map +1 -1
- package/dist/modules/people/routes.d.ts +57 -4
- package/dist/modules/people/routes.d.ts.map +1 -1
- package/dist/modules/people/routes.js +104 -5
- package/dist/modules/people/routes.js.map +1 -1
- package/dist/modules/people/schema.d.ts +366 -1
- package/dist/modules/people/schema.d.ts.map +1 -1
- package/dist/modules/people/schema.js +92 -2
- package/dist/modules/people/schema.js.map +1 -1
- package/dist/modules/people/service.d.ts +30 -1
- package/dist/modules/people/service.d.ts.map +1 -1
- package/dist/modules/people/service.js +115 -38
- package/dist/modules/people/service.js.map +1 -1
- package/dist/modules/people/tools.d.ts.map +1 -1
- package/dist/modules/people/tools.js +4 -1
- package/dist/modules/people/tools.js.map +1 -1
- package/dist/modules/personLinks.d.ts +79 -0
- package/dist/modules/personLinks.d.ts.map +1 -0
- package/dist/modules/personLinks.js +155 -0
- package/dist/modules/personLinks.js.map +1 -0
- package/dist/modules/pipelines/routes.d.ts +1 -0
- package/dist/modules/pipelines/routes.d.ts.map +1 -1
- package/dist/modules/plans/routes.d.ts +1 -0
- package/dist/modules/plans/routes.d.ts.map +1 -1
- package/dist/modules/raises/index.d.ts.map +1 -1
- package/dist/modules/raises/index.js +3 -1
- package/dist/modules/raises/index.js.map +1 -1
- package/dist/modules/raises/repository.d.ts +0 -17
- package/dist/modules/raises/repository.d.ts.map +1 -1
- package/dist/modules/raises/repository.js +6 -77
- package/dist/modules/raises/repository.js.map +1 -1
- package/dist/modules/raises/routes.d.ts +14 -0
- package/dist/modules/raises/routes.d.ts.map +1 -1
- package/dist/modules/raises/routes.js +7 -0
- package/dist/modules/raises/routes.js.map +1 -1
- package/dist/modules/raises/schema.d.ts +20 -41
- package/dist/modules/raises/schema.d.ts.map +1 -1
- package/dist/modules/raises/schema.js +6 -10
- package/dist/modules/raises/schema.js.map +1 -1
- package/dist/modules/raises/service.d.ts +11 -1
- package/dist/modules/raises/service.d.ts.map +1 -1
- package/dist/modules/raises/service.js +41 -18
- package/dist/modules/raises/service.js.map +1 -1
- package/dist/modules/recordTargets.d.ts.map +1 -1
- package/dist/modules/recordTargets.js +2 -0
- package/dist/modules/recordTargets.js.map +1 -1
- package/dist/modules/references.d.ts +10 -0
- package/dist/modules/references.d.ts.map +1 -1
- package/dist/modules/references.js +27 -4
- package/dist/modules/references.js.map +1 -1
- package/dist/modules/sample-data/fixture.d.ts +21 -0
- package/dist/modules/sample-data/fixture.d.ts.map +1 -1
- package/dist/modules/sample-data/fixture.js +40 -0
- package/dist/modules/sample-data/fixture.js.map +1 -1
- package/dist/modules/sample-data/index.d.ts.map +1 -1
- package/dist/modules/sample-data/index.js +1 -0
- package/dist/modules/sample-data/index.js.map +1 -1
- package/dist/modules/sample-data/routes.d.ts.map +1 -1
- package/dist/modules/sample-data/routes.js +1 -0
- package/dist/modules/sample-data/routes.js.map +1 -1
- package/dist/modules/sample-data/service.d.ts +1 -0
- package/dist/modules/sample-data/service.d.ts.map +1 -1
- package/dist/modules/sample-data/service.js +77 -8
- package/dist/modules/sample-data/service.js.map +1 -1
- package/dist/modules/search/index.d.ts +1 -1
- package/dist/modules/search/index.d.ts.map +1 -1
- package/dist/modules/search/index.js +2 -1
- package/dist/modules/search/index.js.map +1 -1
- package/dist/modules/search/repository.d.ts +1 -0
- package/dist/modules/search/repository.d.ts.map +1 -1
- package/dist/modules/search/repository.js +23 -0
- package/dist/modules/search/repository.js.map +1 -1
- package/dist/modules/search/service.d.ts +3 -3
- package/dist/modules/search/service.d.ts.map +1 -1
- package/dist/modules/search/service.js +5 -4
- package/dist/modules/search/service.js.map +1 -1
- package/dist/modules/stagedRecords.d.ts +3 -3
- package/dist/modules/stagedRecords.d.ts.map +1 -1
- package/dist/modules/stagedRecords.js +9 -0
- package/dist/modules/stagedRecords.js.map +1 -1
- package/dist/modules/webhooks/payloads.d.ts.map +1 -1
- package/dist/modules/webhooks/payloads.js +15 -2
- package/dist/modules/webhooks/payloads.js.map +1 -1
- package/dist/modules/workspace/repository.d.ts +2 -0
- package/dist/modules/workspace/repository.d.ts.map +1 -1
- package/dist/modules/workspace/repository.js +7 -0
- package/dist/modules/workspace/repository.js.map +1 -1
- package/dist/modules/workspace/service.d.ts.map +1 -1
- package/dist/modules/workspace/service.js +10 -0
- package/dist/modules/workspace/service.js.map +1 -1
- package/dist/modules/workspace/starters.d.ts.map +1 -1
- package/dist/modules/workspace/starters.js +5 -0
- package/dist/modules/workspace/starters.js.map +1 -1
- package/dist/runtime/events.d.ts +1 -1
- package/dist/runtime/events.d.ts.map +1 -1
- package/dist/runtime/events.js +1 -0
- package/dist/runtime/events.js.map +1 -1
- package/dist/schema/index.d.ts +3 -0
- package/dist/schema/index.d.ts.map +1 -1
- package/dist/schema/index.js +3 -0
- package/dist/schema/index.js.map +1 -1
- package/dist/testing/database.d.ts +5 -1
- package/dist/testing/database.d.ts.map +1 -1
- package/dist/testing/database.js +81 -10
- package/dist/testing/database.js.map +1 -1
- package/migrations/0024_third_king_cobra.sql +46 -0
- package/migrations/0025_worthless_chimera.sql +3 -0
- package/migrations/0026_late_aqueduct.sql +46 -0
- package/migrations/0027_brainy_silver_sable.sql +3 -0
- package/migrations/0028_freezing_scrambler.sql +19 -0
- package/migrations/0029_custom_fields.sql +26 -0
- package/migrations/0030_enquiries.sql +79 -0
- package/migrations/0031_consent.sql +45 -0
- package/migrations/0032_form_field_statement.sql +1 -0
- package/migrations/0033_form_field_consent_purpose_ids.sql +5 -0
- package/migrations/0034_drop_form_field_consent_purpose_id.sql +1 -0
- package/migrations/0035_form_field_consent_purpose_labels.sql +1 -0
- package/migrations/0036_form_field_notice_type.sql +2 -0
- package/migrations/meta/0024_snapshot.json +5516 -0
- package/migrations/meta/0025_snapshot.json +5336 -0
- package/migrations/meta/0026_snapshot.json +5710 -0
- package/migrations/meta/0027_snapshot.json +5716 -0
- package/migrations/meta/0028_snapshot.json +5740 -0
- package/migrations/meta/0029_snapshot.json +5935 -0
- package/migrations/meta/0030_snapshot.json +6245 -0
- package/migrations/meta/0031_snapshot.json +6572 -0
- package/migrations/meta/0032_snapshot.json +6578 -0
- package/migrations/meta/0033_snapshot.json +6572 -0
- package/migrations/meta/0034_snapshot.json +6566 -0
- package/migrations/meta/0035_snapshot.json +6573 -0
- package/migrations/meta/0036_snapshot.json +6573 -0
- package/migrations/meta/_journal.json +91 -0
- package/package.json +2 -2
- package/src/lib/ids.ts +11 -0
- package/src/modules/activities/repository.ts +22 -23
- package/src/modules/activities/wording.ts +18 -0
- package/src/modules/agent-tasks/catalog.ts +63 -0
- package/src/modules/agent-tasks/resolve.ts +64 -24
- package/src/modules/attachedRecords.ts +29 -2
- package/src/modules/companies/index.ts +3 -1
- package/src/modules/companies/routes.ts +7 -0
- package/src/modules/companies/schema.ts +7 -1
- package/src/modules/companies/service.ts +48 -13
- package/src/modules/consent-purposes/capabilities.ts +12 -0
- package/src/modules/consent-purposes/events.ts +38 -0
- package/src/modules/consent-purposes/index.ts +48 -0
- package/src/modules/consent-purposes/repository.ts +163 -0
- package/src/modules/consent-purposes/routes.ts +122 -0
- package/src/modules/consent-purposes/schema.ts +46 -0
- package/src/modules/consent-purposes/service.ts +423 -0
- package/src/modules/consent-purposes/starters.ts +32 -0
- package/src/modules/consent-purposes/tools.ts +44 -0
- package/src/modules/core.ts +10 -0
- package/src/modules/custom-fields/capabilities.ts +17 -0
- package/src/modules/custom-fields/events.ts +51 -0
- package/src/modules/custom-fields/index.ts +61 -0
- package/src/modules/custom-fields/repository.ts +225 -0
- package/src/modules/custom-fields/routes.ts +155 -0
- package/src/modules/custom-fields/schema.ts +61 -0
- package/src/modules/custom-fields/service.ts +439 -0
- package/src/modules/custom-fields/tools.ts +53 -0
- package/src/modules/custom-fields/values.ts +352 -0
- package/src/modules/custom-fields/wire.ts +32 -0
- package/src/modules/dashboard/repository.ts +4 -3
- package/src/modules/deals/index.ts +5 -2
- package/src/modules/deals/repository.ts +6 -106
- package/src/modules/deals/routes.ts +7 -0
- package/src/modules/deals/schema.ts +7 -15
- package/src/modules/deals/service.ts +92 -23
- package/src/modules/decisions/repository.ts +2 -0
- package/src/modules/enquiries/events.ts +45 -0
- package/src/modules/enquiries/index.ts +50 -0
- package/src/modules/enquiries/repository.ts +164 -0
- package/src/modules/enquiries/routes.ts +172 -0
- package/src/modules/enquiries/schema.ts +59 -0
- package/src/modules/enquiries/service.ts +644 -0
- package/src/modules/enquiries/tools.ts +66 -0
- package/src/modules/eventCatalogs.ts +3 -0
- package/src/modules/forms/embed.ts +391 -44
- package/src/modules/forms/events.ts +30 -2
- package/src/modules/forms/fields.ts +102 -2
- package/src/modules/forms/index.ts +12 -1
- package/src/modules/forms/mapping.ts +183 -6
- package/src/modules/forms/publicRoutes.ts +43 -1
- package/src/modules/forms/repository.ts +162 -1
- package/src/modules/forms/routes.ts +212 -2
- package/src/modules/forms/schema.ts +166 -4
- package/src/modules/forms/service.ts +565 -41
- package/src/modules/forms/submission.ts +718 -44
- package/src/modules/import-export/drafts.ts +20 -1
- package/src/modules/import-export/exportRows.ts +21 -5
- package/src/modules/import-export/plan.ts +47 -2
- package/src/modules/import-export/presets.ts +10 -0
- package/src/modules/import-export/repository.ts +73 -8
- package/src/modules/import-export/routes.ts +4 -0
- package/src/modules/import-export/schema.ts +11 -0
- package/src/modules/import-export/service.ts +28 -2
- package/src/modules/import-export/streams.ts +3 -1
- package/src/modules/import-export/tools.ts +10 -0
- package/src/modules/import-export/validation.ts +28 -0
- package/src/modules/import-export/writes.ts +70 -5
- package/src/modules/lists/repository.ts +30 -0
- package/src/modules/lists/routes.ts +8 -0
- package/src/modules/lists/schema.ts +10 -0
- package/src/modules/lists/service.ts +110 -9
- package/src/modules/mcp/index.ts +5 -0
- package/src/modules/opportunities/index.ts +3 -1
- package/src/modules/opportunities/repository.ts +11 -0
- package/src/modules/opportunities/routes.ts +13 -0
- package/src/modules/opportunities/schema.ts +7 -1
- package/src/modules/opportunities/service.ts +188 -22
- package/src/modules/opportunities/tools.ts +2 -0
- package/src/modules/partnerships/index.ts +3 -1
- package/src/modules/partnerships/repository.ts +6 -117
- package/src/modules/partnerships/routes.ts +7 -0
- package/src/modules/partnerships/schema.ts +7 -14
- package/src/modules/partnerships/service.ts +93 -22
- package/src/modules/people/consentHydration.ts +167 -0
- package/src/modules/people/index.ts +3 -1
- package/src/modules/people/personConsentWrites.ts +177 -0
- package/src/modules/people/repository.ts +5 -0
- package/src/modules/people/routes.ts +127 -18
- package/src/modules/people/schema.ts +109 -3
- package/src/modules/people/service.ts +186 -40
- package/src/modules/people/tools.ts +5 -1
- package/src/modules/personLinks.ts +278 -0
- package/src/modules/raises/index.ts +3 -1
- package/src/modules/raises/repository.ts +6 -107
- package/src/modules/raises/routes.ts +7 -0
- package/src/modules/raises/schema.ts +7 -14
- package/src/modules/raises/service.ts +91 -20
- package/src/modules/recordTargets.ts +2 -0
- package/src/modules/references.ts +43 -4
- package/src/modules/sample-data/fixture.ts +63 -0
- package/src/modules/sample-data/index.ts +1 -0
- package/src/modules/sample-data/routes.ts +1 -0
- package/src/modules/sample-data/service.ts +97 -8
- package/src/modules/search/index.ts +2 -1
- package/src/modules/search/repository.ts +33 -1
- package/src/modules/search/service.ts +7 -5
- package/src/modules/stagedRecords.ts +18 -3
- package/src/modules/webhooks/payloads.ts +20 -2
- package/src/modules/workspace/repository.ts +12 -0
- package/src/modules/workspace/service.ts +14 -0
- package/src/modules/workspace/starters.ts +5 -0
- package/src/runtime/events.ts +1 -0
- package/src/schema/index.ts +3 -0
- package/src/testing/database.ts +97 -11
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
import { z } from 'zod'
|
|
2
|
+
|
|
3
|
+
import type { McpToolRegistry } from '../../runtime/module.ts'
|
|
4
|
+
import {
|
|
5
|
+
idArg,
|
|
6
|
+
idSetArg,
|
|
7
|
+
listWindowShape,
|
|
8
|
+
registerCrudTools,
|
|
9
|
+
termArg,
|
|
10
|
+
toSet,
|
|
11
|
+
} from '../crudTools.ts'
|
|
12
|
+
import { dealResponse } from '../deals/routes.ts'
|
|
13
|
+
import { createBody, enquiryResponse, toCreateInput, toUpdateInput, updateBody } from './routes.ts'
|
|
14
|
+
import type { EnquiriesService } from './service.ts'
|
|
15
|
+
|
|
16
|
+
/** `enquiries_*`. Same schemas and mappers as `/v1/enquiries`. */
|
|
17
|
+
|
|
18
|
+
const listArgs = z.strictObject({
|
|
19
|
+
...listWindowShape,
|
|
20
|
+
q: termArg,
|
|
21
|
+
source: idSetArg.optional().describe('Sources are free text, so a match here is exact.'),
|
|
22
|
+
company_id: idSetArg.optional().describe('Only enquiries with these companies.'),
|
|
23
|
+
stage_id: idSetArg.optional().describe('Only enquiries in these pipeline stages.'),
|
|
24
|
+
person_id: idSetArg.optional().describe('Only enquiries any of these people are on.'),
|
|
25
|
+
})
|
|
26
|
+
|
|
27
|
+
export function registerEnquiriesTools(mcp: McpToolRegistry, service: EnquiriesService): void {
|
|
28
|
+
registerCrudTools(mcp, {
|
|
29
|
+
resource: 'enquiries',
|
|
30
|
+
subject: 'enquiry',
|
|
31
|
+
about:
|
|
32
|
+
'An inbound enquiry: a top-of-funnel request that may become a Deal once qualified. ' +
|
|
33
|
+
'Not itself a deal.',
|
|
34
|
+
service,
|
|
35
|
+
render: enquiryResponse,
|
|
36
|
+
listArgs,
|
|
37
|
+
toFilters: (args) => ({
|
|
38
|
+
term: args.q,
|
|
39
|
+
sources: toSet(args.source),
|
|
40
|
+
companyIds: toSet(args.company_id),
|
|
41
|
+
stageIds: toSet(args.stage_id),
|
|
42
|
+
personIds: toSet(args.person_id),
|
|
43
|
+
}),
|
|
44
|
+
createArgs: createBody,
|
|
45
|
+
toCreateInput,
|
|
46
|
+
updateArgs: updateBody.extend({ id: idArg }),
|
|
47
|
+
toUpdateInput,
|
|
48
|
+
})
|
|
49
|
+
|
|
50
|
+
mcp.tool({
|
|
51
|
+
name: 'enquiries_convert_to_deal',
|
|
52
|
+
description:
|
|
53
|
+
'Convert an enquiry to a Deal. Copies name, company, owner and linked ' +
|
|
54
|
+
'people to a new deal in the first open deal stage, moves the enquiry ' +
|
|
55
|
+
'to its first closed stage, and records the link on the enquiry. 409 if ' +
|
|
56
|
+
'the enquiry has already been converted; 422 if it has no company. ' +
|
|
57
|
+
'Mirrors POST /v1/enquiries/{id}/convert.',
|
|
58
|
+
inputSchema: z.strictObject({ id: idArg }),
|
|
59
|
+
invoke: async ({ id }, actor) => {
|
|
60
|
+
const { deal, personIds } = await service.convertToDeal(actor, id)
|
|
61
|
+
const { workspaceId: _workspaceId, ...dealView } = deal
|
|
62
|
+
|
|
63
|
+
return dealResponse({ ...dealView, personIds })
|
|
64
|
+
},
|
|
65
|
+
})
|
|
66
|
+
}
|
|
@@ -24,7 +24,10 @@ import './companies/events.ts'
|
|
|
24
24
|
import './positions/events.ts'
|
|
25
25
|
import './notes/events.ts'
|
|
26
26
|
import './lists/events.ts'
|
|
27
|
+
import './consent-purposes/events.ts'
|
|
28
|
+
import './custom-fields/events.ts'
|
|
27
29
|
import './deals/events.ts'
|
|
30
|
+
import './enquiries/events.ts'
|
|
28
31
|
import './opportunities/events.ts'
|
|
29
32
|
import './partnerships/events.ts'
|
|
30
33
|
import './raises/events.ts'
|
|
@@ -7,6 +7,11 @@ import type { FormFieldRecord, FormRecord } from './repository.ts'
|
|
|
7
7
|
* frames a page from the Kelpie origin, and that page must not drag the CRM's
|
|
8
8
|
* React bundle into somebody else's marketing site to draw five inputs.
|
|
9
9
|
*
|
|
10
|
+
* The hosted layout carries Kelpie's look. The iframe layout is intentionally
|
|
11
|
+
* unbranded (system font, Field colours) so it does not paint Kelpie onto the
|
|
12
|
+
* host site — an iframe cannot inherit the host's CSS, so staying neutral is
|
|
13
|
+
* the alternative.
|
|
14
|
+
*
|
|
10
15
|
* Everything here is pure: a form, its fields, and a URL in; a string out. That
|
|
11
16
|
* is what makes the escaping testable, which for a page built by string
|
|
12
17
|
* concatenation is the part worth testing.
|
|
@@ -74,9 +79,56 @@ function renderControl(field: FormFieldRecord): string {
|
|
|
74
79
|
return `<input ${shared} type="${field.type === 'email' ? 'email' : 'text'}">`
|
|
75
80
|
}
|
|
76
81
|
|
|
77
|
-
function renderField(
|
|
82
|
+
function renderField(
|
|
83
|
+
field: FormFieldRecord,
|
|
84
|
+
consentPurposeLabels: ReadonlyMap<string, string>,
|
|
85
|
+
): string {
|
|
78
86
|
const required = field.required ? '<span class="req" aria-hidden="true">*</span>' : ''
|
|
79
87
|
|
|
88
|
+
if (field.type === 'notice') {
|
|
89
|
+
// Text-only: prose the visitor reads before submitting. Submission is the
|
|
90
|
+
// consent (see readConsentGrants), so no input is rendered. `label` is
|
|
91
|
+
// the heading; `statement` is the prose.
|
|
92
|
+
const statement = field.statement ?? ''
|
|
93
|
+
return [
|
|
94
|
+
'<div class="field notice">',
|
|
95
|
+
`<div class="field-label">${escapeHtml(field.label)}</div>`,
|
|
96
|
+
`<p class="notice-body">${escapeHtml(statement)}</p>`,
|
|
97
|
+
'</div>',
|
|
98
|
+
].join('')
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
if (field.type === 'consent') {
|
|
102
|
+
// Layout: the field label above (heading, e.g. "Consent"), the intro
|
|
103
|
+
// statement, then one checkbox per configured purpose. The submit reads
|
|
104
|
+
// the ticked checkboxes' values (purpose ids) from EMBED_SCRIPT and
|
|
105
|
+
// sends them as a comma-separated string under the field id.
|
|
106
|
+
const statement = field.statement ?? field.label
|
|
107
|
+
const rows = field.consentPurposeIds
|
|
108
|
+
.map((purposeId, index) => {
|
|
109
|
+
const boxId = `${field.id}__${String(index)}`
|
|
110
|
+
// Field-level override wins over the workspace's default label. Falls
|
|
111
|
+
// back to the workspace label, then the raw id — the id only shows up
|
|
112
|
+
// when a purpose has been deleted and its label was never overridden.
|
|
113
|
+
const override = field.consentPurposeLabels[purposeId]
|
|
114
|
+
const label = override ?? consentPurposeLabels.get(purposeId) ?? purposeId
|
|
115
|
+
return [
|
|
116
|
+
'<div class="consent-row">',
|
|
117
|
+
`<input type="checkbox" id="${escapeHtml(boxId)}" data-consent-field="${escapeHtml(field.id)}" value="${escapeHtml(purposeId)}">`,
|
|
118
|
+
`<label for="${escapeHtml(boxId)}">${escapeHtml(label)}</label>`,
|
|
119
|
+
'</div>',
|
|
120
|
+
].join('')
|
|
121
|
+
})
|
|
122
|
+
.join('')
|
|
123
|
+
return [
|
|
124
|
+
'<div class="field consent">',
|
|
125
|
+
`<div class="field-label">${escapeHtml(field.label)}${required}</div>`,
|
|
126
|
+
`<p class="consent-statement">${escapeHtml(statement)}</p>`,
|
|
127
|
+
rows,
|
|
128
|
+
'</div>',
|
|
129
|
+
].join('')
|
|
130
|
+
}
|
|
131
|
+
|
|
80
132
|
return [
|
|
81
133
|
'<div class="field">',
|
|
82
134
|
`<label for="${escapeHtml(field.id)}">${escapeHtml(field.label)}${required}</label>`,
|
|
@@ -86,26 +138,247 @@ function renderField(field: FormFieldRecord): string {
|
|
|
86
138
|
}
|
|
87
139
|
|
|
88
140
|
/**
|
|
89
|
-
* Styles for the page
|
|
90
|
-
* somebody else's design, and a form that tries to bring its own brand fights
|
|
91
|
-
* the site it was embedded in.
|
|
141
|
+
* Styles for the standalone hosted page — Kelpie tokens, brand chrome, card.
|
|
92
142
|
*/
|
|
93
|
-
const
|
|
94
|
-
:root {
|
|
143
|
+
const HOSTED_STYLES = `
|
|
144
|
+
:root {
|
|
145
|
+
color-scheme: light;
|
|
146
|
+
--surface: #fafafa;
|
|
147
|
+
--surface-raised: #ffffff;
|
|
148
|
+
--ink: #18181b;
|
|
149
|
+
--ink-muted: #52525b;
|
|
150
|
+
--ink-faint: #71717a;
|
|
151
|
+
--border: #e4e4e7;
|
|
152
|
+
--accent: #0f766e;
|
|
153
|
+
--accent-hover: #0d9488;
|
|
154
|
+
--accent-soft: #f0fdfa;
|
|
155
|
+
--accent-fg: #ffffff;
|
|
156
|
+
--danger: #dc2626;
|
|
157
|
+
--font: "IBM Plex Sans", ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
|
|
158
|
+
}
|
|
159
|
+
@media (prefers-color-scheme: dark) {
|
|
160
|
+
:root {
|
|
161
|
+
color-scheme: dark;
|
|
162
|
+
--surface: #0c0c0d;
|
|
163
|
+
--surface-raised: #141416;
|
|
164
|
+
--ink: #fafafa;
|
|
165
|
+
--ink-muted: #a1a1aa;
|
|
166
|
+
--ink-faint: #71717a;
|
|
167
|
+
--border: #27272a;
|
|
168
|
+
--accent: #2dd4bf;
|
|
169
|
+
--accent-hover: #5eead4;
|
|
170
|
+
--accent-soft: #134e4a;
|
|
171
|
+
--accent-fg: #042f2e;
|
|
172
|
+
--danger: #f87171;
|
|
173
|
+
}
|
|
174
|
+
}
|
|
95
175
|
* { box-sizing: border-box; }
|
|
96
|
-
|
|
97
|
-
|
|
176
|
+
html { background: var(--surface); }
|
|
177
|
+
body {
|
|
178
|
+
margin: 0;
|
|
179
|
+
min-height: 100vh;
|
|
180
|
+
font: 14px/1.5 var(--font);
|
|
181
|
+
color: var(--ink);
|
|
182
|
+
-webkit-font-smoothing: antialiased;
|
|
183
|
+
background:
|
|
184
|
+
radial-gradient(ellipse at top, color-mix(in srgb, var(--accent-soft) 85%, transparent), transparent 55%),
|
|
185
|
+
var(--surface);
|
|
186
|
+
}
|
|
187
|
+
.shell {
|
|
188
|
+
width: 100%;
|
|
189
|
+
max-width: 28rem;
|
|
190
|
+
margin: 0 auto;
|
|
191
|
+
padding: 2.5rem 1rem 3rem;
|
|
192
|
+
}
|
|
193
|
+
.brand { text-align: center; margin-bottom: 1.5rem; }
|
|
194
|
+
.eyebrow {
|
|
195
|
+
font-size: 11px;
|
|
196
|
+
font-weight: 600;
|
|
197
|
+
letter-spacing: 0.06em;
|
|
198
|
+
text-transform: uppercase;
|
|
199
|
+
color: var(--accent);
|
|
200
|
+
}
|
|
201
|
+
.brand h1 {
|
|
202
|
+
margin: 0.25rem 0 0;
|
|
203
|
+
font-size: 1.375rem;
|
|
204
|
+
font-weight: 600;
|
|
205
|
+
letter-spacing: -0.02em;
|
|
206
|
+
line-height: 1.25;
|
|
207
|
+
color: var(--ink);
|
|
208
|
+
}
|
|
209
|
+
.lead {
|
|
210
|
+
margin: 0.35rem 0 0;
|
|
211
|
+
font-size: 13px;
|
|
212
|
+
color: var(--ink-muted);
|
|
213
|
+
}
|
|
214
|
+
.card {
|
|
215
|
+
border: 1px solid var(--border);
|
|
216
|
+
border-radius: 8px;
|
|
217
|
+
background: var(--surface-raised);
|
|
218
|
+
padding: 1.5rem;
|
|
219
|
+
}
|
|
220
|
+
form { display: grid; gap: 1rem; margin: 0; }
|
|
221
|
+
.field { display: grid; gap: 0.35rem; }
|
|
222
|
+
label { font-weight: 500; font-size: 12px; color: var(--ink); }
|
|
223
|
+
.req { color: var(--danger); margin-left: 2px; }
|
|
224
|
+
input, textarea, select {
|
|
225
|
+
width: 100%;
|
|
226
|
+
padding: 0.5rem 0.75rem;
|
|
227
|
+
border: 1px solid var(--border);
|
|
228
|
+
border-radius: 6px;
|
|
229
|
+
font: inherit;
|
|
230
|
+
font-size: 14px;
|
|
231
|
+
color: var(--ink);
|
|
232
|
+
background: var(--surface);
|
|
233
|
+
outline: none;
|
|
234
|
+
transition: border-color 120ms ease, box-shadow 120ms ease;
|
|
235
|
+
}
|
|
236
|
+
input::placeholder, textarea::placeholder { color: var(--ink-faint); }
|
|
237
|
+
input:focus-visible, textarea:focus-visible, select:focus-visible {
|
|
238
|
+
border-color: var(--accent);
|
|
239
|
+
box-shadow: 0 0 0 3px color-mix(in srgb, var(--accent) 20%, transparent);
|
|
240
|
+
}
|
|
241
|
+
textarea { resize: vertical; min-height: 6.5rem; }
|
|
242
|
+
/* Consent field: label above (heading), a statement, then a checkbox per purpose. */
|
|
243
|
+
.field.consent { gap: 0.35rem; }
|
|
244
|
+
.field.consent .field-label {
|
|
245
|
+
font-weight: 500;
|
|
246
|
+
font-size: 12px;
|
|
247
|
+
color: var(--ink);
|
|
248
|
+
}
|
|
249
|
+
.field.consent .consent-statement {
|
|
250
|
+
margin: 0 0 0.35rem;
|
|
251
|
+
font-size: 12px;
|
|
252
|
+
color: var(--ink-muted);
|
|
253
|
+
}
|
|
254
|
+
.field.consent .consent-row {
|
|
255
|
+
display: grid;
|
|
256
|
+
grid-template-columns: auto 1fr;
|
|
257
|
+
align-items: start;
|
|
258
|
+
gap: 0.5rem;
|
|
259
|
+
padding: 0.15rem 0;
|
|
260
|
+
}
|
|
261
|
+
.field.consent input[type="checkbox"] {
|
|
262
|
+
width: 1rem;
|
|
263
|
+
height: 1rem;
|
|
264
|
+
margin-top: 0.2rem;
|
|
265
|
+
padding: 0;
|
|
266
|
+
background: var(--surface);
|
|
267
|
+
}
|
|
268
|
+
.field.consent .consent-row label {
|
|
269
|
+
font-weight: 400;
|
|
270
|
+
color: var(--ink);
|
|
271
|
+
}
|
|
272
|
+
.field.notice { gap: 0.35rem; }
|
|
273
|
+
.field.notice .field-label {
|
|
274
|
+
font-weight: 500;
|
|
275
|
+
font-size: 12px;
|
|
276
|
+
color: var(--ink);
|
|
277
|
+
}
|
|
278
|
+
.field.notice .notice-body {
|
|
279
|
+
margin: 0;
|
|
280
|
+
padding: 0.5rem 0.75rem;
|
|
281
|
+
font-size: 12px;
|
|
282
|
+
color: var(--ink-muted);
|
|
283
|
+
background: var(--surface);
|
|
284
|
+
border: 1px solid var(--border);
|
|
285
|
+
border-radius: 6px;
|
|
286
|
+
white-space: pre-line;
|
|
287
|
+
}
|
|
288
|
+
button[type="submit"] {
|
|
289
|
+
width: 100%;
|
|
290
|
+
padding: 0.625rem 0.875rem;
|
|
291
|
+
border: 0;
|
|
292
|
+
border-radius: 6px;
|
|
293
|
+
background: var(--accent);
|
|
294
|
+
color: var(--accent-fg);
|
|
295
|
+
font: inherit;
|
|
296
|
+
font-size: 13px;
|
|
297
|
+
font-weight: 600;
|
|
298
|
+
cursor: pointer;
|
|
299
|
+
transition: background 120ms ease;
|
|
300
|
+
}
|
|
301
|
+
button[type="submit"]:hover:not([disabled]) { background: var(--accent-hover); }
|
|
302
|
+
button[type="submit"][disabled] { opacity: 0.55; cursor: progress; }
|
|
303
|
+
.note { margin: 0; font-size: 12px; color: var(--ink-muted); }
|
|
304
|
+
.error { color: var(--danger); font-weight: 500; }
|
|
305
|
+
.done {
|
|
306
|
+
margin: 0;
|
|
307
|
+
text-align: center;
|
|
308
|
+
font-size: 15px;
|
|
309
|
+
font-weight: 500;
|
|
310
|
+
line-height: 1.45;
|
|
311
|
+
color: var(--ink);
|
|
312
|
+
}
|
|
313
|
+
.paused {
|
|
314
|
+
margin: 0;
|
|
315
|
+
font-size: 13px;
|
|
316
|
+
color: var(--ink-muted);
|
|
317
|
+
text-align: center;
|
|
318
|
+
}
|
|
319
|
+
`
|
|
320
|
+
|
|
321
|
+
/**
|
|
322
|
+
* Styles for the iframe document.
|
|
323
|
+
*
|
|
324
|
+
* Deliberately not Kelpie: system font, browser field colours, a plain button.
|
|
325
|
+
* An iframe cannot pick up the host page's CSS, so the only way not to fight
|
|
326
|
+
* the host is to stay neutral and leave the background transparent.
|
|
327
|
+
*/
|
|
328
|
+
const IFRAME_STYLES = `
|
|
329
|
+
* { box-sizing: border-box; }
|
|
330
|
+
html, body { background: transparent; }
|
|
331
|
+
body {
|
|
332
|
+
margin: 0;
|
|
333
|
+
padding: 12px;
|
|
334
|
+
font: 15px/1.5 system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
|
|
335
|
+
color: CanvasText;
|
|
336
|
+
-webkit-font-smoothing: antialiased;
|
|
337
|
+
}
|
|
338
|
+
.shell { margin: 0; padding: 0; }
|
|
339
|
+
form { display: grid; gap: 14px; margin: 0; }
|
|
98
340
|
.field { display: grid; gap: 5px; }
|
|
99
341
|
label { font-weight: 600; font-size: 0.875rem; }
|
|
100
342
|
.req { color: #b4232c; margin-left: 2px; }
|
|
101
|
-
input, textarea, select {
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
343
|
+
input, textarea, select {
|
|
344
|
+
width: 100%;
|
|
345
|
+
padding: 9px 10px;
|
|
346
|
+
border: 1px solid #b9bfc9;
|
|
347
|
+
border-radius: 6px;
|
|
348
|
+
font: inherit;
|
|
349
|
+
background: Field;
|
|
350
|
+
color: FieldText;
|
|
351
|
+
}
|
|
352
|
+
input:focus-visible, textarea:focus-visible, select:focus-visible {
|
|
353
|
+
outline: 2px solid #2f6feb;
|
|
354
|
+
outline-offset: 1px;
|
|
355
|
+
}
|
|
356
|
+
textarea { resize: vertical; min-height: 6rem; }
|
|
357
|
+
.field.consent { gap: 5px; }
|
|
358
|
+
.field.consent .field-label { font-weight: 600; font-size: 0.875rem; color: CanvasText; }
|
|
359
|
+
.field.consent .consent-statement { margin: 0 0 5px; font-size: 0.8125rem; color: #5c6570; }
|
|
360
|
+
.field.consent .consent-row { display: grid; grid-template-columns: auto 1fr; align-items: start; gap: 8px; padding: 2px 0; }
|
|
361
|
+
.field.consent input[type="checkbox"] { width: 1rem; height: 1rem; margin-top: 3px; padding: 0; background: Field; }
|
|
362
|
+
.field.consent .consent-row label { font-weight: 400; }
|
|
363
|
+
.field.notice { gap: 5px; }
|
|
364
|
+
.field.notice .field-label { font-weight: 600; font-size: 0.875rem; color: CanvasText; }
|
|
365
|
+
.field.notice .notice-body { margin: 0; padding: 9px 10px; font-size: 0.8125rem; color: CanvasText; background: Field; border: 1px solid #b9bfc9; border-radius: 6px; white-space: pre-line; }
|
|
366
|
+
button[type="submit"] {
|
|
367
|
+
width: 100%;
|
|
368
|
+
padding: 10px 16px;
|
|
369
|
+
border: 0;
|
|
370
|
+
border-radius: 6px;
|
|
371
|
+
background: #2f6feb;
|
|
372
|
+
color: #fff;
|
|
373
|
+
font: inherit;
|
|
374
|
+
font-weight: 600;
|
|
375
|
+
cursor: pointer;
|
|
376
|
+
}
|
|
377
|
+
button[type="submit"][disabled] { opacity: 0.6; cursor: progress; }
|
|
378
|
+
.note { margin: 0; font-size: 0.875rem; color: #5c6570; }
|
|
379
|
+
.error { color: #b4232c; font-weight: 500; }
|
|
380
|
+
.done { margin: 0; font-size: 15px; font-weight: 500; line-height: 1.45; }
|
|
381
|
+
.paused { margin: 0; font-size: 13px; color: #5c6570; }
|
|
109
382
|
`
|
|
110
383
|
|
|
111
384
|
/**
|
|
@@ -136,8 +409,28 @@ const EMBED_SCRIPT = `
|
|
|
136
409
|
button.disabled = true;
|
|
137
410
|
|
|
138
411
|
var answers = {};
|
|
412
|
+
// Consent fields render a checkbox per purpose, each tagged with
|
|
413
|
+
// data-consent-field=<field_id> and value=<purpose_id>. Collect the
|
|
414
|
+
// ticked ones into a comma-separated list under the field id — the
|
|
415
|
+
// server parses that back into a set of ticked purpose ids.
|
|
416
|
+
var consentBoxes = form.querySelectorAll('input[type="checkbox"][data-consent-field]');
|
|
417
|
+
var consentByField = {};
|
|
418
|
+
for (var i = 0; i < consentBoxes.length; i += 1) {
|
|
419
|
+
var box = consentBoxes[i];
|
|
420
|
+
var fieldId = box.getAttribute('data-consent-field');
|
|
421
|
+
if (!consentByField[fieldId]) { consentByField[fieldId] = []; }
|
|
422
|
+
if (box.checked) { consentByField[fieldId].push(box.value); }
|
|
423
|
+
}
|
|
424
|
+
for (var fieldId in consentByField) {
|
|
425
|
+
if (consentByField[fieldId].length > 0) {
|
|
426
|
+
answers[fieldId] = consentByField[fieldId].join(',');
|
|
427
|
+
}
|
|
428
|
+
}
|
|
139
429
|
config.fieldIds.forEach(function (id) {
|
|
140
|
-
|
|
430
|
+
if (consentByField[id] !== undefined) { return; }
|
|
431
|
+
var element = form.elements[id];
|
|
432
|
+
if (!element) { return; }
|
|
433
|
+
var value = element.value.trim();
|
|
141
434
|
if (value) { answers[id] = value; }
|
|
142
435
|
});
|
|
143
436
|
|
|
@@ -166,13 +459,56 @@ const EMBED_SCRIPT = `
|
|
|
166
459
|
})();
|
|
167
460
|
`
|
|
168
461
|
|
|
462
|
+
export type EmbedLayout = 'page' | 'embed'
|
|
463
|
+
|
|
169
464
|
export interface EmbedPageOptions {
|
|
170
465
|
readonly form: FormRecord
|
|
171
466
|
readonly fields: readonly FormFieldRecord[]
|
|
467
|
+
/** Labels for the consent purposes the fields refer to, keyed by purpose id. */
|
|
468
|
+
readonly consentPurposeLabels: ReadonlyMap<string, string>
|
|
172
469
|
/** Absolute URL of the public submit endpoint this page posts to. */
|
|
173
470
|
readonly submitUrl: string
|
|
174
471
|
/** Per-response value tying the inline style and script to the CSP header. */
|
|
175
472
|
readonly nonce: string
|
|
473
|
+
/** Workspace name shown above the form title on the hosted page layout. */
|
|
474
|
+
readonly workspaceName: string
|
|
475
|
+
/**
|
|
476
|
+
* `page` is the standalone hosted URL (brand chrome). `embed` is the iframe
|
|
477
|
+
* document: fields only, no page design around them.
|
|
478
|
+
*/
|
|
479
|
+
readonly layout: EmbedLayout
|
|
480
|
+
}
|
|
481
|
+
|
|
482
|
+
/**
|
|
483
|
+
* Public heading for the hosted page: the form's `title`, falling back to
|
|
484
|
+
* `name` if somehow blank (legacy rows, a cleared field).
|
|
485
|
+
*/
|
|
486
|
+
function displayTitle(form: FormRecord): string {
|
|
487
|
+
const title = form.title.trim()
|
|
488
|
+
|
|
489
|
+
return title.length > 0 ? title : form.name
|
|
490
|
+
}
|
|
491
|
+
|
|
492
|
+
function renderFormBody(
|
|
493
|
+
form: FormRecord,
|
|
494
|
+
fields: readonly FormFieldRecord[],
|
|
495
|
+
consentPurposeLabels: ReadonlyMap<string, string>,
|
|
496
|
+
config: string,
|
|
497
|
+
nonce: string,
|
|
498
|
+
): string {
|
|
499
|
+
if (form.status === 'paused') {
|
|
500
|
+
return `<p class="paused">This form is not accepting submissions right now.</p>`
|
|
501
|
+
}
|
|
502
|
+
|
|
503
|
+
return [
|
|
504
|
+
'<form id="kelpie-form" novalidate>',
|
|
505
|
+
fields.map((field) => renderField(field, consentPurposeLabels)).join(''),
|
|
506
|
+
'<div><button id="kelpie-submit" type="submit">Submit</button></div>',
|
|
507
|
+
'<p id="kelpie-status" class="note" role="status" aria-live="polite"></p>',
|
|
508
|
+
'</form>',
|
|
509
|
+
`<script type="application/json" id="kelpie-config">${config}</script>`,
|
|
510
|
+
`<script nonce="${escapeHtml(nonce)}">${EMBED_SCRIPT}</script>`,
|
|
511
|
+
].join('')
|
|
176
512
|
}
|
|
177
513
|
|
|
178
514
|
/**
|
|
@@ -183,39 +519,46 @@ export interface EmbedPageOptions {
|
|
|
183
519
|
* form whose submit answers 409.
|
|
184
520
|
*/
|
|
185
521
|
export function renderEmbedPage(options: EmbedPageOptions): string {
|
|
186
|
-
const { form, fields, submitUrl, nonce } = options
|
|
522
|
+
const { form, fields, consentPurposeLabels, submitUrl, nonce, workspaceName, layout } = options
|
|
523
|
+
const heading = displayTitle(form)
|
|
187
524
|
const config = escapeScriptJson({
|
|
188
525
|
formId: form.id,
|
|
189
526
|
submitUrl,
|
|
190
527
|
thankYou: form.thankYouMessage,
|
|
191
528
|
fieldIds: fields.map((field) => field.id),
|
|
192
529
|
})
|
|
193
|
-
const
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
'<div
|
|
200
|
-
'<
|
|
201
|
-
|
|
202
|
-
`<
|
|
203
|
-
|
|
530
|
+
const formBody = renderFormBody(form, fields, consentPurposeLabels, config, nonce)
|
|
531
|
+
|
|
532
|
+
const styles = layout === 'page' ? HOSTED_STYLES : IFRAME_STYLES
|
|
533
|
+
const shell =
|
|
534
|
+
layout === 'page'
|
|
535
|
+
? [
|
|
536
|
+
'<div class="shell">',
|
|
537
|
+
'<header class="brand">',
|
|
538
|
+
`<div class="eyebrow">${escapeHtml(workspaceName)}</div>`,
|
|
539
|
+
`<h1>${escapeHtml(heading)}</h1>`,
|
|
540
|
+
form.description === null || form.description.trim().length === 0
|
|
541
|
+
? ''
|
|
542
|
+
: `<p class="lead">${escapeHtml(form.description)}</p>`,
|
|
543
|
+
'</header>',
|
|
544
|
+
`<div class="card">${formBody}</div>`,
|
|
545
|
+
'</div>',
|
|
204
546
|
].join('')
|
|
547
|
+
: `<div class="shell">${formBody}</div>`
|
|
205
548
|
|
|
206
549
|
return [
|
|
207
550
|
'<!doctype html>',
|
|
208
|
-
|
|
551
|
+
`<html lang="en" class="layout-${layout}">`,
|
|
209
552
|
'<head>',
|
|
210
553
|
'<meta charset="utf-8">',
|
|
211
554
|
'<meta name="viewport" content="width=device-width, initial-scale=1">',
|
|
212
555
|
// Not indexed: the canonical page for this form is the customer's own, and
|
|
213
556
|
// a bare embed ranking above it would be a worse result for a reader.
|
|
214
557
|
'<meta name="robots" content="noindex">',
|
|
215
|
-
`<title>${escapeHtml(
|
|
216
|
-
`<style nonce="${escapeHtml(nonce)}">${
|
|
558
|
+
`<title>${escapeHtml(heading)}</title>`,
|
|
559
|
+
`<style nonce="${escapeHtml(nonce)}">${styles}</style>`,
|
|
217
560
|
'</head>',
|
|
218
|
-
`<body>${
|
|
561
|
+
`<body class="layout-${layout}">${shell}</body>`,
|
|
219
562
|
'</html>',
|
|
220
563
|
].join('')
|
|
221
564
|
}
|
|
@@ -239,28 +582,32 @@ export function embedContentSecurityPolicy(nonce: string): string {
|
|
|
239
582
|
].join('; ')
|
|
240
583
|
}
|
|
241
584
|
|
|
242
|
-
/** What a customer pastes into their site
|
|
585
|
+
/** What a customer pastes into their site, plus the standalone hosted URL. */
|
|
243
586
|
export interface EmbedSnippets {
|
|
587
|
+
/** Standalone hosted page (brand chrome). */
|
|
244
588
|
readonly url: string
|
|
589
|
+
/** Bare document the iframe snippets load (fields only). */
|
|
590
|
+
readonly embedUrl: string
|
|
245
591
|
readonly iframe: string
|
|
246
592
|
readonly script: string
|
|
247
593
|
}
|
|
248
594
|
|
|
249
595
|
/**
|
|
250
|
-
* The two ways to embed.
|
|
596
|
+
* The two ways to embed, plus the hosted page URL.
|
|
251
597
|
*
|
|
252
|
-
*
|
|
253
|
-
*
|
|
254
|
-
*
|
|
598
|
+
* Hosted `url` is the full page. The iframe snippets point at `embedUrl`, which
|
|
599
|
+
* is the same form without page chrome — what belongs inside somebody else's
|
|
600
|
+
* site. The plain iframe is fixed height; the script listens for height
|
|
601
|
+
* messages as fields appear and as the thank-you replaces the form.
|
|
255
602
|
*/
|
|
256
|
-
export function embedSnippets(
|
|
603
|
+
export function embedSnippets(hostedUrl: string, embedUrl: string, formId: string): EmbedSnippets {
|
|
257
604
|
const iframe =
|
|
258
|
-
`<iframe src="${escapeHtml(
|
|
259
|
-
`style="width:100%;border:0;height:
|
|
605
|
+
`<iframe src="${escapeHtml(embedUrl)}" title="Contact form" ` +
|
|
606
|
+
`style="width:100%;border:0;height:720px" loading="lazy"></iframe>`
|
|
260
607
|
|
|
261
608
|
const script = [
|
|
262
|
-
`<iframe id="kelpie-${formId}" src="${escapeHtml(
|
|
263
|
-
` style="width:100%;border:0;height:
|
|
609
|
+
`<iframe id="kelpie-${formId}" src="${escapeHtml(embedUrl)}" title="Contact form"`,
|
|
610
|
+
` style="width:100%;border:0;height:720px" loading="lazy"></iframe>`,
|
|
264
611
|
`<script>`,
|
|
265
612
|
` window.addEventListener('message', function (event) {`,
|
|
266
613
|
` if (event.data && event.data.kelpie === 'height' && event.data.formId === '${formId}') {`,
|
|
@@ -270,5 +617,5 @@ export function embedSnippets(url: string, formId: string): EmbedSnippets {
|
|
|
270
617
|
`</script>`,
|
|
271
618
|
].join('\n')
|
|
272
619
|
|
|
273
|
-
return { url, iframe, script }
|
|
620
|
+
return { url: hostedUrl, embedUrl, iframe, script }
|
|
274
621
|
}
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import { FORM_ACTION_STATUSES } from '@kelpie/schemas'
|
|
2
|
+
import type { FormActionStatus } from '@kelpie/schemas'
|
|
1
3
|
import { z } from 'zod'
|
|
2
4
|
|
|
3
5
|
import type { ModuleEventCatalog } from '../../runtime/module.ts'
|
|
@@ -7,14 +9,32 @@ import type { ModuleEventCatalog } from '../../runtime/module.ts'
|
|
|
7
9
|
*
|
|
8
10
|
* `forms.form.*` cover the form definition CRUD. `forms.submission.submitted`
|
|
9
11
|
* fires once per submission; the webhooks bridge translates it to the wire
|
|
10
|
-
* `form.submitted` event (the ids live in `data`).
|
|
12
|
+
* `form.submitted` event (the ids and per-action statuses live in `data`).
|
|
13
|
+
*
|
|
14
|
+
* The action summary carries statuses only, no detail strings: the webhook
|
|
15
|
+
* receiver learns whether each action ran; the authenticated Submissions
|
|
16
|
+
* reader gets the full detail from `action_log` on the row.
|
|
11
17
|
*/
|
|
12
18
|
|
|
19
|
+
const actionSummarySchema = z
|
|
20
|
+
.object({
|
|
21
|
+
action: z.string(),
|
|
22
|
+
status: z.enum(FORM_ACTION_STATUSES),
|
|
23
|
+
})
|
|
24
|
+
.readonly()
|
|
25
|
+
|
|
13
26
|
export const formsEvents = {
|
|
14
27
|
'forms.form.created': z.object({}).strict(),
|
|
15
28
|
'forms.form.updated': z.object({ changed: z.array(z.string()).readonly() }),
|
|
16
29
|
'forms.form.deleted': z.object({}).strict(),
|
|
17
|
-
'forms.submission.submitted': z.object({
|
|
30
|
+
'forms.submission.submitted': z.object({
|
|
31
|
+
formId: z.string(),
|
|
32
|
+
submissionId: z.string(),
|
|
33
|
+
opportunityId: z.string().nullable(),
|
|
34
|
+
partnershipId: z.string().nullable(),
|
|
35
|
+
enquiryId: z.string().nullable(),
|
|
36
|
+
actions: z.array(actionSummarySchema).readonly(),
|
|
37
|
+
}),
|
|
18
38
|
} satisfies ModuleEventCatalog
|
|
19
39
|
|
|
20
40
|
export type FormCreatedData = Record<string, never>
|
|
@@ -22,9 +42,17 @@ export interface FormUpdatedData {
|
|
|
22
42
|
readonly changed: readonly string[]
|
|
23
43
|
}
|
|
24
44
|
export type FormDeletedData = Record<string, never>
|
|
45
|
+
export interface FormSubmissionActionSummary {
|
|
46
|
+
readonly action: string
|
|
47
|
+
readonly status: FormActionStatus
|
|
48
|
+
}
|
|
25
49
|
export interface FormSubmissionData {
|
|
26
50
|
readonly formId: string
|
|
27
51
|
readonly submissionId: string
|
|
52
|
+
readonly opportunityId: string | null
|
|
53
|
+
readonly partnershipId: string | null
|
|
54
|
+
readonly enquiryId: string | null
|
|
55
|
+
readonly actions: readonly FormSubmissionActionSummary[]
|
|
28
56
|
}
|
|
29
57
|
|
|
30
58
|
declare module '../../runtime/events.ts' {
|