@kelpie/server 0.11.0 → 0.13.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/app.d.ts +13 -0
- package/dist/app.d.ts.map +1 -1
- package/dist/app.js +8 -1
- package/dist/app.js.map +1 -1
- package/dist/boot.d.ts.map +1 -1
- package/dist/boot.js +1 -0
- package/dist/boot.js.map +1 -1
- package/dist/index.d.ts +3 -3
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/lib/apiKeyScopes.d.ts.map +1 -1
- package/dist/lib/apiKeyScopes.js +6 -0
- package/dist/lib/apiKeyScopes.js.map +1 -1
- package/dist/lib/columns.d.ts +6 -0
- package/dist/lib/columns.d.ts.map +1 -1
- package/dist/lib/columns.js +5 -3
- package/dist/lib/columns.js.map +1 -1
- package/dist/lib/config.d.ts +17 -0
- package/dist/lib/config.d.ts.map +1 -1
- package/dist/lib/config.js +3 -0
- package/dist/lib/config.js.map +1 -1
- package/dist/lib/egress.d.ts.map +1 -1
- package/dist/lib/egress.js +8 -4
- package/dist/lib/egress.js.map +1 -1
- package/dist/lib/errors.d.ts +18 -0
- package/dist/lib/errors.d.ts.map +1 -1
- package/dist/lib/errors.js +25 -0
- package/dist/lib/errors.js.map +1 -1
- 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/lib/kelpieConfigFile.d.ts +15 -1
- package/dist/lib/kelpieConfigFile.d.ts.map +1 -1
- package/dist/lib/kelpieConfigFile.js +33 -1
- package/dist/lib/kelpieConfigFile.js.map +1 -1
- package/dist/modules/agent-tasks/catalog.d.ts.map +1 -1
- package/dist/modules/agent-tasks/catalog.js +32 -1
- package/dist/modules/agent-tasks/catalog.js.map +1 -1
- package/dist/modules/agent-tasks/index.d.ts.map +1 -1
- package/dist/modules/agent-tasks/index.js +1 -0
- package/dist/modules/agent-tasks/index.js.map +1 -1
- package/dist/modules/agent-tasks/resolve.d.ts.map +1 -1
- package/dist/modules/agent-tasks/resolve.js +5 -0
- 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 +22 -8
- package/dist/modules/attachedRecords.d.ts.map +1 -1
- package/dist/modules/attachedRecords.js +42 -5
- package/dist/modules/attachedRecords.js.map +1 -1
- package/dist/modules/auth/index.d.ts.map +1 -1
- package/dist/modules/auth/index.js +22 -4
- package/dist/modules/auth/index.js.map +1 -1
- package/dist/modules/auth/repository.d.ts +16 -1
- package/dist/modules/auth/repository.d.ts.map +1 -1
- package/dist/modules/auth/repository.js +21 -2
- package/dist/modules/auth/repository.js.map +1 -1
- package/dist/modules/auth/routes.d.ts.map +1 -1
- package/dist/modules/auth/routes.js +32 -6
- package/dist/modules/auth/routes.js.map +1 -1
- package/dist/modules/auth/schema.d.ts +18 -1
- package/dist/modules/auth/schema.d.ts.map +1 -1
- package/dist/modules/auth/schema.js +12 -1
- package/dist/modules/auth/schema.js.map +1 -1
- package/dist/modules/auth/service.d.ts +46 -0
- package/dist/modules/auth/service.d.ts.map +1 -1
- package/dist/modules/auth/service.js +167 -10
- package/dist/modules/auth/service.js.map +1 -1
- package/dist/modules/auth/session.d.ts +12 -0
- package/dist/modules/auth/session.d.ts.map +1 -1
- package/dist/modules/auth/session.js +12 -0
- package/dist/modules/auth/session.js.map +1 -1
- package/dist/modules/companies/repository.d.ts.map +1 -1
- package/dist/modules/companies/repository.js +1 -1
- package/dist/modules/companies/repository.js.map +1 -1
- package/dist/modules/companies/routes.d.ts +2 -4
- package/dist/modules/companies/routes.d.ts.map +1 -1
- package/dist/modules/companies/routes.js +6 -11
- package/dist/modules/companies/routes.js.map +1 -1
- package/dist/modules/companies/schema.d.ts +13 -28
- package/dist/modules/companies/schema.d.ts.map +1 -1
- package/dist/modules/companies/schema.js +2 -2
- package/dist/modules/companies/schema.js.map +1 -1
- package/dist/modules/companies/service.d.ts +2 -3
- package/dist/modules/companies/service.d.ts.map +1 -1
- package/dist/modules/companies/service.js +4 -7
- package/dist/modules/companies/service.js.map +1 -1
- package/dist/modules/core.d.ts.map +1 -1
- package/dist/modules/core.js +2 -0
- package/dist/modules/core.js.map +1 -1
- package/dist/modules/custom-fields/repository.d.ts.map +1 -1
- package/dist/modules/custom-fields/repository.js +2 -0
- package/dist/modules/custom-fields/repository.js.map +1 -1
- package/dist/modules/custom-fields/routes.d.ts +1 -0
- package/dist/modules/custom-fields/routes.d.ts.map +1 -1
- package/dist/modules/dashboard/index.d.ts.map +1 -1
- package/dist/modules/dashboard/index.js +1 -0
- package/dist/modules/dashboard/index.js.map +1 -1
- package/dist/modules/dashboard/repository.d.ts +13 -0
- package/dist/modules/dashboard/repository.d.ts.map +1 -1
- package/dist/modules/dashboard/repository.js +36 -0
- package/dist/modules/dashboard/repository.js.map +1 -1
- package/dist/modules/dashboard/routes.d.ts.map +1 -1
- package/dist/modules/dashboard/routes.js +13 -0
- package/dist/modules/dashboard/routes.js.map +1 -1
- package/dist/modules/dashboard/service.d.ts +11 -0
- package/dist/modules/dashboard/service.d.ts.map +1 -1
- package/dist/modules/dashboard/service.js +24 -1
- package/dist/modules/dashboard/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 +2 -0
- package/dist/modules/decisions/routes.d.ts.map +1 -1
- package/dist/modules/events/attendances.d.ts +35 -0
- package/dist/modules/events/attendances.d.ts.map +1 -0
- package/dist/modules/events/attendances.js +157 -0
- package/dist/modules/events/attendances.js.map +1 -0
- package/dist/modules/events/catalog.d.ts +35 -0
- package/dist/modules/events/catalog.d.ts.map +1 -0
- package/dist/modules/events/catalog.js +11 -0
- package/dist/modules/events/catalog.js.map +1 -0
- package/dist/modules/events/index.d.ts +10 -0
- package/dist/modules/events/index.d.ts.map +1 -0
- package/dist/modules/events/index.js +47 -0
- package/dist/modules/events/index.js.map +1 -0
- package/dist/modules/events/repository.d.ts +67 -0
- package/dist/modules/events/repository.d.ts.map +1 -0
- package/dist/modules/events/repository.js +212 -0
- package/dist/modules/events/repository.js.map +1 -0
- package/dist/modules/events/routes.d.ts +136 -0
- package/dist/modules/events/routes.d.ts.map +1 -0
- package/dist/modules/events/routes.js +280 -0
- package/dist/modules/events/routes.js.map +1 -0
- package/dist/modules/events/schema.d.ts +626 -0
- package/dist/modules/events/schema.d.ts.map +1 -0
- package/dist/modules/events/schema.js +93 -0
- package/dist/modules/events/schema.js.map +1 -0
- package/dist/modules/events/service.d.ts +68 -0
- package/dist/modules/events/service.d.ts.map +1 -0
- package/dist/modules/events/service.js +262 -0
- package/dist/modules/events/service.js.map +1 -0
- package/dist/modules/events/tools.d.ts +8 -0
- package/dist/modules/events/tools.d.ts.map +1 -0
- package/dist/modules/events/tools.js +80 -0
- package/dist/modules/events/tools.js.map +1 -0
- package/dist/modules/forms/applySubmissionFields.d.ts.map +1 -1
- package/dist/modules/forms/applySubmissionFields.js +7 -5
- package/dist/modules/forms/applySubmissionFields.js.map +1 -1
- package/dist/modules/forms/fillAddresses.d.ts +4 -0
- package/dist/modules/forms/fillAddresses.d.ts.map +1 -0
- package/dist/modules/forms/fillAddresses.js +93 -0
- package/dist/modules/forms/fillAddresses.js.map +1 -0
- package/dist/modules/forms/repository.d.ts +2 -2
- package/dist/modules/forms/repository.d.ts.map +1 -1
- package/dist/modules/forms/repository.js.map +1 -1
- package/dist/modules/forms/routes.d.ts +2 -0
- package/dist/modules/forms/routes.d.ts.map +1 -1
- package/dist/modules/forms/routes.js +2 -2
- package/dist/modules/forms/routes.js.map +1 -1
- package/dist/modules/forms/schema.js +2 -2
- package/dist/modules/forms/schema.js.map +1 -1
- package/dist/modules/forms/service.js +2 -2
- package/dist/modules/forms/service.js.map +1 -1
- package/dist/modules/forms/submission.d.ts +1 -0
- package/dist/modules/forms/submission.d.ts.map +1 -1
- package/dist/modules/forms/submission.js +27 -4
- package/dist/modules/forms/submission.js.map +1 -1
- package/dist/modules/hiring/roles.d.ts.map +1 -1
- package/dist/modules/hiring/roles.js +2 -1
- package/dist/modules/hiring/roles.js.map +1 -1
- package/dist/modules/import-export/addresses.d.ts +22 -0
- package/dist/modules/import-export/addresses.d.ts.map +1 -0
- package/dist/modules/import-export/addresses.js +83 -0
- package/dist/modules/import-export/addresses.js.map +1 -0
- package/dist/modules/import-export/drafts.d.ts +3 -4
- package/dist/modules/import-export/drafts.d.ts.map +1 -1
- package/dist/modules/import-export/drafts.js +4 -5
- package/dist/modules/import-export/drafts.js.map +1 -1
- package/dist/modules/import-export/exportRows.d.ts.map +1 -1
- package/dist/modules/import-export/exportRows.js +3 -3
- package/dist/modules/import-export/exportRows.js.map +1 -1
- package/dist/modules/import-export/plan.d.ts.map +1 -1
- package/dist/modules/import-export/plan.js +17 -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 +52 -7
- package/dist/modules/import-export/presets.js.map +1 -1
- package/dist/modules/import-export/repository.d.ts +3 -4
- package/dist/modules/import-export/repository.d.ts.map +1 -1
- package/dist/modules/import-export/repository.js +2 -3
- package/dist/modules/import-export/repository.js.map +1 -1
- package/dist/modules/import-export/writes.d.ts.map +1 -1
- package/dist/modules/import-export/writes.js +8 -4
- package/dist/modules/import-export/writes.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/notes/routes.d.ts +2 -0
- package/dist/modules/notes/routes.d.ts.map +1 -1
- package/dist/modules/people/repository.d.ts.map +1 -1
- package/dist/modules/people/repository.js +1 -1
- package/dist/modules/people/repository.js.map +1 -1
- package/dist/modules/people/routes.d.ts +2 -2
- package/dist/modules/people/routes.js +6 -6
- package/dist/modules/people/routes.js.map +1 -1
- package/dist/modules/people/schema.d.ts +17 -14
- package/dist/modules/people/schema.d.ts.map +1 -1
- package/dist/modules/people/schema.js +6 -4
- package/dist/modules/people/schema.js.map +1 -1
- package/dist/modules/people/service.d.ts +2 -2
- package/dist/modules/people/service.d.ts.map +1 -1
- package/dist/modules/people/service.js +5 -4
- package/dist/modules/people/service.js.map +1 -1
- package/dist/modules/plans/repository.d.ts +2 -2
- package/dist/modules/plans/repository.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/plans/routes.js +4 -4
- package/dist/modules/plans/routes.js.map +1 -1
- package/dist/modules/plans/schema.d.ts +2 -2
- package/dist/modules/plans/schema.d.ts.map +1 -1
- package/dist/modules/plans/schema.js +3 -3
- package/dist/modules/plans/schema.js.map +1 -1
- package/dist/modules/plans/service.d.ts +2 -2
- package/dist/modules/plans/service.d.ts.map +1 -1
- package/dist/modules/plans/service.js.map +1 -1
- package/dist/modules/plans/tools.js +2 -2
- package/dist/modules/plans/tools.js.map +1 -1
- package/dist/modules/recordTargets.d.ts.map +1 -1
- package/dist/modules/recordTargets.js +11 -0
- package/dist/modules/recordTargets.js.map +1 -1
- package/dist/modules/references.d.ts.map +1 -1
- package/dist/modules/references.js +2 -0
- package/dist/modules/references.js.map +1 -1
- package/dist/modules/sample-data/fixture.d.ts +26 -4
- package/dist/modules/sample-data/fixture.d.ts.map +1 -1
- package/dist/modules/sample-data/fixture.js +157 -23
- package/dist/modules/sample-data/fixture.js.map +1 -1
- package/dist/modules/sample-data/index.d.ts +5 -2
- package/dist/modules/sample-data/index.d.ts.map +1 -1
- package/dist/modules/sample-data/index.js +7 -2
- 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 +2 -0
- package/dist/modules/sample-data/routes.js.map +1 -1
- package/dist/modules/sample-data/service.d.ts +11 -3
- package/dist/modules/sample-data/service.d.ts.map +1 -1
- package/dist/modules/sample-data/service.js +452 -363
- package/dist/modules/sample-data/service.js.map +1 -1
- package/dist/modules/sample-data/tools.d.ts.map +1 -1
- package/dist/modules/sample-data/tools.js +4 -3
- package/dist/modules/sample-data/tools.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 +22 -0
- package/dist/modules/search/repository.js.map +1 -1
- package/dist/modules/search/service.d.ts +2 -2
- package/dist/modules/search/service.d.ts.map +1 -1
- package/dist/modules/search/service.js +4 -3
- package/dist/modules/search/service.js.map +1 -1
- package/dist/modules/smtp-email/index.d.ts +12 -4
- package/dist/modules/smtp-email/index.d.ts.map +1 -1
- package/dist/modules/smtp-email/index.js +25 -5
- package/dist/modules/smtp-email/index.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 +12 -0
- package/dist/modules/workspace/repository.js.map +1 -1
- package/dist/modules/workspace/routes.d.ts.map +1 -1
- package/dist/modules/workspace/routes.js +13 -0
- package/dist/modules/workspace/routes.js.map +1 -1
- package/dist/modules/workspace/service.d.ts +10 -0
- package/dist/modules/workspace/service.d.ts.map +1 -1
- package/dist/modules/workspace/service.js +34 -10
- package/dist/modules/workspace/service.js.map +1 -1
- package/dist/modules/workspace/starters.d.ts +17 -2
- package/dist/modules/workspace/starters.d.ts.map +1 -1
- package/dist/modules/workspace/starters.js +141 -14
- package/dist/modules/workspace/starters.js.map +1 -1
- package/dist/modules/workspace/workspaceAccessMiddleware.d.ts.map +1 -1
- package/dist/modules/workspace/workspaceAccessMiddleware.js +3 -4
- package/dist/modules/workspace/workspaceAccessMiddleware.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 +2 -0
- package/dist/runtime/events.js.map +1 -1
- package/dist/runtime/module.d.ts +71 -1
- package/dist/runtime/module.d.ts.map +1 -1
- package/dist/runtime/registry.d.ts.map +1 -1
- package/dist/runtime/registry.js +142 -9
- package/dist/runtime/registry.js.map +1 -1
- package/dist/schema/index.d.ts +1 -0
- package/dist/schema/index.d.ts.map +1 -1
- package/dist/schema/index.js +1 -0
- package/dist/schema/index.js.map +1 -1
- package/dist/testing/app.d.ts +8 -0
- package/dist/testing/app.d.ts.map +1 -1
- package/dist/testing/app.js +6 -1
- package/dist/testing/app.js.map +1 -1
- package/dist/testing/client.d.ts.map +1 -1
- package/dist/testing/client.js +9 -1
- package/dist/testing/client.js.map +1 -1
- package/migrations/0043_external_sign_in.sql +2 -0
- package/migrations/0044_events.sql +79 -0
- package/migrations/0045_addresses.sql +66 -0
- package/migrations/0046_drop_company_website.sql +66 -0
- package/migrations/meta/_journal.json +28 -0
- package/package.json +3 -3
- package/src/app.ts +25 -1
- package/src/boot.ts +1 -0
- package/src/index.ts +13 -1
- package/src/lib/apiKeyScopes.ts +6 -0
- package/src/lib/columns.ts +12 -3
- package/src/lib/config.ts +21 -0
- package/src/lib/egress.ts +8 -4
- package/src/lib/errors.ts +37 -0
- package/src/lib/ids.ts +11 -0
- package/src/lib/kelpieConfigFile.ts +69 -1
- package/src/modules/agent-tasks/catalog.ts +33 -1
- package/src/modules/agent-tasks/index.ts +1 -0
- package/src/modules/agent-tasks/resolve.ts +11 -0
- package/src/modules/attachedRecords.ts +85 -13
- package/src/modules/auth/index.ts +26 -4
- package/src/modules/auth/repository.ts +36 -4
- package/src/modules/auth/routes.ts +46 -9
- package/src/modules/auth/schema.ts +12 -1
- package/src/modules/auth/service.ts +261 -10
- package/src/modules/auth/session.ts +14 -0
- package/src/modules/companies/repository.ts +1 -0
- package/src/modules/companies/routes.ts +6 -11
- package/src/modules/companies/schema.ts +3 -3
- package/src/modules/companies/service.ts +6 -10
- package/src/modules/core.ts +2 -0
- package/src/modules/custom-fields/repository.ts +2 -0
- package/src/modules/dashboard/index.ts +1 -0
- package/src/modules/dashboard/repository.ts +64 -0
- package/src/modules/dashboard/routes.ts +15 -0
- package/src/modules/dashboard/service.ts +48 -0
- package/src/modules/decisions/repository.ts +2 -0
- package/src/modules/events/attendances.ts +245 -0
- package/src/modules/events/catalog.ts +36 -0
- package/src/modules/events/index.ts +54 -0
- package/src/modules/events/repository.ts +396 -0
- package/src/modules/events/routes.ts +405 -0
- package/src/modules/events/schema.ts +148 -0
- package/src/modules/events/service.ts +443 -0
- package/src/modules/events/tools.ts +118 -0
- package/src/modules/forms/applySubmissionFields.ts +7 -5
- package/src/modules/forms/fillAddresses.ts +185 -0
- package/src/modules/forms/repository.ts +3 -3
- package/src/modules/forms/routes.ts +2 -2
- package/src/modules/forms/schema.ts +2 -2
- package/src/modules/forms/service.ts +2 -2
- package/src/modules/forms/submission.ts +34 -4
- package/src/modules/hiring/roles.ts +2 -1
- package/src/modules/import-export/addresses.ts +150 -0
- package/src/modules/import-export/drafts.ts +7 -9
- package/src/modules/import-export/exportRows.ts +3 -3
- package/src/modules/import-export/plan.ts +30 -2
- package/src/modules/import-export/presets.ts +55 -7
- package/src/modules/import-export/repository.ts +5 -7
- package/src/modules/import-export/writes.ts +8 -4
- package/src/modules/people/repository.ts +1 -0
- package/src/modules/people/routes.ts +6 -6
- package/src/modules/people/schema.ts +7 -5
- package/src/modules/people/service.ts +7 -5
- package/src/modules/plans/repository.ts +2 -2
- package/src/modules/plans/routes.ts +6 -6
- package/src/modules/plans/schema.ts +4 -4
- package/src/modules/plans/service.ts +3 -3
- package/src/modules/plans/tools.ts +2 -2
- package/src/modules/recordTargets.ts +14 -0
- package/src/modules/references.ts +2 -0
- package/src/modules/sample-data/fixture.ts +208 -27
- package/src/modules/sample-data/index.ts +7 -2
- package/src/modules/sample-data/routes.ts +2 -0
- package/src/modules/sample-data/service.ts +166 -49
- package/src/modules/sample-data/tools.ts +4 -3
- package/src/modules/search/index.ts +2 -1
- package/src/modules/search/repository.ts +32 -1
- package/src/modules/search/service.ts +6 -4
- package/src/modules/smtp-email/index.ts +32 -10
- package/src/modules/workspace/repository.ts +18 -0
- package/src/modules/workspace/routes.ts +16 -0
- package/src/modules/workspace/service.ts +59 -14
- package/src/modules/workspace/starters.ts +275 -14
- package/src/modules/workspace/workspaceAccessMiddleware.ts +3 -4
- package/src/runtime/events.ts +2 -0
- package/src/runtime/module.ts +78 -1
- package/src/runtime/registry.ts +176 -8
- package/src/schema/index.ts +1 -0
- package/src/testing/app.ts +14 -1
- package/src/testing/client.ts +11 -1
|
@@ -21,10 +21,12 @@ import { seedStarterForms } from './seedStarterForms.ts'
|
|
|
21
21
|
import { parseInvitableRole, parseMemberRole, roleAllows } from './roles.ts'
|
|
22
22
|
import type { InvitableRole, InviteStatus, MemberRole } from './roles.ts'
|
|
23
23
|
import {
|
|
24
|
-
|
|
24
|
+
getHandbookPagesForTemplate,
|
|
25
|
+
isStarterHandbookBody,
|
|
25
26
|
STARTER_PIPELINE_STAGES,
|
|
26
27
|
starterHandbookBody,
|
|
27
28
|
} from './starters.ts'
|
|
29
|
+
import type { HandbookTemplateId } from './starters.ts'
|
|
28
30
|
|
|
29
31
|
/**
|
|
30
32
|
* Workspaces and who belongs to them.
|
|
@@ -89,6 +91,15 @@ export interface CreateWorkspaceInput {
|
|
|
89
91
|
readonly timezone: string
|
|
90
92
|
}
|
|
91
93
|
|
|
94
|
+
export interface SeedHandbookInput {
|
|
95
|
+
readonly handbookTemplate: HandbookTemplateId
|
|
96
|
+
readonly replace?: boolean | undefined
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
export interface SeedHandbookResult {
|
|
100
|
+
readonly handbookPages: number
|
|
101
|
+
}
|
|
102
|
+
|
|
92
103
|
/**
|
|
93
104
|
* A partial update, on `api.md`'s rule: an absent field is not being changed,
|
|
94
105
|
* and `null` clears one.
|
|
@@ -108,6 +119,8 @@ export interface UpdateWorkspaceInput {
|
|
|
108
119
|
export interface WorkspaceService {
|
|
109
120
|
/** Creates the workspace, makes the caller its owner, and seeds its starters. */
|
|
110
121
|
create(actor: SessionActor, input: CreateWorkspaceInput): Promise<WorkspaceView>
|
|
122
|
+
/** Seeds starter handbook pages for the chosen organisation template. */
|
|
123
|
+
seedHandbook(actor: Actor, workspaceId: string, input: SeedHandbookInput): Promise<SeedHandbookResult>
|
|
111
124
|
get(actor: Actor, workspaceId: string): Promise<WorkspaceView>
|
|
112
125
|
update(actor: Actor, workspaceId: string, changes: UpdateWorkspaceInput): Promise<WorkspaceView>
|
|
113
126
|
/**
|
|
@@ -439,19 +452,6 @@ export function createWorkspaceService(dependencies: WorkspaceDependencies): Wor
|
|
|
439
452
|
joinedAt: now,
|
|
440
453
|
})
|
|
441
454
|
|
|
442
|
-
await repository.insertHandbookPages(
|
|
443
|
-
tx,
|
|
444
|
-
STARTER_HANDBOOK_PAGES.map((page, index) => ({
|
|
445
|
-
id: dependencies.createId('handbookPage'),
|
|
446
|
-
workspaceId,
|
|
447
|
-
title: page.title,
|
|
448
|
-
slug: page.slug,
|
|
449
|
-
sortOrder: index,
|
|
450
|
-
body: starterHandbookBody(page.title),
|
|
451
|
-
updatedBy: memberId,
|
|
452
|
-
})),
|
|
453
|
-
)
|
|
454
|
-
|
|
455
455
|
await repository.insertPipelineStages(
|
|
456
456
|
tx,
|
|
457
457
|
Object.entries(STARTER_PIPELINE_STAGES).flatMap(([kind, stages]) =>
|
|
@@ -511,6 +511,51 @@ export function createWorkspaceService(dependencies: WorkspaceDependencies): Wor
|
|
|
511
511
|
}, { workspaceId, actor: toEventActor(actor) })
|
|
512
512
|
},
|
|
513
513
|
|
|
514
|
+
async seedHandbook(actor, workspaceId, input) {
|
|
515
|
+
const { memberId } = await requireMembership(actor, workspaceId, 'admin')
|
|
516
|
+
|
|
517
|
+
if (memberId === null) {
|
|
518
|
+
throw new AppError('forbidden', 'This action needs a workspace member')
|
|
519
|
+
}
|
|
520
|
+
|
|
521
|
+
const existing = await repository.listHandbookPages(dependencies.db, workspaceId)
|
|
522
|
+
|
|
523
|
+
if (existing.length > 0) {
|
|
524
|
+
if (input.replace !== true) {
|
|
525
|
+
throw AppError.conflict('This workspace already has handbook pages', [
|
|
526
|
+
{ field: 'replace', message: 'Set replace to true to replace starter pages' },
|
|
527
|
+
])
|
|
528
|
+
}
|
|
529
|
+
|
|
530
|
+
if (!existing.every((page) => isStarterHandbookBody(page))) {
|
|
531
|
+
throw AppError.conflict('Handbook pages have been edited and cannot be replaced')
|
|
532
|
+
}
|
|
533
|
+
}
|
|
534
|
+
|
|
535
|
+
const templatePages = getHandbookPagesForTemplate(input.handbookTemplate)
|
|
536
|
+
|
|
537
|
+
return dependencies.transaction(async ({ tx }) => {
|
|
538
|
+
if (existing.length > 0) {
|
|
539
|
+
await repository.deleteAllHandbookPages(tx, workspaceId)
|
|
540
|
+
}
|
|
541
|
+
|
|
542
|
+
await repository.insertHandbookPages(
|
|
543
|
+
tx,
|
|
544
|
+
templatePages.map((page, index) => ({
|
|
545
|
+
id: dependencies.createId('handbookPage'),
|
|
546
|
+
workspaceId,
|
|
547
|
+
title: page.title,
|
|
548
|
+
slug: page.slug,
|
|
549
|
+
sortOrder: index,
|
|
550
|
+
body: starterHandbookBody(page),
|
|
551
|
+
updatedBy: memberId,
|
|
552
|
+
})),
|
|
553
|
+
)
|
|
554
|
+
|
|
555
|
+
return { handbookPages: templatePages.length }
|
|
556
|
+
})
|
|
557
|
+
},
|
|
558
|
+
|
|
514
559
|
async get(actor, workspaceId) {
|
|
515
560
|
await requireMembership(actor, workspaceId, 'member')
|
|
516
561
|
const workspace = await repository.findWorkspace(dependencies.db, workspaceId)
|
|
@@ -6,27 +6,288 @@
|
|
|
6
6
|
* owner can then rename, reorder, or delete.
|
|
7
7
|
*/
|
|
8
8
|
|
|
9
|
+
export const HANDBOOK_TEMPLATE_IDS = [
|
|
10
|
+
'startup',
|
|
11
|
+
'agency',
|
|
12
|
+
'nonprofit',
|
|
13
|
+
'community',
|
|
14
|
+
'professional-services',
|
|
15
|
+
'creator',
|
|
16
|
+
] as const
|
|
17
|
+
|
|
18
|
+
export type HandbookTemplateId = (typeof HANDBOOK_TEMPLATE_IDS)[number]
|
|
19
|
+
|
|
9
20
|
export interface StarterHandbookPage {
|
|
10
21
|
readonly title: string
|
|
11
22
|
readonly slug: string
|
|
23
|
+
readonly bodyPrompt: string
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
export interface HandbookTemplate {
|
|
27
|
+
readonly id: HandbookTemplateId
|
|
28
|
+
readonly label: string
|
|
29
|
+
readonly description: string
|
|
30
|
+
readonly pages: readonly StarterHandbookPage[]
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
function page(title: string, slug: string, bodyPrompt: string): StarterHandbookPage {
|
|
34
|
+
return { title, slug, bodyPrompt }
|
|
12
35
|
}
|
|
13
36
|
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
37
|
+
const STARTUP_PAGES: readonly StarterHandbookPage[] = [
|
|
38
|
+
page('About us', 'about-us', 'What does your company do, and why does it exist?'),
|
|
39
|
+
page('Product', 'product', 'What do you sell, and what problem does it solve?'),
|
|
40
|
+
page(
|
|
41
|
+
'Ideal customer profile',
|
|
42
|
+
'ideal-customer-profile',
|
|
43
|
+
'Who is your best-fit customer? Size, industry, pain points, and buying signals.',
|
|
44
|
+
),
|
|
45
|
+
page('Voice and tone', 'voice-and-tone', 'How should Kelpie and your agents sound when they write on your behalf?'),
|
|
46
|
+
page('Pricing', 'pricing', 'How is your product priced? Plans, tiers, and what is included.'),
|
|
47
|
+
page('How we sell', 'how-we-sell', 'Your sales motion: inbound, outbound, trials, demos, and typical cycle.'),
|
|
48
|
+
page(
|
|
49
|
+
'Competitive landscape',
|
|
50
|
+
'competitive-landscape',
|
|
51
|
+
'Who else solves this problem, and why do customers choose you over them?',
|
|
52
|
+
),
|
|
53
|
+
page('Team and roles', 'team-and-roles', 'Who does what, and who owns which relationships or decisions?'),
|
|
54
|
+
page('Tools and stack', 'tools-and-stack', 'The systems your team and agents should know about.'),
|
|
55
|
+
page(
|
|
56
|
+
'Agent FAQ',
|
|
57
|
+
'agent-faq',
|
|
58
|
+
'Standing rules for agents: what they may promise, what they must escalate, and what never to invent.',
|
|
59
|
+
),
|
|
60
|
+
]
|
|
61
|
+
|
|
62
|
+
const AGENCY_PAGES: readonly StarterHandbookPage[] = [
|
|
63
|
+
page('About us', 'about-us', 'What does your agency do, and what makes your team distinctive?'),
|
|
64
|
+
page(
|
|
65
|
+
'Services & capabilities',
|
|
66
|
+
'product',
|
|
67
|
+
'What services do you offer, and what kinds of clients or projects fit best?',
|
|
68
|
+
),
|
|
69
|
+
page(
|
|
70
|
+
'Ideal client profile',
|
|
71
|
+
'ideal-customer-profile',
|
|
72
|
+
'Who is your best-fit client? Size, sector, budget, and the problems you solve best.',
|
|
73
|
+
),
|
|
74
|
+
page('Voice and tone', 'voice-and-tone', 'How should Kelpie and your agents sound in client-facing writing?'),
|
|
75
|
+
page(
|
|
76
|
+
'Pricing & engagement models',
|
|
77
|
+
'pricing',
|
|
78
|
+
'How you price work: retainers, fixed bids, day rates, and typical scopes.',
|
|
79
|
+
),
|
|
80
|
+
page('How we win work', 'how-we-sell', 'How you find and close clients: referrals, pitches, RFPs, and follow-up.'),
|
|
81
|
+
page(
|
|
82
|
+
'Competitive landscape',
|
|
83
|
+
'competitive-landscape',
|
|
84
|
+
'Who you compete with, and why clients choose you over alternatives.',
|
|
85
|
+
),
|
|
86
|
+
page(
|
|
87
|
+
'Case studies & proof points',
|
|
88
|
+
'case-studies',
|
|
89
|
+
'Outcomes you can cite: client wins, metrics, and stories agents may reference.',
|
|
90
|
+
),
|
|
91
|
+
page(
|
|
92
|
+
'How we deliver work',
|
|
93
|
+
'delivery-process',
|
|
94
|
+
'How a project runs from kickoff to handoff: phases, checkpoints, and client touchpoints.',
|
|
95
|
+
),
|
|
96
|
+
page('Team and roles', 'team-and-roles', 'Who leads delivery, sales, and client relationships?'),
|
|
97
|
+
page('Tools and stack', 'tools-and-stack', 'The systems your team and agents should know about.'),
|
|
98
|
+
page(
|
|
99
|
+
'Agent FAQ',
|
|
100
|
+
'agent-faq',
|
|
101
|
+
'Standing rules for agents: what they may promise, what they must escalate, and what never to invent.',
|
|
102
|
+
),
|
|
103
|
+
]
|
|
104
|
+
|
|
105
|
+
const NONPROFIT_PAGES: readonly StarterHandbookPage[] = [
|
|
106
|
+
page('About us & mission', 'about-us', 'Your mission, vision, and the change you exist to make.'),
|
|
107
|
+
page(
|
|
108
|
+
'Programs & impact',
|
|
109
|
+
'product',
|
|
110
|
+
'What programs or services you run, and what outcomes they aim for.',
|
|
111
|
+
),
|
|
112
|
+
page(
|
|
113
|
+
'Who we serve',
|
|
114
|
+
'ideal-customer-profile',
|
|
115
|
+
'The communities, beneficiaries, or stakeholders your programs exist for.',
|
|
116
|
+
),
|
|
117
|
+
page('Voice and tone', 'voice-and-tone', 'How should Kelpie and your agents sound when they write on your behalf?'),
|
|
118
|
+
page(
|
|
119
|
+
'How we engage supporters',
|
|
120
|
+
'how-we-sell',
|
|
121
|
+
'How you build relationships with donors, volunteers, partners, and the public.',
|
|
122
|
+
),
|
|
123
|
+
page(
|
|
124
|
+
'Funding & donations',
|
|
125
|
+
'funding-and-donations',
|
|
126
|
+
'Revenue streams: donations, grants, memberships, and major-gift approaches.',
|
|
127
|
+
),
|
|
128
|
+
page('Impact & outcomes', 'impact-metrics', 'How you measure success: outputs, outcomes, and stories you can cite.'),
|
|
129
|
+
page(
|
|
130
|
+
'Grant applications',
|
|
131
|
+
'grant-applications',
|
|
132
|
+
'How you find, qualify, and apply for grants; common requirements and deadlines.',
|
|
133
|
+
),
|
|
134
|
+
page('Team and roles', 'team-and-roles', 'Who does what, and who owns programs, fundraising, and comms?'),
|
|
135
|
+
page('Tools and stack', 'tools-and-stack', 'The systems your team and agents should know about.'),
|
|
136
|
+
page(
|
|
137
|
+
'Agent FAQ',
|
|
138
|
+
'agent-faq',
|
|
139
|
+
'Standing rules for agents: what they may promise, what they must escalate, and what never to invent.',
|
|
140
|
+
),
|
|
141
|
+
]
|
|
142
|
+
|
|
143
|
+
const COMMUNITY_PAGES: readonly StarterHandbookPage[] = [
|
|
144
|
+
page('About us', 'about-us', 'What your organisation is, its purpose, and who it serves.'),
|
|
145
|
+
page('What we offer', 'product', 'What members get: benefits, services, events, and community value.'),
|
|
146
|
+
page(
|
|
147
|
+
'Ideal member profile',
|
|
148
|
+
'ideal-customer-profile',
|
|
149
|
+
'Who should join, and what makes someone a good fit for your community?',
|
|
150
|
+
),
|
|
151
|
+
page('Voice and tone', 'voice-and-tone', 'How should Kelpie and your agents sound when they write on your behalf?'),
|
|
152
|
+
page('Membership & fees', 'pricing', 'Membership tiers, fees, and what each level includes.'),
|
|
153
|
+
page(
|
|
154
|
+
'How we grow membership',
|
|
155
|
+
'how-we-sell',
|
|
156
|
+
'How you attract and retain members: outreach, events, referrals, and renewals.',
|
|
157
|
+
),
|
|
158
|
+
page('Membership benefits', 'membership-benefits', 'What members receive: access, discounts, resources, and perks.'),
|
|
159
|
+
page(
|
|
160
|
+
'Events & programming',
|
|
161
|
+
'events-and-programming',
|
|
162
|
+
'Regular events, programs, and how members can participate.',
|
|
163
|
+
),
|
|
164
|
+
page('Team and roles', 'team-and-roles', 'Who runs the organisation, and who owns membership and events?'),
|
|
165
|
+
page('Tools and stack', 'tools-and-stack', 'The systems your team and agents should know about.'),
|
|
166
|
+
page(
|
|
167
|
+
'Agent FAQ',
|
|
168
|
+
'agent-faq',
|
|
169
|
+
'Standing rules for agents: what they may promise, what they must escalate, and what never to invent.',
|
|
170
|
+
),
|
|
26
171
|
]
|
|
27
172
|
|
|
28
|
-
|
|
29
|
-
|
|
173
|
+
const PROFESSIONAL_SERVICES_PAGES: readonly StarterHandbookPage[] = [
|
|
174
|
+
page('About the practice', 'about-us', 'What your practice does, its history, and what distinguishes it.'),
|
|
175
|
+
page('Practice areas', 'product', 'The services and matters you handle, and what you do not take on.'),
|
|
176
|
+
page(
|
|
177
|
+
'Ideal client profile',
|
|
178
|
+
'ideal-customer-profile',
|
|
179
|
+
'Who your best-fit clients are: size, sector, matter types, and engagement style.',
|
|
180
|
+
),
|
|
181
|
+
page('Voice and tone', 'voice-and-tone', 'How should Kelpie and your agents sound in client-facing writing?'),
|
|
182
|
+
page('Fee structures', 'pricing', 'How you charge: hourly, fixed, value-based, and typical ranges.'),
|
|
183
|
+
page(
|
|
184
|
+
'Business development',
|
|
185
|
+
'how-we-sell',
|
|
186
|
+
'How you win clients: referrals, networking, pitches, and follow-up.',
|
|
187
|
+
),
|
|
188
|
+
page('Market position', 'competitive-landscape', 'How you compare to peer firms and why clients choose you.'),
|
|
189
|
+
page(
|
|
190
|
+
'Conflicts & ethics',
|
|
191
|
+
'conflicts-and-ethics',
|
|
192
|
+
'Conflict checks, ethical boundaries, and what agents must never assume or promise.',
|
|
193
|
+
),
|
|
194
|
+
page('Team and roles', 'team-and-roles', 'Partners, associates, and who owns client relationships.'),
|
|
195
|
+
page('Tools and stack', 'tools-and-stack', 'The systems your team and agents should know about.'),
|
|
196
|
+
page(
|
|
197
|
+
'Agent FAQ',
|
|
198
|
+
'agent-faq',
|
|
199
|
+
'Standing rules for agents: what they may promise, what they must escalate, and what never to invent.',
|
|
200
|
+
),
|
|
201
|
+
]
|
|
202
|
+
|
|
203
|
+
const CREATOR_PAGES: readonly StarterHandbookPage[] = [
|
|
204
|
+
page('About me', 'about-us', 'Who you are, what you create, and what your brand stands for.'),
|
|
205
|
+
page('What I create', 'product', 'Your content, products, or services, and what makes them distinctive.'),
|
|
206
|
+
page(
|
|
207
|
+
'Audience profile',
|
|
208
|
+
'ideal-customer-profile',
|
|
209
|
+
'Who follows you, who buys from you, and what they care about.',
|
|
210
|
+
),
|
|
211
|
+
page('Voice and tone', 'voice-and-tone', 'How you sound across content, email, and brand partnerships.'),
|
|
212
|
+
page('Rates & packages', 'pricing', 'What you charge: sponsorship rates, consulting packages, and deliverables.'),
|
|
213
|
+
page(
|
|
214
|
+
'How I work with clients',
|
|
215
|
+
'how-we-sell',
|
|
216
|
+
'How inbound leads become paid work: discovery, scope, contracts, and delivery.',
|
|
217
|
+
),
|
|
218
|
+
page(
|
|
219
|
+
'Brand partnerships & sponsorships',
|
|
220
|
+
'brand-partnerships',
|
|
221
|
+
'What you offer sponsors, your rates, and brands you will or will not work with.',
|
|
222
|
+
),
|
|
223
|
+
page('Tools and stack', 'tools-and-stack', 'The systems you and your agents should know about.'),
|
|
224
|
+
page(
|
|
225
|
+
'Agent FAQ',
|
|
226
|
+
'agent-faq',
|
|
227
|
+
'Standing rules for agents: what they may promise, what they must escalate, and what never to invent.',
|
|
228
|
+
),
|
|
229
|
+
]
|
|
230
|
+
|
|
231
|
+
export const HANDBOOK_TEMPLATES: Readonly<Record<HandbookTemplateId, HandbookTemplate>> = {
|
|
232
|
+
startup: {
|
|
233
|
+
id: 'startup',
|
|
234
|
+
label: 'Startup',
|
|
235
|
+
description: 'Product company, SaaS, or tech startup selling software or services.',
|
|
236
|
+
pages: STARTUP_PAGES,
|
|
237
|
+
},
|
|
238
|
+
agency: {
|
|
239
|
+
id: 'agency',
|
|
240
|
+
label: 'Agency',
|
|
241
|
+
description: 'Consultancy, design shop, dev shop, or marketing agency.',
|
|
242
|
+
pages: AGENCY_PAGES,
|
|
243
|
+
},
|
|
244
|
+
nonprofit: {
|
|
245
|
+
id: 'nonprofit',
|
|
246
|
+
label: 'Nonprofit',
|
|
247
|
+
description: 'Charity, foundation, or social enterprise.',
|
|
248
|
+
pages: NONPROFIT_PAGES,
|
|
249
|
+
},
|
|
250
|
+
community: {
|
|
251
|
+
id: 'community',
|
|
252
|
+
label: 'Community',
|
|
253
|
+
description: 'Club, association, co-op, or membership organisation.',
|
|
254
|
+
pages: COMMUNITY_PAGES,
|
|
255
|
+
},
|
|
256
|
+
'professional-services': {
|
|
257
|
+
id: 'professional-services',
|
|
258
|
+
label: 'Professional services',
|
|
259
|
+
description: 'Law, accounting, architecture, or advisory practice.',
|
|
260
|
+
pages: PROFESSIONAL_SERVICES_PAGES,
|
|
261
|
+
},
|
|
262
|
+
creator: {
|
|
263
|
+
id: 'creator',
|
|
264
|
+
label: 'Creator',
|
|
265
|
+
description: 'Solo creator, freelancer, or personal brand.',
|
|
266
|
+
pages: CREATOR_PAGES,
|
|
267
|
+
},
|
|
268
|
+
}
|
|
269
|
+
|
|
270
|
+
/** Default startup template pages — same list `onboarding.md` names. */
|
|
271
|
+
export const STARTER_HANDBOOK_PAGES: readonly StarterHandbookPage[] = STARTUP_PAGES
|
|
272
|
+
|
|
273
|
+
export function isStarterHandbookBody(page: { readonly slug: string; readonly body: string }): boolean {
|
|
274
|
+
for (const template of Object.values(HANDBOOK_TEMPLATES)) {
|
|
275
|
+
for (const def of template.pages) {
|
|
276
|
+
if (def.slug === page.slug && starterHandbookBody(def) === page.body) {
|
|
277
|
+
return true
|
|
278
|
+
}
|
|
279
|
+
}
|
|
280
|
+
}
|
|
281
|
+
|
|
282
|
+
return false
|
|
283
|
+
}
|
|
284
|
+
|
|
285
|
+
export function getHandbookPagesForTemplate(templateId: HandbookTemplateId): readonly StarterHandbookPage[] {
|
|
286
|
+
return HANDBOOK_TEMPLATES[templateId].pages
|
|
287
|
+
}
|
|
288
|
+
|
|
289
|
+
export function starterHandbookBody(page: StarterHandbookPage): string {
|
|
290
|
+
return `# ${page.title}\n\n${page.bodyPrompt}`
|
|
30
291
|
}
|
|
31
292
|
|
|
32
293
|
export interface StarterStage {
|
|
@@ -23,10 +23,9 @@ import { WORKSPACE_ACCESS } from './capabilities.ts'
|
|
|
23
23
|
*
|
|
24
24
|
* Exempts `/v1/auth/*` and `/v1/account*`: they manage the *account*, not
|
|
25
25
|
* the workspace, and a member of a workspace this gate has locked out
|
|
26
|
-
* still needs to sign in, sign out,
|
|
27
|
-
*
|
|
28
|
-
* session to a different
|
|
29
|
-
* at login — so there is nothing further to exempt for that case.
|
|
26
|
+
* still needs to sign in, sign out, see their own account, list the
|
|
27
|
+
* workspaces they belong to (`GET /v1/auth/workspaces`), and switch this
|
|
28
|
+
* session to a different membership (`POST /v1/auth/workspace`).
|
|
30
29
|
*
|
|
31
30
|
* Also exempts `DELETE /v1/workspaces/:id` itself, and only that exact
|
|
32
31
|
* path: a suspension must never trap an owner into a workspace they can no
|
package/src/runtime/events.ts
CHANGED
package/src/runtime/module.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { Handler, Hono, MiddlewareHandler } from 'hono'
|
|
1
|
+
import type { Context, Handler, Hono, MiddlewareHandler } from 'hono'
|
|
2
2
|
import type { ZodType } from 'zod'
|
|
3
3
|
|
|
4
4
|
import type { Actor } from '../lib/actor.ts'
|
|
@@ -58,6 +58,53 @@ export interface McpToolRegistry {
|
|
|
58
58
|
tool<Input>(definition: McpToolDefinition<Input>): void
|
|
59
59
|
}
|
|
60
60
|
|
|
61
|
+
/**
|
|
62
|
+
* An identity a module verified somewhere else, handed back for core to sign in.
|
|
63
|
+
*
|
|
64
|
+
* Core never learns what OIDC or SAML is. Verification is the module's job and
|
|
65
|
+
* core does not redo it; core's job is that everything downstream of the cookie
|
|
66
|
+
* is identical to a password sign-in.
|
|
67
|
+
*/
|
|
68
|
+
export interface VerifiedIdentity {
|
|
69
|
+
readonly email: string
|
|
70
|
+
/** Core refuses the identity when false, rather than assuming the module checked. */
|
|
71
|
+
readonly emailVerified: boolean
|
|
72
|
+
/** The provider's display name, when it has one. The local part of the address is used otherwise. */
|
|
73
|
+
readonly name: string | null
|
|
74
|
+
/** Who verified it, recorded on the session: the module id, optionally suffixed (`sign-in:google`). */
|
|
75
|
+
readonly verifiedBy: string
|
|
76
|
+
/**
|
|
77
|
+
* What to do with an address core has never seen. The policy is the module's,
|
|
78
|
+
* because only it knows whether its provider vouches for strangers; executing
|
|
79
|
+
* it is core's.
|
|
80
|
+
*/
|
|
81
|
+
readonly provision: 'create' | 'refuse'
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
/** The account a completed sign-in belongs to. */
|
|
85
|
+
export interface CompletedSignInAccount {
|
|
86
|
+
readonly id: string
|
|
87
|
+
readonly email: string
|
|
88
|
+
readonly name: string
|
|
89
|
+
readonly emailVerified: boolean
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
export interface CompletedSignIn {
|
|
93
|
+
readonly account: CompletedSignInAccount
|
|
94
|
+
/** True when this sign-in provisioned the account rather than finding it. */
|
|
95
|
+
readonly created: boolean
|
|
96
|
+
readonly activeWorkspaceId: string | null
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
/**
|
|
100
|
+
* Completes a sign-in. Takes the Hono context because writing the session
|
|
101
|
+
* cookie on it is the point.
|
|
102
|
+
*/
|
|
103
|
+
export type ExternalSignInHandler = (
|
|
104
|
+
context: Context,
|
|
105
|
+
identity: VerifiedIdentity,
|
|
106
|
+
) => Promise<CompletedSignIn>
|
|
107
|
+
|
|
61
108
|
/**
|
|
62
109
|
* What a module gets to build with, beyond its own contributions.
|
|
63
110
|
*
|
|
@@ -86,6 +133,14 @@ export interface ModuleServices {
|
|
|
86
133
|
* `secretEncryption`. Same fallback pattern as `appBaseUrl`.
|
|
87
134
|
*/
|
|
88
135
|
readonly secretEncryption?: SecretEncryptionConfig | undefined
|
|
136
|
+
/**
|
|
137
|
+
* Whether the instance accepts a brand-new account, from `kelpie.config.ts`'s
|
|
138
|
+
* `signups` (or `SIGNUPS`). Undefined defaults to `true` (open), the same
|
|
139
|
+
* default `loadConfig` and `resolveKelpieConfig` use, so a caller that has
|
|
140
|
+
* not thought about it — a test, an older assembly — sees no change in
|
|
141
|
+
* behaviour.
|
|
142
|
+
*/
|
|
143
|
+
readonly signupsEnabled?: boolean
|
|
89
144
|
}
|
|
90
145
|
|
|
91
146
|
export interface ModuleContext extends ModuleServices {
|
|
@@ -119,6 +174,28 @@ export interface ModuleContext extends ModuleServices {
|
|
|
119
174
|
* delegates to the provider `email.provider` picked.
|
|
120
175
|
*/
|
|
121
176
|
readonly email: EmailSender
|
|
177
|
+
/**
|
|
178
|
+
* Installs the one implementation of external sign-in. Core's `auth` module
|
|
179
|
+
* calls this; a second caller fails boot.
|
|
180
|
+
*
|
|
181
|
+
* The same shape as `provideEmailSender`: a capability only one module owns,
|
|
182
|
+
* reached by every module through a proxy, so registration order does not
|
|
183
|
+
* matter to a consumer.
|
|
184
|
+
*/
|
|
185
|
+
provideExternalSignIn(handler: ExternalSignInHandler): void
|
|
186
|
+
/**
|
|
187
|
+
* Completes a sign-in for an identity this module already verified: finds or
|
|
188
|
+
* provisions the account, issues a session, and writes the session cookie on
|
|
189
|
+
* `context`.
|
|
190
|
+
*
|
|
191
|
+
* The alternative is a module writing core's `sessions` table itself, which
|
|
192
|
+
* ties it to core's token hashing, cookie flags and expiry with nothing
|
|
193
|
+
* keeping the two in step (`modules.md`).
|
|
194
|
+
*
|
|
195
|
+
* @throws ExternalSignInError when the identity is unverified, or unknown and
|
|
196
|
+
* the module asked for `provision: 'refuse'`.
|
|
197
|
+
*/
|
|
198
|
+
completeExternalSignIn(context: Context, identity: VerifiedIdentity): Promise<CompletedSignIn>
|
|
122
199
|
/**
|
|
123
200
|
* Registers routes that mount under `/v1/public`, take no credentials, and
|
|
124
201
|
* answer cross-origin requests from any site.
|