@kelpie/server 0.1.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/LICENSE +661 -0
- package/README.md +57 -0
- package/dist/app.d.ts +36 -0
- package/dist/app.d.ts.map +1 -0
- package/dist/app.js +98 -0
- package/dist/app.js.map +1 -0
- package/dist/index.d.ts +46 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +26 -0
- package/dist/index.js.map +1 -0
- package/dist/lib/actor.d.ts +71 -0
- package/dist/lib/actor.d.ts.map +1 -0
- package/dist/lib/actor.js +48 -0
- package/dist/lib/actor.js.map +1 -0
- package/dist/lib/changes.d.ts +17 -0
- package/dist/lib/changes.d.ts.map +1 -0
- package/dist/lib/changes.js +35 -0
- package/dist/lib/changes.js.map +1 -0
- package/dist/lib/columns.d.ts +152 -0
- package/dist/lib/columns.d.ts.map +1 -0
- package/dist/lib/columns.js +126 -0
- package/dist/lib/columns.js.map +1 -0
- package/dist/lib/config.d.ts +36 -0
- package/dist/lib/config.d.ts.map +1 -0
- package/dist/lib/config.js +52 -0
- package/dist/lib/config.js.map +1 -0
- package/dist/lib/database.d.ts +57 -0
- package/dist/lib/database.d.ts.map +1 -0
- package/dist/lib/database.js +91 -0
- package/dist/lib/database.js.map +1 -0
- package/dist/lib/dates.d.ts +11 -0
- package/dist/lib/dates.d.ts.map +1 -0
- package/dist/lib/dates.js +17 -0
- package/dist/lib/dates.js.map +1 -0
- package/dist/lib/email.d.ts +42 -0
- package/dist/lib/email.d.ts.map +1 -0
- package/dist/lib/email.js +38 -0
- package/dist/lib/email.js.map +1 -0
- package/dist/lib/errors.d.ts +76 -0
- package/dist/lib/errors.d.ts.map +1 -0
- package/dist/lib/errors.js +102 -0
- package/dist/lib/errors.js.map +1 -0
- package/dist/lib/http.d.ts +59 -0
- package/dist/lib/http.d.ts.map +1 -0
- package/dist/lib/http.js +89 -0
- package/dist/lib/http.js.map +1 -0
- package/dist/lib/ids.d.ts +55 -0
- package/dist/lib/ids.d.ts.map +1 -0
- package/dist/lib/ids.js +56 -0
- package/dist/lib/ids.js.map +1 -0
- package/dist/lib/logger.d.ts +22 -0
- package/dist/lib/logger.d.ts.map +1 -0
- package/dist/lib/logger.js +43 -0
- package/dist/lib/logger.js.map +1 -0
- package/dist/lib/moduleConfig.d.ts +14 -0
- package/dist/lib/moduleConfig.d.ts.map +1 -0
- package/dist/lib/moduleConfig.js +56 -0
- package/dist/lib/moduleConfig.js.map +1 -0
- package/dist/lib/normalisation.d.ts +19 -0
- package/dist/lib/normalisation.d.ts.map +1 -0
- package/dist/lib/normalisation.js +32 -0
- package/dist/lib/normalisation.js.map +1 -0
- package/dist/lib/pagination.d.ts +104 -0
- package/dist/lib/pagination.d.ts.map +1 -0
- package/dist/lib/pagination.js +189 -0
- package/dist/lib/pagination.js.map +1 -0
- package/dist/lib/passwords.d.ts +32 -0
- package/dist/lib/passwords.d.ts.map +1 -0
- package/dist/lib/passwords.js +51 -0
- package/dist/lib/passwords.js.map +1 -0
- package/dist/lib/search.d.ts +11 -0
- package/dist/lib/search.d.ts.map +1 -0
- package/dist/lib/search.js +25 -0
- package/dist/lib/search.js.map +1 -0
- package/dist/lib/secrets.d.ts +40 -0
- package/dist/lib/secrets.d.ts.map +1 -0
- package/dist/lib/secrets.js +152 -0
- package/dist/lib/secrets.js.map +1 -0
- package/dist/lib/timezones.d.ts +38 -0
- package/dist/lib/timezones.d.ts.map +1 -0
- package/dist/lib/timezones.js +55 -0
- package/dist/lib/timezones.js.map +1 -0
- package/dist/lib/tokens.d.ts +10 -0
- package/dist/lib/tokens.d.ts.map +1 -0
- package/dist/lib/tokens.js +31 -0
- package/dist/lib/tokens.js.map +1 -0
- package/dist/lib/url.d.ts +25 -0
- package/dist/lib/url.d.ts.map +1 -0
- package/dist/lib/url.js +41 -0
- package/dist/lib/url.js.map +1 -0
- package/dist/modules/activities/index.d.ts +18 -0
- package/dist/modules/activities/index.d.ts.map +1 -0
- package/dist/modules/activities/index.js +34 -0
- package/dist/modules/activities/index.js.map +1 -0
- package/dist/modules/activities/recorder.d.ts +53 -0
- package/dist/modules/activities/recorder.d.ts.map +1 -0
- package/dist/modules/activities/recorder.js +36 -0
- package/dist/modules/activities/recorder.js.map +1 -0
- package/dist/modules/activities/repository.d.ts +52 -0
- package/dist/modules/activities/repository.d.ts.map +1 -0
- package/dist/modules/activities/repository.js +127 -0
- package/dist/modules/activities/repository.js.map +1 -0
- package/dist/modules/activities/routes.d.ts +17 -0
- package/dist/modules/activities/routes.d.ts.map +1 -0
- package/dist/modules/activities/routes.js +45 -0
- package/dist/modules/activities/routes.js.map +1 -0
- package/dist/modules/activities/schema.d.ts +188 -0
- package/dist/modules/activities/schema.d.ts.map +1 -0
- package/dist/modules/activities/schema.js +34 -0
- package/dist/modules/activities/schema.js.map +1 -0
- package/dist/modules/activities/service.d.ts +32 -0
- package/dist/modules/activities/service.d.ts.map +1 -0
- package/dist/modules/activities/service.js +28 -0
- package/dist/modules/activities/service.js.map +1 -0
- package/dist/modules/activities/tools.d.ts +4 -0
- package/dist/modules/activities/tools.d.ts.map +1 -0
- package/dist/modules/activities/tools.js +26 -0
- package/dist/modules/activities/tools.js.map +1 -0
- package/dist/modules/activities/wording.d.ts +79 -0
- package/dist/modules/activities/wording.d.ts.map +1 -0
- package/dist/modules/activities/wording.js +134 -0
- package/dist/modules/activities/wording.js.map +1 -0
- package/dist/modules/agent-tasks/catalog.d.ts +16 -0
- package/dist/modules/agent-tasks/catalog.d.ts.map +1 -0
- package/dist/modules/agent-tasks/catalog.js +694 -0
- package/dist/modules/agent-tasks/catalog.js.map +1 -0
- package/dist/modules/agent-tasks/dispatch.d.ts +61 -0
- package/dist/modules/agent-tasks/dispatch.d.ts.map +1 -0
- package/dist/modules/agent-tasks/dispatch.js +139 -0
- package/dist/modules/agent-tasks/dispatch.js.map +1 -0
- package/dist/modules/agent-tasks/index.d.ts +17 -0
- package/dist/modules/agent-tasks/index.d.ts.map +1 -0
- package/dist/modules/agent-tasks/index.js +54 -0
- package/dist/modules/agent-tasks/index.js.map +1 -0
- package/dist/modules/agent-tasks/prompt.d.ts +41 -0
- package/dist/modules/agent-tasks/prompt.d.ts.map +1 -0
- package/dist/modules/agent-tasks/prompt.js +78 -0
- package/dist/modules/agent-tasks/prompt.js.map +1 -0
- package/dist/modules/agent-tasks/repository.d.ts +32 -0
- package/dist/modules/agent-tasks/repository.d.ts.map +1 -0
- package/dist/modules/agent-tasks/repository.js +83 -0
- package/dist/modules/agent-tasks/repository.js.map +1 -0
- package/dist/modules/agent-tasks/resolve.d.ts +44 -0
- package/dist/modules/agent-tasks/resolve.d.ts.map +1 -0
- package/dist/modules/agent-tasks/resolve.js +396 -0
- package/dist/modules/agent-tasks/resolve.js.map +1 -0
- package/dist/modules/agent-tasks/routes.d.ts +55 -0
- package/dist/modules/agent-tasks/routes.d.ts.map +1 -0
- package/dist/modules/agent-tasks/routes.js +173 -0
- package/dist/modules/agent-tasks/routes.js.map +1 -0
- package/dist/modules/agent-tasks/schema.d.ts +346 -0
- package/dist/modules/agent-tasks/schema.d.ts.map +1 -0
- package/dist/modules/agent-tasks/schema.js +47 -0
- package/dist/modules/agent-tasks/schema.js.map +1 -0
- package/dist/modules/agent-tasks/service.d.ts +79 -0
- package/dist/modules/agent-tasks/service.d.ts.map +1 -0
- package/dist/modules/agent-tasks/service.js +210 -0
- package/dist/modules/agent-tasks/service.js.map +1 -0
- package/dist/modules/agent-tasks/wire.d.ts +35 -0
- package/dist/modules/agent-tasks/wire.d.ts.map +1 -0
- package/dist/modules/agent-tasks/wire.js +31 -0
- package/dist/modules/agent-tasks/wire.js.map +1 -0
- package/dist/modules/api-keys/index.d.ts +9 -0
- package/dist/modules/api-keys/index.d.ts.map +1 -0
- package/dist/modules/api-keys/index.js +29 -0
- package/dist/modules/api-keys/index.js.map +1 -0
- package/dist/modules/api-keys/keys.d.ts +25 -0
- package/dist/modules/api-keys/keys.d.ts.map +1 -0
- package/dist/modules/api-keys/keys.js +40 -0
- package/dist/modules/api-keys/keys.js.map +1 -0
- package/dist/modules/api-keys/repository.d.ts +15 -0
- package/dist/modules/api-keys/repository.d.ts.map +1 -0
- package/dist/modules/api-keys/repository.js +48 -0
- package/dist/modules/api-keys/repository.js.map +1 -0
- package/dist/modules/api-keys/routes.d.ts +8 -0
- package/dist/modules/api-keys/routes.d.ts.map +1 -0
- package/dist/modules/api-keys/routes.js +52 -0
- package/dist/modules/api-keys/routes.js.map +1 -0
- package/dist/modules/api-keys/schema.d.ts +166 -0
- package/dist/modules/api-keys/schema.d.ts.map +1 -0
- package/dist/modules/api-keys/schema.js +23 -0
- package/dist/modules/api-keys/schema.js.map +1 -0
- package/dist/modules/api-keys/service.d.ts +37 -0
- package/dist/modules/api-keys/service.d.ts.map +1 -0
- package/dist/modules/api-keys/service.js +95 -0
- package/dist/modules/api-keys/service.js.map +1 -0
- package/dist/modules/attachedRecords.d.ts +39 -0
- package/dist/modules/attachedRecords.d.ts.map +1 -0
- package/dist/modules/attachedRecords.js +52 -0
- package/dist/modules/attachedRecords.js.map +1 -0
- package/dist/modules/auth/actor.d.ts +11 -0
- package/dist/modules/auth/actor.d.ts.map +1 -0
- package/dist/modules/auth/actor.js +10 -0
- package/dist/modules/auth/actor.js.map +1 -0
- package/dist/modules/auth/credentials.d.ts +18 -0
- package/dist/modules/auth/credentials.d.ts.map +1 -0
- package/dist/modules/auth/credentials.js +105 -0
- package/dist/modules/auth/credentials.js.map +1 -0
- package/dist/modules/auth/index.d.ts +3 -0
- package/dist/modules/auth/index.d.ts.map +1 -0
- package/dist/modules/auth/index.js +41 -0
- package/dist/modules/auth/index.js.map +1 -0
- package/dist/modules/auth/preferences.d.ts +34 -0
- package/dist/modules/auth/preferences.d.ts.map +1 -0
- package/dist/modules/auth/preferences.js +30 -0
- package/dist/modules/auth/preferences.js.map +1 -0
- package/dist/modules/auth/repository.d.ts +54 -0
- package/dist/modules/auth/repository.d.ts.map +1 -0
- package/dist/modules/auth/repository.js +137 -0
- package/dist/modules/auth/repository.js.map +1 -0
- package/dist/modules/auth/routes.d.ts +10 -0
- package/dist/modules/auth/routes.d.ts.map +1 -0
- package/dist/modules/auth/routes.js +181 -0
- package/dist/modules/auth/routes.js.map +1 -0
- package/dist/modules/auth/schema.d.ts +530 -0
- package/dist/modules/auth/schema.d.ts.map +1 -0
- package/dist/modules/auth/schema.js +67 -0
- package/dist/modules/auth/schema.js.map +1 -0
- package/dist/modules/auth/service.d.ts +73 -0
- package/dist/modules/auth/service.d.ts.map +1 -0
- package/dist/modules/auth/service.js +288 -0
- package/dist/modules/auth/service.js.map +1 -0
- package/dist/modules/auth/session.d.ts +16 -0
- package/dist/modules/auth/session.d.ts.map +1 -0
- package/dist/modules/auth/session.js +30 -0
- package/dist/modules/auth/session.js.map +1 -0
- package/dist/modules/companies/index.d.ts +9 -0
- package/dist/modules/companies/index.d.ts.map +1 -0
- package/dist/modules/companies/index.js +37 -0
- package/dist/modules/companies/index.js.map +1 -0
- package/dist/modules/companies/repository.d.ts +40 -0
- package/dist/modules/companies/repository.d.ts.map +1 -0
- package/dist/modules/companies/repository.js +112 -0
- package/dist/modules/companies/repository.js.map +1 -0
- package/dist/modules/companies/routes.d.ts +89 -0
- package/dist/modules/companies/routes.d.ts.map +1 -0
- package/dist/modules/companies/routes.js +125 -0
- package/dist/modules/companies/routes.js.map +1 -0
- package/dist/modules/companies/schema.d.ts +381 -0
- package/dist/modules/companies/schema.d.ts.map +1 -0
- package/dist/modules/companies/schema.js +51 -0
- package/dist/modules/companies/schema.js.map +1 -0
- package/dist/modules/companies/service.d.ts +49 -0
- package/dist/modules/companies/service.d.ts.map +1 -0
- package/dist/modules/companies/service.js +184 -0
- package/dist/modules/companies/service.js.map +1 -0
- package/dist/modules/companies/tools.d.ts +4 -0
- package/dist/modules/companies/tools.d.ts.map +1 -0
- package/dist/modules/companies/tools.js +27 -0
- package/dist/modules/companies/tools.js.map +1 -0
- package/dist/modules/core.d.ts +21 -0
- package/dist/modules/core.d.ts.map +1 -0
- package/dist/modules/core.js +82 -0
- package/dist/modules/core.js.map +1 -0
- package/dist/modules/crudTools.d.ts +99 -0
- package/dist/modules/crudTools.d.ts.map +1 -0
- package/dist/modules/crudTools.js +123 -0
- package/dist/modules/crudTools.js.map +1 -0
- package/dist/modules/dashboard/attention.d.ts +39 -0
- package/dist/modules/dashboard/attention.d.ts.map +1 -0
- package/dist/modules/dashboard/attention.js +57 -0
- package/dist/modules/dashboard/attention.js.map +1 -0
- package/dist/modules/dashboard/index.d.ts +15 -0
- package/dist/modules/dashboard/index.d.ts.map +1 -0
- package/dist/modules/dashboard/index.js +44 -0
- package/dist/modules/dashboard/index.js.map +1 -0
- package/dist/modules/dashboard/repository.d.ts +83 -0
- package/dist/modules/dashboard/repository.d.ts.map +1 -0
- package/dist/modules/dashboard/repository.js +217 -0
- package/dist/modules/dashboard/repository.js.map +1 -0
- package/dist/modules/dashboard/routes.d.ts +21 -0
- package/dist/modules/dashboard/routes.d.ts.map +1 -0
- package/dist/modules/dashboard/routes.js +116 -0
- package/dist/modules/dashboard/routes.js.map +1 -0
- package/dist/modules/dashboard/service.d.ts +122 -0
- package/dist/modules/dashboard/service.d.ts.map +1 -0
- package/dist/modules/dashboard/service.js +215 -0
- package/dist/modules/dashboard/service.js.map +1 -0
- package/dist/modules/dashboard/tools.d.ts +4 -0
- package/dist/modules/dashboard/tools.d.ts.map +1 -0
- package/dist/modules/dashboard/tools.js +33 -0
- package/dist/modules/dashboard/tools.js.map +1 -0
- package/dist/modules/deals/index.d.ts +11 -0
- package/dist/modules/deals/index.d.ts.map +1 -0
- package/dist/modules/deals/index.js +38 -0
- package/dist/modules/deals/index.js.map +1 -0
- package/dist/modules/deals/repository.d.ts +44 -0
- package/dist/modules/deals/repository.d.ts.map +1 -0
- package/dist/modules/deals/repository.js +160 -0
- package/dist/modules/deals/repository.js.map +1 -0
- package/dist/modules/deals/routes.d.ts +50 -0
- package/dist/modules/deals/routes.d.ts.map +1 -0
- package/dist/modules/deals/routes.js +132 -0
- package/dist/modules/deals/routes.js.map +1 -0
- package/dist/modules/deals/schema.d.ts +419 -0
- package/dist/modules/deals/schema.d.ts.map +1 -0
- package/dist/modules/deals/schema.js +61 -0
- package/dist/modules/deals/schema.js.map +1 -0
- package/dist/modules/deals/service.d.ts +71 -0
- package/dist/modules/deals/service.d.ts.map +1 -0
- package/dist/modules/deals/service.js +277 -0
- package/dist/modules/deals/service.js.map +1 -0
- package/dist/modules/deals/tools.d.ts +4 -0
- package/dist/modules/deals/tools.d.ts.map +1 -0
- package/dist/modules/deals/tools.js +33 -0
- package/dist/modules/deals/tools.js.map +1 -0
- package/dist/modules/decisions/index.d.ts +11 -0
- package/dist/modules/decisions/index.d.ts.map +1 -0
- package/dist/modules/decisions/index.js +34 -0
- package/dist/modules/decisions/index.js.map +1 -0
- package/dist/modules/decisions/repository.d.ts +38 -0
- package/dist/modules/decisions/repository.d.ts.map +1 -0
- package/dist/modules/decisions/repository.js +126 -0
- package/dist/modules/decisions/repository.js.map +1 -0
- package/dist/modules/decisions/routes.d.ts +42 -0
- package/dist/modules/decisions/routes.d.ts.map +1 -0
- package/dist/modules/decisions/routes.js +131 -0
- package/dist/modules/decisions/routes.js.map +1 -0
- package/dist/modules/decisions/schema.d.ts +228 -0
- package/dist/modules/decisions/schema.d.ts.map +1 -0
- package/dist/modules/decisions/schema.js +41 -0
- package/dist/modules/decisions/schema.js.map +1 -0
- package/dist/modules/decisions/service.d.ts +60 -0
- package/dist/modules/decisions/service.d.ts.map +1 -0
- package/dist/modules/decisions/service.js +122 -0
- package/dist/modules/decisions/service.js.map +1 -0
- package/dist/modules/decisions/tools.d.ts +4 -0
- package/dist/modules/decisions/tools.d.ts.map +1 -0
- package/dist/modules/decisions/tools.js +32 -0
- package/dist/modules/decisions/tools.js.map +1 -0
- package/dist/modules/forms/embed.d.ts +50 -0
- package/dist/modules/forms/embed.d.ts.map +1 -0
- package/dist/modules/forms/embed.js +236 -0
- package/dist/modules/forms/embed.js.map +1 -0
- package/dist/modules/forms/fields.d.ts +71 -0
- package/dist/modules/forms/fields.d.ts.map +1 -0
- package/dist/modules/forms/fields.js +122 -0
- package/dist/modules/forms/fields.js.map +1 -0
- package/dist/modules/forms/index.d.ts +15 -0
- package/dist/modules/forms/index.d.ts.map +1 -0
- package/dist/modules/forms/index.js +53 -0
- package/dist/modules/forms/index.js.map +1 -0
- package/dist/modules/forms/mapping.d.ts +99 -0
- package/dist/modules/forms/mapping.d.ts.map +1 -0
- package/dist/modules/forms/mapping.js +152 -0
- package/dist/modules/forms/mapping.js.map +1 -0
- package/dist/modules/forms/publicRoutes.d.ts +11 -0
- package/dist/modules/forms/publicRoutes.d.ts.map +1 -0
- package/dist/modules/forms/publicRoutes.js +68 -0
- package/dist/modules/forms/publicRoutes.js.map +1 -0
- package/dist/modules/forms/repository.d.ts +65 -0
- package/dist/modules/forms/repository.d.ts.map +1 -0
- package/dist/modules/forms/repository.js +139 -0
- package/dist/modules/forms/repository.js.map +1 -0
- package/dist/modules/forms/routes.d.ts +106 -0
- package/dist/modules/forms/routes.d.ts.map +1 -0
- package/dist/modules/forms/routes.js +204 -0
- package/dist/modules/forms/routes.js.map +1 -0
- package/dist/modules/forms/schema.d.ts +643 -0
- package/dist/modules/forms/schema.d.ts.map +1 -0
- package/dist/modules/forms/schema.js +87 -0
- package/dist/modules/forms/schema.js.map +1 -0
- package/dist/modules/forms/service.d.ts +62 -0
- package/dist/modules/forms/service.d.ts.map +1 -0
- package/dist/modules/forms/service.js +208 -0
- package/dist/modules/forms/service.js.map +1 -0
- package/dist/modules/forms/submission.d.ts +30 -0
- package/dist/modules/forms/submission.d.ts.map +1 -0
- package/dist/modules/forms/submission.js +337 -0
- package/dist/modules/forms/submission.js.map +1 -0
- package/dist/modules/forms/tools.d.ts +4 -0
- package/dist/modules/forms/tools.d.ts.map +1 -0
- package/dist/modules/forms/tools.js +46 -0
- package/dist/modules/forms/tools.js.map +1 -0
- package/dist/modules/handbook/index.d.ts +15 -0
- package/dist/modules/handbook/index.d.ts.map +1 -0
- package/dist/modules/handbook/index.js +37 -0
- package/dist/modules/handbook/index.js.map +1 -0
- package/dist/modules/handbook/repository.d.ts +52 -0
- package/dist/modules/handbook/repository.d.ts.map +1 -0
- package/dist/modules/handbook/repository.js +109 -0
- package/dist/modules/handbook/repository.js.map +1 -0
- package/dist/modules/handbook/routes.d.ts +38 -0
- package/dist/modules/handbook/routes.d.ts.map +1 -0
- package/dist/modules/handbook/routes.js +103 -0
- package/dist/modules/handbook/routes.js.map +1 -0
- package/dist/modules/handbook/schema.d.ts +206 -0
- package/dist/modules/handbook/schema.d.ts.map +1 -0
- package/dist/modules/handbook/schema.js +37 -0
- package/dist/modules/handbook/schema.js.map +1 -0
- package/dist/modules/handbook/service.d.ts +59 -0
- package/dist/modules/handbook/service.d.ts.map +1 -0
- package/dist/modules/handbook/service.js +246 -0
- package/dist/modules/handbook/service.js.map +1 -0
- package/dist/modules/handbook/slugs.d.ts +28 -0
- package/dist/modules/handbook/slugs.d.ts.map +1 -0
- package/dist/modules/handbook/slugs.js +48 -0
- package/dist/modules/handbook/slugs.js.map +1 -0
- package/dist/modules/handbook/tools.d.ts +4 -0
- package/dist/modules/handbook/tools.d.ts.map +1 -0
- package/dist/modules/handbook/tools.js +26 -0
- package/dist/modules/handbook/tools.js.map +1 -0
- package/dist/modules/handbook/tree.d.ts +69 -0
- package/dist/modules/handbook/tree.d.ts.map +1 -0
- package/dist/modules/handbook/tree.js +117 -0
- package/dist/modules/handbook/tree.js.map +1 -0
- package/dist/modules/hiring/candidates.d.ts +70 -0
- package/dist/modules/hiring/candidates.d.ts.map +1 -0
- package/dist/modules/hiring/candidates.js +243 -0
- package/dist/modules/hiring/candidates.js.map +1 -0
- package/dist/modules/hiring/index.d.ts +15 -0
- package/dist/modules/hiring/index.d.ts.map +1 -0
- package/dist/modules/hiring/index.js +48 -0
- package/dist/modules/hiring/index.js.map +1 -0
- package/dist/modules/hiring/repository.d.ts +52 -0
- package/dist/modules/hiring/repository.d.ts.map +1 -0
- package/dist/modules/hiring/repository.js +137 -0
- package/dist/modules/hiring/repository.js.map +1 -0
- package/dist/modules/hiring/roles.d.ts +42 -0
- package/dist/modules/hiring/roles.d.ts.map +1 -0
- package/dist/modules/hiring/roles.js +104 -0
- package/dist/modules/hiring/roles.js.map +1 -0
- package/dist/modules/hiring/routes.d.ts +73 -0
- package/dist/modules/hiring/routes.d.ts.map +1 -0
- package/dist/modules/hiring/routes.js +170 -0
- package/dist/modules/hiring/routes.js.map +1 -0
- package/dist/modules/hiring/schema.d.ts +308 -0
- package/dist/modules/hiring/schema.d.ts.map +1 -0
- package/dist/modules/hiring/schema.js +62 -0
- package/dist/modules/hiring/schema.js.map +1 -0
- package/dist/modules/hiring/tools.d.ts +8 -0
- package/dist/modules/hiring/tools.d.ts.map +1 -0
- package/dist/modules/hiring/tools.js +50 -0
- package/dist/modules/hiring/tools.js.map +1 -0
- package/dist/modules/import-export/csv.d.ts +47 -0
- package/dist/modules/import-export/csv.d.ts.map +1 -0
- package/dist/modules/import-export/csv.js +138 -0
- package/dist/modules/import-export/csv.js.map +1 -0
- package/dist/modules/import-export/drafts.d.ts +83 -0
- package/dist/modules/import-export/drafts.d.ts.map +1 -0
- package/dist/modules/import-export/drafts.js +97 -0
- package/dist/modules/import-export/drafts.js.map +1 -0
- package/dist/modules/import-export/exportRows.d.ts +8 -0
- package/dist/modules/import-export/exportRows.d.ts.map +1 -0
- package/dist/modules/import-export/exportRows.js +71 -0
- package/dist/modules/import-export/exportRows.js.map +1 -0
- package/dist/modules/import-export/index.d.ts +15 -0
- package/dist/modules/import-export/index.d.ts.map +1 -0
- package/dist/modules/import-export/index.js +43 -0
- package/dist/modules/import-export/index.js.map +1 -0
- package/dist/modules/import-export/mapping.d.ts +46 -0
- package/dist/modules/import-export/mapping.d.ts.map +1 -0
- package/dist/modules/import-export/mapping.js +115 -0
- package/dist/modules/import-export/mapping.js.map +1 -0
- package/dist/modules/import-export/plan.d.ts +107 -0
- package/dist/modules/import-export/plan.d.ts.map +1 -0
- package/dist/modules/import-export/plan.js +178 -0
- package/dist/modules/import-export/plan.js.map +1 -0
- package/dist/modules/import-export/presets.d.ts +39 -0
- package/dist/modules/import-export/presets.d.ts.map +1 -0
- package/dist/modules/import-export/presets.js +151 -0
- package/dist/modules/import-export/presets.js.map +1 -0
- package/dist/modules/import-export/repository.d.ts +171 -0
- package/dist/modules/import-export/repository.d.ts.map +1 -0
- package/dist/modules/import-export/repository.js +343 -0
- package/dist/modules/import-export/repository.js.map +1 -0
- package/dist/modules/import-export/routes.d.ts +9 -0
- package/dist/modules/import-export/routes.d.ts.map +1 -0
- package/dist/modules/import-export/routes.js +199 -0
- package/dist/modules/import-export/routes.js.map +1 -0
- package/dist/modules/import-export/schema.d.ts +494 -0
- package/dist/modules/import-export/schema.d.ts.map +1 -0
- package/dist/modules/import-export/schema.js +99 -0
- package/dist/modules/import-export/schema.js.map +1 -0
- package/dist/modules/import-export/service.d.ts +74 -0
- package/dist/modules/import-export/service.d.ts.map +1 -0
- package/dist/modules/import-export/service.js +561 -0
- package/dist/modules/import-export/service.js.map +1 -0
- package/dist/modules/import-export/streams.d.ts +4 -0
- package/dist/modules/import-export/streams.d.ts.map +1 -0
- package/dist/modules/import-export/streams.js +55 -0
- package/dist/modules/import-export/streams.js.map +1 -0
- package/dist/modules/import-export/tools.d.ts +22 -0
- package/dist/modules/import-export/tools.d.ts.map +1 -0
- package/dist/modules/import-export/tools.js +116 -0
- package/dist/modules/import-export/tools.js.map +1 -0
- package/dist/modules/import-export/validation.d.ts +7 -0
- package/dist/modules/import-export/validation.d.ts.map +1 -0
- package/dist/modules/import-export/validation.js +114 -0
- package/dist/modules/import-export/validation.js.map +1 -0
- package/dist/modules/import-export/writes.d.ts +45 -0
- package/dist/modules/import-export/writes.d.ts.map +1 -0
- package/dist/modules/import-export/writes.js +247 -0
- package/dist/modules/import-export/writes.js.map +1 -0
- package/dist/modules/integrations/schema.d.ts +185 -0
- package/dist/modules/integrations/schema.d.ts.map +1 -0
- package/dist/modules/integrations/schema.js +26 -0
- package/dist/modules/integrations/schema.js.map +1 -0
- package/dist/modules/mcp/index.d.ts +26 -0
- package/dist/modules/mcp/index.d.ts.map +1 -0
- package/dist/modules/mcp/index.js +45 -0
- package/dist/modules/mcp/index.js.map +1 -0
- package/dist/modules/mcp/protocol.d.ts +166 -0
- package/dist/modules/mcp/protocol.d.ts.map +1 -0
- package/dist/modules/mcp/protocol.js +292 -0
- package/dist/modules/mcp/protocol.js.map +1 -0
- package/dist/modules/mcp/router.d.ts +23 -0
- package/dist/modules/mcp/router.d.ts.map +1 -0
- package/dist/modules/mcp/router.js +298 -0
- package/dist/modules/mcp/router.js.map +1 -0
- package/dist/modules/notes/index.d.ts +9 -0
- package/dist/modules/notes/index.d.ts.map +1 -0
- package/dist/modules/notes/index.js +37 -0
- package/dist/modules/notes/index.js.map +1 -0
- package/dist/modules/notes/repository.d.ts +34 -0
- package/dist/modules/notes/repository.d.ts.map +1 -0
- package/dist/modules/notes/repository.js +70 -0
- package/dist/modules/notes/repository.js.map +1 -0
- package/dist/modules/notes/routes.d.ts +37 -0
- package/dist/modules/notes/routes.d.ts.map +1 -0
- package/dist/modules/notes/routes.js +124 -0
- package/dist/modules/notes/routes.js.map +1 -0
- package/dist/modules/notes/schema.d.ts +176 -0
- package/dist/modules/notes/schema.d.ts.map +1 -0
- package/dist/modules/notes/schema.js +35 -0
- package/dist/modules/notes/schema.js.map +1 -0
- package/dist/modules/notes/service.d.ts +49 -0
- package/dist/modules/notes/service.d.ts.map +1 -0
- package/dist/modules/notes/service.js +118 -0
- package/dist/modules/notes/service.js.map +1 -0
- package/dist/modules/notes/tools.d.ts +4 -0
- package/dist/modules/notes/tools.d.ts.map +1 -0
- package/dist/modules/notes/tools.js +41 -0
- package/dist/modules/notes/tools.js.map +1 -0
- package/dist/modules/opportunities/index.d.ts +11 -0
- package/dist/modules/opportunities/index.d.ts.map +1 -0
- package/dist/modules/opportunities/index.js +38 -0
- package/dist/modules/opportunities/index.js.map +1 -0
- package/dist/modules/opportunities/repository.d.ts +28 -0
- package/dist/modules/opportunities/repository.d.ts.map +1 -0
- package/dist/modules/opportunities/repository.js +89 -0
- package/dist/modules/opportunities/repository.js.map +1 -0
- package/dist/modules/opportunities/routes.d.ts +39 -0
- package/dist/modules/opportunities/routes.d.ts.map +1 -0
- package/dist/modules/opportunities/routes.js +104 -0
- package/dist/modules/opportunities/routes.js.map +1 -0
- package/dist/modules/opportunities/schema.d.ts +266 -0
- package/dist/modules/opportunities/schema.d.ts.map +1 -0
- package/dist/modules/opportunities/schema.js +41 -0
- package/dist/modules/opportunities/schema.js.map +1 -0
- package/dist/modules/opportunities/service.d.ts +60 -0
- package/dist/modules/opportunities/service.d.ts.map +1 -0
- package/dist/modules/opportunities/service.js +212 -0
- package/dist/modules/opportunities/service.js.map +1 -0
- package/dist/modules/opportunities/tools.d.ts +4 -0
- package/dist/modules/opportunities/tools.d.ts.map +1 -0
- package/dist/modules/opportunities/tools.js +33 -0
- package/dist/modules/opportunities/tools.js.map +1 -0
- package/dist/modules/partnerships/index.d.ts +11 -0
- package/dist/modules/partnerships/index.d.ts.map +1 -0
- package/dist/modules/partnerships/index.js +38 -0
- package/dist/modules/partnerships/index.js.map +1 -0
- package/dist/modules/partnerships/repository.d.ts +47 -0
- package/dist/modules/partnerships/repository.d.ts.map +1 -0
- package/dist/modules/partnerships/repository.js +169 -0
- package/dist/modules/partnerships/repository.js.map +1 -0
- package/dist/modules/partnerships/routes.d.ts +46 -0
- package/dist/modules/partnerships/routes.d.ts.map +1 -0
- package/dist/modules/partnerships/routes.js +122 -0
- package/dist/modules/partnerships/routes.js.map +1 -0
- package/dist/modules/partnerships/schema.d.ts +338 -0
- package/dist/modules/partnerships/schema.d.ts.map +1 -0
- package/dist/modules/partnerships/schema.js +54 -0
- package/dist/modules/partnerships/schema.js.map +1 -0
- package/dist/modules/partnerships/service.d.ts +71 -0
- package/dist/modules/partnerships/service.d.ts.map +1 -0
- package/dist/modules/partnerships/service.js +273 -0
- package/dist/modules/partnerships/service.js.map +1 -0
- package/dist/modules/partnerships/tools.d.ts +4 -0
- package/dist/modules/partnerships/tools.d.ts.map +1 -0
- package/dist/modules/partnerships/tools.js +35 -0
- package/dist/modules/partnerships/tools.js.map +1 -0
- package/dist/modules/people/index.d.ts +9 -0
- package/dist/modules/people/index.d.ts.map +1 -0
- package/dist/modules/people/index.js +37 -0
- package/dist/modules/people/index.js.map +1 -0
- package/dist/modules/people/repository.d.ts +31 -0
- package/dist/modules/people/repository.d.ts.map +1 -0
- package/dist/modules/people/repository.js +109 -0
- package/dist/modules/people/repository.js.map +1 -0
- package/dist/modules/people/routes.d.ts +111 -0
- package/dist/modules/people/routes.d.ts.map +1 -0
- package/dist/modules/people/routes.js +134 -0
- package/dist/modules/people/routes.js.map +1 -0
- package/dist/modules/people/schema.d.ts +354 -0
- package/dist/modules/people/schema.d.ts.map +1 -0
- package/dist/modules/people/schema.js +61 -0
- package/dist/modules/people/schema.js.map +1 -0
- package/dist/modules/people/service.d.ts +56 -0
- package/dist/modules/people/service.d.ts.map +1 -0
- package/dist/modules/people/service.js +190 -0
- package/dist/modules/people/service.js.map +1 -0
- package/dist/modules/people/tools.d.ts +4 -0
- package/dist/modules/people/tools.d.ts.map +1 -0
- package/dist/modules/people/tools.js +27 -0
- package/dist/modules/people/tools.js.map +1 -0
- package/dist/modules/pipelines/index.d.ts +9 -0
- package/dist/modules/pipelines/index.d.ts.map +1 -0
- package/dist/modules/pipelines/index.js +37 -0
- package/dist/modules/pipelines/index.js.map +1 -0
- package/dist/modules/pipelines/repository.d.ts +26 -0
- package/dist/modules/pipelines/repository.d.ts.map +1 -0
- package/dist/modules/pipelines/repository.js +67 -0
- package/dist/modules/pipelines/repository.js.map +1 -0
- package/dist/modules/pipelines/routes.d.ts +33 -0
- package/dist/modules/pipelines/routes.d.ts.map +1 -0
- package/dist/modules/pipelines/routes.js +98 -0
- package/dist/modules/pipelines/routes.js.map +1 -0
- package/dist/modules/pipelines/schema.d.ts +170 -0
- package/dist/modules/pipelines/schema.d.ts.map +1 -0
- package/dist/modules/pipelines/schema.js +30 -0
- package/dist/modules/pipelines/schema.js.map +1 -0
- package/dist/modules/pipelines/service.d.ts +49 -0
- package/dist/modules/pipelines/service.d.ts.map +1 -0
- package/dist/modules/pipelines/service.js +227 -0
- package/dist/modules/pipelines/service.js.map +1 -0
- package/dist/modules/pipelines/tools.d.ts +4 -0
- package/dist/modules/pipelines/tools.d.ts.map +1 -0
- package/dist/modules/pipelines/tools.js +43 -0
- package/dist/modules/pipelines/tools.js.map +1 -0
- package/dist/modules/plans/index.d.ts +10 -0
- package/dist/modules/plans/index.d.ts.map +1 -0
- package/dist/modules/plans/index.js +33 -0
- package/dist/modules/plans/index.js.map +1 -0
- package/dist/modules/plans/repository.d.ts +49 -0
- package/dist/modules/plans/repository.d.ts.map +1 -0
- package/dist/modules/plans/repository.js +94 -0
- package/dist/modules/plans/repository.js.map +1 -0
- package/dist/modules/plans/routes.d.ts +46 -0
- package/dist/modules/plans/routes.d.ts.map +1 -0
- package/dist/modules/plans/routes.js +152 -0
- package/dist/modules/plans/routes.js.map +1 -0
- package/dist/modules/plans/schema.d.ts +209 -0
- package/dist/modules/plans/schema.d.ts.map +1 -0
- package/dist/modules/plans/schema.js +37 -0
- package/dist/modules/plans/schema.js.map +1 -0
- package/dist/modules/plans/service.d.ts +57 -0
- package/dist/modules/plans/service.d.ts.map +1 -0
- package/dist/modules/plans/service.js +125 -0
- package/dist/modules/plans/service.js.map +1 -0
- package/dist/modules/plans/tools.d.ts +4 -0
- package/dist/modules/plans/tools.d.ts.map +1 -0
- package/dist/modules/plans/tools.js +39 -0
- package/dist/modules/plans/tools.js.map +1 -0
- package/dist/modules/positions/index.d.ts +9 -0
- package/dist/modules/positions/index.d.ts.map +1 -0
- package/dist/modules/positions/index.js +36 -0
- package/dist/modules/positions/index.js.map +1 -0
- package/dist/modules/positions/repository.d.ts +34 -0
- package/dist/modules/positions/repository.d.ts.map +1 -0
- package/dist/modules/positions/repository.js +71 -0
- package/dist/modules/positions/repository.js.map +1 -0
- package/dist/modules/positions/routes.d.ts +22 -0
- package/dist/modules/positions/routes.d.ts.map +1 -0
- package/dist/modules/positions/routes.js +56 -0
- package/dist/modules/positions/routes.js.map +1 -0
- package/dist/modules/positions/schema.d.ts +154 -0
- package/dist/modules/positions/schema.d.ts.map +1 -0
- package/dist/modules/positions/schema.js +36 -0
- package/dist/modules/positions/schema.js.map +1 -0
- package/dist/modules/positions/service.d.ts +46 -0
- package/dist/modules/positions/service.d.ts.map +1 -0
- package/dist/modules/positions/service.js +159 -0
- package/dist/modules/positions/service.js.map +1 -0
- package/dist/modules/positions/tools.d.ts +4 -0
- package/dist/modules/positions/tools.d.ts.map +1 -0
- package/dist/modules/positions/tools.js +26 -0
- package/dist/modules/positions/tools.js.map +1 -0
- package/dist/modules/raises/index.d.ts +11 -0
- package/dist/modules/raises/index.d.ts.map +1 -0
- package/dist/modules/raises/index.js +38 -0
- package/dist/modules/raises/index.js.map +1 -0
- package/dist/modules/raises/repository.d.ts +48 -0
- package/dist/modules/raises/repository.d.ts.map +1 -0
- package/dist/modules/raises/repository.js +164 -0
- package/dist/modules/raises/repository.js.map +1 -0
- package/dist/modules/raises/routes.d.ts +48 -0
- package/dist/modules/raises/routes.d.ts.map +1 -0
- package/dist/modules/raises/routes.js +126 -0
- package/dist/modules/raises/routes.js.map +1 -0
- package/dist/modules/raises/schema.d.ts +356 -0
- package/dist/modules/raises/schema.d.ts.map +1 -0
- package/dist/modules/raises/schema.js +55 -0
- package/dist/modules/raises/schema.js.map +1 -0
- package/dist/modules/raises/service.d.ts +79 -0
- package/dist/modules/raises/service.d.ts.map +1 -0
- package/dist/modules/raises/service.js +275 -0
- package/dist/modules/raises/service.js.map +1 -0
- package/dist/modules/raises/tools.d.ts +4 -0
- package/dist/modules/raises/tools.d.ts.map +1 -0
- package/dist/modules/raises/tools.js +33 -0
- package/dist/modules/raises/tools.js.map +1 -0
- package/dist/modules/recordTargets.d.ts +55 -0
- package/dist/modules/recordTargets.d.ts.map +1 -0
- package/dist/modules/recordTargets.js +107 -0
- package/dist/modules/recordTargets.js.map +1 -0
- package/dist/modules/references.d.ts +8 -0
- package/dist/modules/references.d.ts.map +1 -0
- package/dist/modules/references.js +40 -0
- package/dist/modules/references.js.map +1 -0
- package/dist/modules/reseal.d.ts +33 -0
- package/dist/modules/reseal.d.ts.map +1 -0
- package/dist/modules/reseal.js +108 -0
- package/dist/modules/reseal.js.map +1 -0
- package/dist/modules/search/index.d.ts +21 -0
- package/dist/modules/search/index.d.ts.map +1 -0
- package/dist/modules/search/index.js +50 -0
- package/dist/modules/search/index.js.map +1 -0
- package/dist/modules/search/query.d.ts +44 -0
- package/dist/modules/search/query.d.ts.map +1 -0
- package/dist/modules/search/query.js +88 -0
- package/dist/modules/search/query.js.map +1 -0
- package/dist/modules/search/repository.d.ts +44 -0
- package/dist/modules/search/repository.d.ts.map +1 -0
- package/dist/modules/search/repository.js +252 -0
- package/dist/modules/search/repository.js.map +1 -0
- package/dist/modules/search/routes.d.ts +17 -0
- package/dist/modules/search/routes.d.ts.map +1 -0
- package/dist/modules/search/routes.js +93 -0
- package/dist/modules/search/routes.js.map +1 -0
- package/dist/modules/search/service.d.ts +55 -0
- package/dist/modules/search/service.d.ts.map +1 -0
- package/dist/modules/search/service.js +69 -0
- package/dist/modules/search/service.js.map +1 -0
- package/dist/modules/search/tools.d.ts +4 -0
- package/dist/modules/search/tools.d.ts.map +1 -0
- package/dist/modules/search/tools.js +52 -0
- package/dist/modules/search/tools.js.map +1 -0
- package/dist/modules/stagedRecords.d.ts +28 -0
- package/dist/modules/stagedRecords.d.ts.map +1 -0
- package/dist/modules/stagedRecords.js +50 -0
- package/dist/modules/stagedRecords.js.map +1 -0
- package/dist/modules/webhooks/delivery.d.ts +98 -0
- package/dist/modules/webhooks/delivery.d.ts.map +1 -0
- package/dist/modules/webhooks/delivery.js +237 -0
- package/dist/modules/webhooks/delivery.js.map +1 -0
- package/dist/modules/webhooks/index.d.ts +23 -0
- package/dist/modules/webhooks/index.d.ts.map +1 -0
- package/dist/modules/webhooks/index.js +48 -0
- package/dist/modules/webhooks/index.js.map +1 -0
- package/dist/modules/webhooks/payloads.d.ts +31 -0
- package/dist/modules/webhooks/payloads.d.ts.map +1 -0
- package/dist/modules/webhooks/payloads.js +52 -0
- package/dist/modules/webhooks/payloads.js.map +1 -0
- package/dist/modules/webhooks/repository.d.ts +70 -0
- package/dist/modules/webhooks/repository.d.ts.map +1 -0
- package/dist/modules/webhooks/repository.js +140 -0
- package/dist/modules/webhooks/repository.js.map +1 -0
- package/dist/modules/webhooks/routes.d.ts +47 -0
- package/dist/modules/webhooks/routes.d.ts.map +1 -0
- package/dist/modules/webhooks/routes.js +170 -0
- package/dist/modules/webhooks/routes.js.map +1 -0
- package/dist/modules/webhooks/schema.d.ts +396 -0
- package/dist/modules/webhooks/schema.d.ts.map +1 -0
- package/dist/modules/webhooks/schema.js +61 -0
- package/dist/modules/webhooks/schema.js.map +1 -0
- package/dist/modules/webhooks/service.d.ts +65 -0
- package/dist/modules/webhooks/service.d.ts.map +1 -0
- package/dist/modules/webhooks/service.js +202 -0
- package/dist/modules/webhooks/service.js.map +1 -0
- package/dist/modules/webhooks/signing.d.ts +57 -0
- package/dist/modules/webhooks/signing.d.ts.map +1 -0
- package/dist/modules/webhooks/signing.js +69 -0
- package/dist/modules/webhooks/signing.js.map +1 -0
- package/dist/modules/webhooks/tools.d.ts +4 -0
- package/dist/modules/webhooks/tools.d.ts.map +1 -0
- package/dist/modules/webhooks/tools.js +77 -0
- package/dist/modules/webhooks/tools.js.map +1 -0
- package/dist/modules/webhooks/url.d.ts +10 -0
- package/dist/modules/webhooks/url.d.ts.map +1 -0
- package/dist/modules/webhooks/url.js +9 -0
- package/dist/modules/webhooks/url.js.map +1 -0
- package/dist/modules/workspace/capabilities.d.ts +9 -0
- package/dist/modules/workspace/capabilities.d.ts.map +1 -0
- package/dist/modules/workspace/capabilities.js +12 -0
- package/dist/modules/workspace/capabilities.js.map +1 -0
- package/dist/modules/workspace/idempotencyMiddleware.d.ts +16 -0
- package/dist/modules/workspace/idempotencyMiddleware.d.ts.map +1 -0
- package/dist/modules/workspace/idempotencyMiddleware.js +142 -0
- package/dist/modules/workspace/idempotencyMiddleware.js.map +1 -0
- package/dist/modules/workspace/idempotencyRepository.d.ts +43 -0
- package/dist/modules/workspace/idempotencyRepository.d.ts.map +1 -0
- package/dist/modules/workspace/idempotencyRepository.js +75 -0
- package/dist/modules/workspace/idempotencyRepository.js.map +1 -0
- package/dist/modules/workspace/index.d.ts +9 -0
- package/dist/modules/workspace/index.d.ts.map +1 -0
- package/dist/modules/workspace/index.js +53 -0
- package/dist/modules/workspace/index.js.map +1 -0
- package/dist/modules/workspace/repository.d.ts +112 -0
- package/dist/modules/workspace/repository.d.ts.map +1 -0
- package/dist/modules/workspace/repository.js +266 -0
- package/dist/modules/workspace/repository.js.map +1 -0
- package/dist/modules/workspace/roles.d.ts +22 -0
- package/dist/modules/workspace/roles.d.ts.map +1 -0
- package/dist/modules/workspace/roles.js +31 -0
- package/dist/modules/workspace/roles.js.map +1 -0
- package/dist/modules/workspace/routes.d.ts +41 -0
- package/dist/modules/workspace/routes.d.ts.map +1 -0
- package/dist/modules/workspace/routes.js +158 -0
- package/dist/modules/workspace/routes.js.map +1 -0
- package/dist/modules/workspace/schema.d.ts +719 -0
- package/dist/modules/workspace/schema.d.ts.map +1 -0
- package/dist/modules/workspace/schema.js +102 -0
- package/dist/modules/workspace/schema.js.map +1 -0
- package/dist/modules/workspace/service.d.ts +94 -0
- package/dist/modules/workspace/service.d.ts.map +1 -0
- package/dist/modules/workspace/service.js +528 -0
- package/dist/modules/workspace/service.js.map +1 -0
- package/dist/modules/workspace/starters.d.ts +22 -0
- package/dist/modules/workspace/starters.d.ts.map +1 -0
- package/dist/modules/workspace/starters.js +56 -0
- package/dist/modules/workspace/starters.js.map +1 -0
- package/dist/modules/workspace/tools.d.ts +4 -0
- package/dist/modules/workspace/tools.d.ts.map +1 -0
- package/dist/modules/workspace/tools.js +95 -0
- package/dist/modules/workspace/tools.js.map +1 -0
- package/dist/runtime/entitlements.d.ts +66 -0
- package/dist/runtime/entitlements.d.ts.map +1 -0
- package/dist/runtime/entitlements.js +62 -0
- package/dist/runtime/entitlements.js.map +1 -0
- package/dist/runtime/events.d.ts +139 -0
- package/dist/runtime/events.d.ts.map +1 -0
- package/dist/runtime/events.js +98 -0
- package/dist/runtime/events.js.map +1 -0
- package/dist/runtime/migrate.d.ts +28 -0
- package/dist/runtime/migrate.d.ts.map +1 -0
- package/dist/runtime/migrate.js +43 -0
- package/dist/runtime/migrate.js.map +1 -0
- package/dist/runtime/module.d.ts +138 -0
- package/dist/runtime/module.d.ts.map +1 -0
- package/dist/runtime/module.js +2 -0
- package/dist/runtime/module.js.map +1 -0
- package/dist/runtime/moduleConfig.d.ts +21 -0
- package/dist/runtime/moduleConfig.d.ts.map +1 -0
- package/dist/runtime/moduleConfig.js +54 -0
- package/dist/runtime/moduleConfig.js.map +1 -0
- package/dist/runtime/order.d.ts +21 -0
- package/dist/runtime/order.d.ts.map +1 -0
- package/dist/runtime/order.js +72 -0
- package/dist/runtime/order.js.map +1 -0
- package/dist/runtime/registry.d.ts +66 -0
- package/dist/runtime/registry.d.ts.map +1 -0
- package/dist/runtime/registry.js +148 -0
- package/dist/runtime/registry.js.map +1 -0
- package/dist/runtime/transaction.d.ts +34 -0
- package/dist/runtime/transaction.d.ts.map +1 -0
- package/dist/runtime/transaction.js +24 -0
- package/dist/runtime/transaction.js.map +1 -0
- package/dist/schema/index.d.ts +30 -0
- package/dist/schema/index.d.ts.map +1 -0
- package/dist/schema/index.js +30 -0
- package/dist/schema/index.js.map +1 -0
- package/dist/testing/app.d.ts +42 -0
- package/dist/testing/app.d.ts.map +1 -0
- package/dist/testing/app.js +31 -0
- package/dist/testing/app.js.map +1 -0
- package/dist/testing/client.d.ts +34 -0
- package/dist/testing/client.d.ts.map +1 -0
- package/dist/testing/client.js +70 -0
- package/dist/testing/client.js.map +1 -0
- package/dist/testing/database.d.ts +17 -0
- package/dist/testing/database.d.ts.map +1 -0
- package/dist/testing/database.js +84 -0
- package/dist/testing/database.js.map +1 -0
- package/dist/testing/environment.d.ts +17 -0
- package/dist/testing/environment.d.ts.map +1 -0
- package/dist/testing/environment.js +19 -0
- package/dist/testing/environment.js.map +1 -0
- package/dist/testing/fixtures.d.ts +22 -0
- package/dist/testing/fixtures.d.ts.map +1 -0
- package/dist/testing/fixtures.js +55 -0
- package/dist/testing/fixtures.js.map +1 -0
- package/dist/testing/index.d.ts +10 -0
- package/dist/testing/index.d.ts.map +1 -0
- package/dist/testing/index.js +6 -0
- package/dist/testing/index.js.map +1 -0
- package/dist/testing/services.d.ts +18 -0
- package/dist/testing/services.d.ts.map +1 -0
- package/dist/testing/services.js +43 -0
- package/dist/testing/services.js.map +1 -0
- package/migrations/0000_initial_schema.sql +597 -0
- package/migrations/0001_uneven_lockjaw.sql +11 -0
- package/migrations/0002_neat_madame_web.sql +2 -0
- package/migrations/0003_bright_shockwave.sql +1 -0
- package/migrations/0004_drop_unused_import_columns.sql +2 -0
- package/migrations/0005_import_job_rows.sql +23 -0
- package/migrations/0006_drop_webhook_secret_hash.sql +1 -0
- package/migrations/0007_add_webhook_secret_encrypted.sql +1 -0
- package/migrations/0008_rich_mister_sinister.sql +3 -0
- package/migrations/0009_natural_proemial_gods.sql +1 -0
- package/migrations/0010_fine_brood.sql +1 -0
- package/migrations/0011_add_webhook_previous_secret.sql +2 -0
- package/migrations/0012_idempotency_keys_response_nullable.sql +1 -0
- package/migrations/0013_add_agent_run_failure_reason.sql +1 -0
- package/migrations/0014_right_shinko_yamashiro.sql +12 -0
- package/migrations/0015_peaceful_chimera.sql +33 -0
- package/migrations/meta/0000_snapshot.json +4467 -0
- package/migrations/meta/0001_snapshot.json +4539 -0
- package/migrations/meta/0002_snapshot.json +4539 -0
- package/migrations/meta/0003_snapshot.json +4544 -0
- package/migrations/meta/0004_snapshot.json +4531 -0
- package/migrations/meta/0005_snapshot.json +4674 -0
- package/migrations/meta/0006_snapshot.json +4668 -0
- package/migrations/meta/0007_snapshot.json +4674 -0
- package/migrations/meta/0008_snapshot.json +4694 -0
- package/migrations/meta/0009_snapshot.json +4700 -0
- package/migrations/meta/0010_snapshot.json +4694 -0
- package/migrations/meta/0011_snapshot.json +4706 -0
- package/migrations/meta/0012_snapshot.json +4706 -0
- package/migrations/meta/0013_snapshot.json +4712 -0
- package/migrations/meta/0014_snapshot.json +4802 -0
- package/migrations/meta/0015_snapshot.json +5077 -0
- package/migrations/meta/_journal.json +118 -0
- package/package.json +68 -0
- package/src/app.ts +157 -0
- package/src/index.ts +113 -0
- package/src/lib/actor.ts +99 -0
- package/src/lib/changes.ts +43 -0
- package/src/lib/columns.ts +170 -0
- package/src/lib/config.ts +86 -0
- package/src/lib/database.ts +118 -0
- package/src/lib/dates.ts +18 -0
- package/src/lib/email.ts +65 -0
- package/src/lib/errors.ts +156 -0
- package/src/lib/http.ts +109 -0
- package/src/lib/ids.ts +61 -0
- package/src/lib/logger.ts +73 -0
- package/src/lib/moduleConfig.ts +65 -0
- package/src/lib/normalisation.ts +36 -0
- package/src/lib/pagination.ts +291 -0
- package/src/lib/passwords.ts +56 -0
- package/src/lib/search.ts +29 -0
- package/src/lib/secrets.ts +223 -0
- package/src/lib/timezones.ts +59 -0
- package/src/lib/tokens.ts +37 -0
- package/src/lib/url.ts +52 -0
- package/src/modules/activities/index.ts +43 -0
- package/src/modules/activities/recorder.ts +108 -0
- package/src/modules/activities/repository.ts +196 -0
- package/src/modules/activities/routes.ts +78 -0
- package/src/modules/activities/schema.ts +41 -0
- package/src/modules/activities/service.ts +93 -0
- package/src/modules/activities/tools.ts +40 -0
- package/src/modules/activities/wording.ts +168 -0
- package/src/modules/agent-tasks/catalog.ts +712 -0
- package/src/modules/agent-tasks/dispatch.ts +188 -0
- package/src/modules/agent-tasks/index.ts +79 -0
- package/src/modules/agent-tasks/prompt.ts +140 -0
- package/src/modules/agent-tasks/repository.ts +152 -0
- package/src/modules/agent-tasks/resolve.ts +704 -0
- package/src/modules/agent-tasks/routes.ts +260 -0
- package/src/modules/agent-tasks/schema.ts +57 -0
- package/src/modules/agent-tasks/service.ts +370 -0
- package/src/modules/agent-tasks/wire.ts +61 -0
- package/src/modules/api-keys/index.ts +34 -0
- package/src/modules/api-keys/keys.ts +59 -0
- package/src/modules/api-keys/repository.ts +82 -0
- package/src/modules/api-keys/routes.ts +83 -0
- package/src/modules/api-keys/schema.ts +28 -0
- package/src/modules/api-keys/service.ts +152 -0
- package/src/modules/attachedRecords.ts +85 -0
- package/src/modules/auth/actor.ts +17 -0
- package/src/modules/auth/credentials.ts +153 -0
- package/src/modules/auth/index.ts +49 -0
- package/src/modules/auth/preferences.ts +57 -0
- package/src/modules/auth/repository.ts +240 -0
- package/src/modules/auth/routes.ts +247 -0
- package/src/modules/auth/schema.ts +77 -0
- package/src/modules/auth/service.ts +441 -0
- package/src/modules/auth/session.ts +40 -0
- package/src/modules/companies/index.ts +43 -0
- package/src/modules/companies/repository.ts +185 -0
- package/src/modules/companies/routes.ts +170 -0
- package/src/modules/companies/schema.ts +66 -0
- package/src/modules/companies/service.ts +267 -0
- package/src/modules/companies/tools.ts +32 -0
- package/src/modules/core.ts +93 -0
- package/src/modules/crudTools.ts +226 -0
- package/src/modules/dashboard/attention.ts +67 -0
- package/src/modules/dashboard/index.ts +49 -0
- package/src/modules/dashboard/repository.ts +360 -0
- package/src/modules/dashboard/routes.ts +171 -0
- package/src/modules/dashboard/service.ts +449 -0
- package/src/modules/dashboard/tools.ts +39 -0
- package/src/modules/deals/index.ts +44 -0
- package/src/modules/deals/repository.ts +251 -0
- package/src/modules/deals/routes.ts +166 -0
- package/src/modules/deals/schema.ts +72 -0
- package/src/modules/deals/service.ts +433 -0
- package/src/modules/deals/tools.ts +39 -0
- package/src/modules/decisions/index.ts +40 -0
- package/src/modules/decisions/repository.ts +204 -0
- package/src/modules/decisions/routes.ts +184 -0
- package/src/modules/decisions/schema.ts +56 -0
- package/src/modules/decisions/service.ts +223 -0
- package/src/modules/decisions/tools.ts +38 -0
- package/src/modules/forms/embed.ts +274 -0
- package/src/modules/forms/fields.ts +206 -0
- package/src/modules/forms/index.ts +61 -0
- package/src/modules/forms/mapping.ts +222 -0
- package/src/modules/forms/publicRoutes.ts +92 -0
- package/src/modules/forms/repository.ts +223 -0
- package/src/modules/forms/routes.ts +276 -0
- package/src/modules/forms/schema.ts +135 -0
- package/src/modules/forms/service.ts +362 -0
- package/src/modules/forms/submission.ts +496 -0
- package/src/modules/forms/tools.ts +66 -0
- package/src/modules/handbook/index.ts +43 -0
- package/src/modules/handbook/repository.ts +173 -0
- package/src/modules/handbook/routes.ts +145 -0
- package/src/modules/handbook/schema.ts +43 -0
- package/src/modules/handbook/service.ts +399 -0
- package/src/modules/handbook/slugs.ts +54 -0
- package/src/modules/handbook/tools.ts +32 -0
- package/src/modules/handbook/tree.ts +158 -0
- package/src/modules/hiring/candidates.ts +391 -0
- package/src/modules/hiring/index.ts +55 -0
- package/src/modules/hiring/repository.ts +244 -0
- package/src/modules/hiring/roles.ts +174 -0
- package/src/modules/hiring/routes.ts +257 -0
- package/src/modules/hiring/schema.ts +93 -0
- package/src/modules/hiring/tools.ts +73 -0
- package/src/modules/import-export/csv.ts +180 -0
- package/src/modules/import-export/drafts.ts +182 -0
- package/src/modules/import-export/exportRows.ts +85 -0
- package/src/modules/import-export/index.ts +49 -0
- package/src/modules/import-export/mapping.ts +154 -0
- package/src/modules/import-export/plan.ts +311 -0
- package/src/modules/import-export/presets.ts +183 -0
- package/src/modules/import-export/repository.ts +603 -0
- package/src/modules/import-export/routes.ts +276 -0
- package/src/modules/import-export/schema.ts +142 -0
- package/src/modules/import-export/service.ts +842 -0
- package/src/modules/import-export/streams.ts +98 -0
- package/src/modules/import-export/tools.ts +153 -0
- package/src/modules/import-export/validation.ts +163 -0
- package/src/modules/import-export/writes.ts +365 -0
- package/src/modules/integrations/schema.ts +31 -0
- package/src/modules/mcp/index.ts +52 -0
- package/src/modules/mcp/protocol.ts +442 -0
- package/src/modules/mcp/router.ts +425 -0
- package/src/modules/notes/index.ts +43 -0
- package/src/modules/notes/repository.ts +130 -0
- package/src/modules/notes/routes.ts +170 -0
- package/src/modules/notes/schema.ts +42 -0
- package/src/modules/notes/service.ts +204 -0
- package/src/modules/notes/tools.ts +46 -0
- package/src/modules/opportunities/index.ts +44 -0
- package/src/modules/opportunities/repository.ts +157 -0
- package/src/modules/opportunities/routes.ts +152 -0
- package/src/modules/opportunities/schema.ts +47 -0
- package/src/modules/opportunities/service.ts +342 -0
- package/src/modules/opportunities/tools.ts +39 -0
- package/src/modules/partnerships/index.ts +44 -0
- package/src/modules/partnerships/repository.ts +274 -0
- package/src/modules/partnerships/routes.ts +170 -0
- package/src/modules/partnerships/schema.ts +65 -0
- package/src/modules/partnerships/service.ts +442 -0
- package/src/modules/partnerships/tools.ts +41 -0
- package/src/modules/people/index.ts +43 -0
- package/src/modules/people/repository.ts +167 -0
- package/src/modules/people/routes.ts +175 -0
- package/src/modules/people/schema.ts +89 -0
- package/src/modules/people/service.ts +284 -0
- package/src/modules/people/tools.ts +32 -0
- package/src/modules/pipelines/index.ts +43 -0
- package/src/modules/pipelines/repository.ts +116 -0
- package/src/modules/pipelines/routes.ts +157 -0
- package/src/modules/pipelines/schema.ts +37 -0
- package/src/modules/pipelines/service.ts +339 -0
- package/src/modules/pipelines/tools.ts +52 -0
- package/src/modules/plans/index.ts +39 -0
- package/src/modules/plans/repository.ts +174 -0
- package/src/modules/plans/routes.ts +212 -0
- package/src/modules/plans/schema.ts +45 -0
- package/src/modules/plans/service.ts +223 -0
- package/src/modules/plans/tools.ts +45 -0
- package/src/modules/positions/index.ts +42 -0
- package/src/modules/positions/repository.ts +136 -0
- package/src/modules/positions/routes.ts +97 -0
- package/src/modules/positions/schema.ts +42 -0
- package/src/modules/positions/service.ts +253 -0
- package/src/modules/positions/tools.ts +32 -0
- package/src/modules/raises/index.ts +44 -0
- package/src/modules/raises/repository.ts +254 -0
- package/src/modules/raises/routes.ts +160 -0
- package/src/modules/raises/schema.ts +66 -0
- package/src/modules/raises/service.ts +442 -0
- package/src/modules/raises/tools.ts +39 -0
- package/src/modules/recordTargets.ts +194 -0
- package/src/modules/references.ts +44 -0
- package/src/modules/reseal.ts +178 -0
- package/src/modules/search/index.ts +55 -0
- package/src/modules/search/query.ts +104 -0
- package/src/modules/search/repository.ts +388 -0
- package/src/modules/search/routes.ts +131 -0
- package/src/modules/search/service.ts +153 -0
- package/src/modules/search/tools.ts +60 -0
- package/src/modules/stagedRecords.ts +91 -0
- package/src/modules/webhooks/delivery.ts +349 -0
- package/src/modules/webhooks/index.ts +85 -0
- package/src/modules/webhooks/payloads.ts +84 -0
- package/src/modules/webhooks/repository.ts +244 -0
- package/src/modules/webhooks/routes.ts +240 -0
- package/src/modules/webhooks/schema.ts +78 -0
- package/src/modules/webhooks/service.ts +347 -0
- package/src/modules/webhooks/signing.ts +95 -0
- package/src/modules/webhooks/tools.ts +108 -0
- package/src/modules/webhooks/url.ts +21 -0
- package/src/modules/workspace/capabilities.ts +14 -0
- package/src/modules/workspace/idempotencyMiddleware.ts +207 -0
- package/src/modules/workspace/idempotencyRepository.ts +111 -0
- package/src/modules/workspace/index.ts +64 -0
- package/src/modules/workspace/repository.ts +420 -0
- package/src/modules/workspace/roles.ts +38 -0
- package/src/modules/workspace/routes.ts +255 -0
- package/src/modules/workspace/schema.ts +130 -0
- package/src/modules/workspace/service.ts +798 -0
- package/src/modules/workspace/starters.ts +69 -0
- package/src/modules/workspace/tools.ts +141 -0
- package/src/runtime/entitlements.ts +142 -0
- package/src/runtime/events.ts +185 -0
- package/src/runtime/migrate.ts +75 -0
- package/src/runtime/module.ts +147 -0
- package/src/runtime/moduleConfig.ts +68 -0
- package/src/runtime/order.ts +90 -0
- package/src/runtime/registry.ts +263 -0
- package/src/runtime/transaction.ts +80 -0
- package/src/schema/index.ts +30 -0
- package/src/testing/app.ts +79 -0
- package/src/testing/client.ts +118 -0
- package/src/testing/database.ts +106 -0
- package/src/testing/environment.ts +22 -0
- package/src/testing/fixtures.ts +70 -0
- package/src/testing/index.ts +13 -0
- package/src/testing/services.ts +67 -0
|
@@ -0,0 +1,798 @@
|
|
|
1
|
+
import { UNIQUE_VIOLATION, isReferenceViolation, postgresErrorCode } from '../../lib/database.ts'
|
|
2
|
+
import type { Database } from '../../lib/database.ts'
|
|
3
|
+
import type { EmailSender } from '../../lib/email.ts'
|
|
4
|
+
import { AppError } from '../../lib/errors.ts'
|
|
5
|
+
import type { IdFactory } from '../../lib/ids.ts'
|
|
6
|
+
import { generateToken, hashToken } from '../../lib/tokens.ts'
|
|
7
|
+
import type { EntitlementRegistry } from '../../runtime/entitlements.ts'
|
|
8
|
+
import { limitFor } from '../../runtime/entitlements.ts'
|
|
9
|
+
import { moduleCapabilityName } from '../../runtime/moduleConfig.ts'
|
|
10
|
+
import type { TransactionScope } from '../../runtime/transaction.ts'
|
|
11
|
+
import type { Actor, SessionActor } from '../auth/actor.ts'
|
|
12
|
+
import * as authRepository from '../auth/repository.ts'
|
|
13
|
+
import { SEATS_LIMIT } from './capabilities.ts'
|
|
14
|
+
import * as repository from './repository.ts'
|
|
15
|
+
import { parseInvitableRole, parseMemberRole, roleAllows } from './roles.ts'
|
|
16
|
+
import type { InvitableRole, InviteStatus, MemberRole } from './roles.ts'
|
|
17
|
+
import {
|
|
18
|
+
STARTER_HANDBOOK_PAGES,
|
|
19
|
+
STARTER_PIPELINE_STAGES,
|
|
20
|
+
starterHandbookBody,
|
|
21
|
+
} from './starters.ts'
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* Workspaces and who belongs to them.
|
|
25
|
+
*
|
|
26
|
+
* Creating a workspace is the only place a member row appears without an invite,
|
|
27
|
+
* and it is what turns a bare account into something that can hold data.
|
|
28
|
+
*/
|
|
29
|
+
|
|
30
|
+
const INVITE_LIFETIME_MS = 7 * 24 * 60 * 60 * 1000
|
|
31
|
+
|
|
32
|
+
export interface WorkspaceDependencies {
|
|
33
|
+
readonly db: Database
|
|
34
|
+
readonly transaction: TransactionScope
|
|
35
|
+
readonly email: EmailSender
|
|
36
|
+
readonly createId: IdFactory
|
|
37
|
+
readonly now: () => Date
|
|
38
|
+
readonly entitlements: EntitlementRegistry
|
|
39
|
+
readonly newToken?: () => string
|
|
40
|
+
/** Every non-structural module id (`runtime/module.ts`'s `moduleCatalog`), in assembly order. */
|
|
41
|
+
readonly toggleableModuleIds: readonly string[]
|
|
42
|
+
/** The deploy-time module override, if this deployment has one. */
|
|
43
|
+
readonly moduleConfigOverrides: Readonly<Record<string, boolean>> | undefined
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
export interface WorkspaceView {
|
|
47
|
+
readonly id: string
|
|
48
|
+
readonly name: string
|
|
49
|
+
readonly slug: string
|
|
50
|
+
readonly timezone: string
|
|
51
|
+
readonly tagline: string | null
|
|
52
|
+
readonly oneLiner: string | null
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
export interface MemberView {
|
|
56
|
+
readonly id: string
|
|
57
|
+
readonly userId: string
|
|
58
|
+
readonly role: MemberRole
|
|
59
|
+
readonly joinedAt: Date
|
|
60
|
+
readonly name: string
|
|
61
|
+
readonly email: string
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
export interface InviteView {
|
|
65
|
+
readonly id: string
|
|
66
|
+
readonly email: string
|
|
67
|
+
readonly role: InvitableRole
|
|
68
|
+
readonly status: InviteStatus
|
|
69
|
+
readonly expiresAt: Date
|
|
70
|
+
readonly createdAt: Date
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
export interface ModuleSettingView {
|
|
74
|
+
readonly moduleId: string
|
|
75
|
+
readonly enabled: boolean
|
|
76
|
+
/** True when a deploy-time config file holds this module's value, not the workspace's own choice. */
|
|
77
|
+
readonly locked: boolean
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
export interface CreateWorkspaceInput {
|
|
81
|
+
readonly name: string
|
|
82
|
+
readonly slug: string
|
|
83
|
+
readonly timezone: string
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
export interface UpdateWorkspaceInput {
|
|
87
|
+
readonly name?: string
|
|
88
|
+
readonly slug?: string
|
|
89
|
+
readonly timezone?: string
|
|
90
|
+
readonly tagline?: string | null
|
|
91
|
+
readonly oneLiner?: string | null
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
export interface WorkspaceService {
|
|
95
|
+
/** Creates the workspace, makes the caller its owner, and seeds its starters. */
|
|
96
|
+
create(actor: SessionActor, input: CreateWorkspaceInput): Promise<WorkspaceView>
|
|
97
|
+
get(actor: Actor, workspaceId: string): Promise<WorkspaceView>
|
|
98
|
+
update(actor: Actor, workspaceId: string, changes: UpdateWorkspaceInput): Promise<WorkspaceView>
|
|
99
|
+
/**
|
|
100
|
+
* Deletes the workspace and everything in it.
|
|
101
|
+
*
|
|
102
|
+
* @param confirmSlug The workspace's own slug. The caller has to name what it
|
|
103
|
+
* is destroying, so an unintended `DELETE` at the right id does nothing.
|
|
104
|
+
*/
|
|
105
|
+
remove(actor: Actor, workspaceId: string, confirmSlug: string): Promise<void>
|
|
106
|
+
listMembers(actor: Actor, workspaceId: string): Promise<readonly MemberView[]>
|
|
107
|
+
/** Changes a member's role, or transfers ownership when `role` is `owner`. */
|
|
108
|
+
setMemberRole(actor: Actor, workspaceId: string, memberId: string, role: MemberRole): Promise<MemberView>
|
|
109
|
+
removeMember(actor: Actor, workspaceId: string, memberId: string): Promise<void>
|
|
110
|
+
invite(actor: Actor, workspaceId: string, email: string, role: InvitableRole, urlTemplate: string): Promise<InviteView>
|
|
111
|
+
listInvites(actor: Actor, workspaceId: string): Promise<readonly InviteView[]>
|
|
112
|
+
/** Issues a fresh token and expiry for an invitation, and emails it again. */
|
|
113
|
+
resendInvite(actor: Actor, workspaceId: string, inviteId: string, urlTemplate: string): Promise<InviteView>
|
|
114
|
+
revokeInvite(actor: Actor, workspaceId: string, inviteId: string): Promise<void>
|
|
115
|
+
/** Joins the invited workspace as the calling account. */
|
|
116
|
+
acceptInvite(actor: SessionActor, token: string): Promise<WorkspaceView>
|
|
117
|
+
listModuleSettings(actor: Actor, workspaceId: string): Promise<readonly ModuleSettingView[]>
|
|
118
|
+
/**
|
|
119
|
+
* @throws AppError 'not_found' for a structural or unknown module id.
|
|
120
|
+
* @throws AppError 'conflict' when a deploy-time config file locks this module.
|
|
121
|
+
*/
|
|
122
|
+
setModuleEnabled(actor: Actor, workspaceId: string, moduleId: string, enabled: boolean): Promise<ModuleSettingView>
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
function toWorkspaceView(record: repository.WorkspaceRecord): WorkspaceView {
|
|
126
|
+
return {
|
|
127
|
+
id: record.id,
|
|
128
|
+
name: record.name,
|
|
129
|
+
slug: record.slug,
|
|
130
|
+
timezone: record.timezone,
|
|
131
|
+
tagline: record.tagline,
|
|
132
|
+
oneLiner: record.oneLiner,
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
/**
|
|
137
|
+
* An invitation as a reader sees it.
|
|
138
|
+
*
|
|
139
|
+
* `status` is computed from `expires_at` rather than read from the column.
|
|
140
|
+
* Expiry is a function of the clock, so a stored value would only be true until
|
|
141
|
+
* the moment it passed, and keeping it true would mean a sweeper. `acceptInvite`
|
|
142
|
+
* already decides the same way, and this keeps the list agreeing with it.
|
|
143
|
+
*/
|
|
144
|
+
function toInviteView(record: repository.InviteRecord, now: Date): InviteView {
|
|
145
|
+
const role = parseInvitableRole(record.role)
|
|
146
|
+
|
|
147
|
+
if (role === undefined) {
|
|
148
|
+
throw new Error(`invites.role holds "${record.role}", which its check constraint forbids`)
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
return {
|
|
152
|
+
id: record.id,
|
|
153
|
+
email: record.email,
|
|
154
|
+
role,
|
|
155
|
+
status: record.expiresAt > now ? 'pending' : 'expired',
|
|
156
|
+
expiresAt: record.expiresAt,
|
|
157
|
+
createdAt: record.createdAt,
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
function toMemberView(record: repository.MemberWithUser): MemberView {
|
|
162
|
+
const role = parseMemberRole(record.role)
|
|
163
|
+
|
|
164
|
+
if (role === undefined) {
|
|
165
|
+
throw new Error(`workspace_members.role holds "${record.role}", which its check forbids`)
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
return {
|
|
169
|
+
id: record.id,
|
|
170
|
+
userId: record.userId,
|
|
171
|
+
role,
|
|
172
|
+
joinedAt: record.joinedAt,
|
|
173
|
+
name: record.name,
|
|
174
|
+
email: record.email,
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
export function createWorkspaceService(dependencies: WorkspaceDependencies): WorkspaceService {
|
|
179
|
+
const newToken = dependencies.newToken ?? generateToken
|
|
180
|
+
|
|
181
|
+
/**
|
|
182
|
+
* A workspace the actor does not belong to is indistinguishable from one that
|
|
183
|
+
* does not exist, per `api.md`.
|
|
184
|
+
*
|
|
185
|
+
* A workspace key has no member row: it is bound to its workspace at creation,
|
|
186
|
+
* and that binding is the membership. `memberId` is null for it, so anything
|
|
187
|
+
* needing a member to attribute the action to must say so.
|
|
188
|
+
*/
|
|
189
|
+
async function requireMembership(
|
|
190
|
+
actor: Actor,
|
|
191
|
+
workspaceId: string,
|
|
192
|
+
required: MemberRole,
|
|
193
|
+
): Promise<{ memberId: string | null; role: MemberRole }> {
|
|
194
|
+
if (actor.kind === 'api_key') {
|
|
195
|
+
if (actor.workspaceId !== workspaceId) {
|
|
196
|
+
throw AppError.notFound('Workspace not found')
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
if (actor.userId === null) {
|
|
200
|
+
if (!roleAllows(actor.role, required)) {
|
|
201
|
+
throw new AppError('forbidden', `This action needs the ${required} role`)
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
return { memberId: null, role: actor.role }
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
return membershipFor(actor.userId, workspaceId, required)
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
return membershipFor(actor.userId, workspaceId, required)
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
async function membershipFor(
|
|
214
|
+
userId: string,
|
|
215
|
+
workspaceId: string,
|
|
216
|
+
required: MemberRole,
|
|
217
|
+
): Promise<{ memberId: string; role: MemberRole }> {
|
|
218
|
+
const membership = await authRepository.findMembership(dependencies.db, workspaceId, userId)
|
|
219
|
+
|
|
220
|
+
if (membership === undefined) {
|
|
221
|
+
throw AppError.notFound('Workspace not found')
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
const role = parseMemberRole(membership.role)
|
|
225
|
+
|
|
226
|
+
if (role === undefined) {
|
|
227
|
+
throw new Error(`workspace_members.role holds "${membership.role}", which its check forbids`)
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
if (!roleAllows(role, required)) {
|
|
231
|
+
throw new AppError('forbidden', `This action needs the ${required} role`)
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
return { memberId: membership.id, role }
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
/**
|
|
238
|
+
* Refuses a new invitation once the workspace is at its seat limit.
|
|
239
|
+
*
|
|
240
|
+
* Open source has no grant provider, so the limit is null and this never
|
|
241
|
+
* refuses. The cloud billing module is what makes it bite.
|
|
242
|
+
*/
|
|
243
|
+
async function requireSeat(workspaceId: string): Promise<void> {
|
|
244
|
+
const limit = await limitFor(dependencies.entitlements, workspaceId, SEATS_LIMIT.name)
|
|
245
|
+
|
|
246
|
+
if (limit === null) {
|
|
247
|
+
return
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
const inUse = await repository.countSeatsInUse(dependencies.db, workspaceId, dependencies.now())
|
|
251
|
+
|
|
252
|
+
if (inUse >= limit) {
|
|
253
|
+
throw new AppError(
|
|
254
|
+
'entitlement_required',
|
|
255
|
+
`This workspace has ${String(limit)} seats and all of them are taken`,
|
|
256
|
+
)
|
|
257
|
+
}
|
|
258
|
+
}
|
|
259
|
+
|
|
260
|
+
/**
|
|
261
|
+
* Refuses an address that already belongs to a member of this workspace.
|
|
262
|
+
*
|
|
263
|
+
* The question has to be asked through `users`, because membership is held by
|
|
264
|
+
* account and an account is identified by its address; `invites` has never met
|
|
265
|
+
* the member. Without this the Team page lists one person twice, once as a
|
|
266
|
+
* member and once as an invitation whose emailed link works right up until an
|
|
267
|
+
* accept that can only ever fail.
|
|
268
|
+
*/
|
|
269
|
+
async function requireStranger(workspaceId: string, address: string): Promise<void> {
|
|
270
|
+
const user = await authRepository.findUserByEmail(dependencies.db, address)
|
|
271
|
+
|
|
272
|
+
if (user === undefined) {
|
|
273
|
+
return
|
|
274
|
+
}
|
|
275
|
+
|
|
276
|
+
const membership = await authRepository.findMembership(dependencies.db, workspaceId, user.id)
|
|
277
|
+
|
|
278
|
+
if (membership !== undefined) {
|
|
279
|
+
throw AppError.conflict('That address already belongs to a member of this workspace', [
|
|
280
|
+
{ field: 'email', message: 'Already a member' },
|
|
281
|
+
])
|
|
282
|
+
}
|
|
283
|
+
}
|
|
284
|
+
|
|
285
|
+
/**
|
|
286
|
+
* The membership being acted on.
|
|
287
|
+
*
|
|
288
|
+
* A member of another workspace is not found rather than forbidden, for the
|
|
289
|
+
* same reason `api.md` gives for records: an id that answers differently when
|
|
290
|
+
* it exists elsewhere tells the caller it exists elsewhere.
|
|
291
|
+
*/
|
|
292
|
+
async function requireTarget(workspaceId: string, memberId: string): Promise<repository.MemberRecord> {
|
|
293
|
+
const target = await repository.findMember(dependencies.db, workspaceId, memberId)
|
|
294
|
+
|
|
295
|
+
if (target === undefined) {
|
|
296
|
+
throw AppError.notFound('Member not found')
|
|
297
|
+
}
|
|
298
|
+
|
|
299
|
+
return target
|
|
300
|
+
}
|
|
301
|
+
|
|
302
|
+
function sendInviteEmail(to: string, token: string, urlTemplate: string): Promise<void> {
|
|
303
|
+
return dependencies.email.send({
|
|
304
|
+
to,
|
|
305
|
+
subject: 'You have been invited to a Kelpie workspace',
|
|
306
|
+
body: `Accept the invitation within seven days:\n\n${urlTemplate.replace('{token}', token)}`,
|
|
307
|
+
})
|
|
308
|
+
}
|
|
309
|
+
|
|
310
|
+
/** The same membership with the name and email a reader needs, after a write. */
|
|
311
|
+
async function requireMemberWithUser(
|
|
312
|
+
workspaceId: string,
|
|
313
|
+
memberId: string,
|
|
314
|
+
): Promise<repository.MemberWithUser> {
|
|
315
|
+
const member = await repository.findMemberWithUser(dependencies.db, workspaceId, memberId)
|
|
316
|
+
|
|
317
|
+
if (member === undefined) {
|
|
318
|
+
throw new Error(`Member ${memberId} has no user row, which the join makes impossible`)
|
|
319
|
+
}
|
|
320
|
+
|
|
321
|
+
return member
|
|
322
|
+
}
|
|
323
|
+
|
|
324
|
+
async function requireInvite(workspaceId: string, inviteId: string): Promise<repository.InviteRecord> {
|
|
325
|
+
const invite = await repository.findInvite(dependencies.db, workspaceId, inviteId)
|
|
326
|
+
|
|
327
|
+
if (invite === undefined) {
|
|
328
|
+
throw AppError.notFound('Invitation not found')
|
|
329
|
+
}
|
|
330
|
+
|
|
331
|
+
return invite
|
|
332
|
+
}
|
|
333
|
+
|
|
334
|
+
/**
|
|
335
|
+
* Moves ownership to `target` and leaves the outgoing owner an admin.
|
|
336
|
+
*
|
|
337
|
+
* One transaction, because a workspace with two owners or none is a state no
|
|
338
|
+
* other code is written to survive.
|
|
339
|
+
*/
|
|
340
|
+
async function transferOwnership(
|
|
341
|
+
workspaceId: string,
|
|
342
|
+
currentOwner: repository.MemberRecord,
|
|
343
|
+
target: repository.MemberRecord,
|
|
344
|
+
): Promise<repository.MemberWithUser> {
|
|
345
|
+
const now = dependencies.now()
|
|
346
|
+
|
|
347
|
+
return dependencies.transaction(async ({ tx }) => {
|
|
348
|
+
await repository.updateMemberRole(tx, currentOwner.id, 'admin', now)
|
|
349
|
+
await repository.updateMemberRole(tx, target.id, 'owner', now)
|
|
350
|
+
|
|
351
|
+
const updated = await repository.findMemberWithUser(tx, workspaceId, target.id)
|
|
352
|
+
|
|
353
|
+
if (updated === undefined) {
|
|
354
|
+
throw new Error(`Member ${target.id} vanished during an ownership transfer`)
|
|
355
|
+
}
|
|
356
|
+
|
|
357
|
+
return updated
|
|
358
|
+
})
|
|
359
|
+
}
|
|
360
|
+
|
|
361
|
+
return {
|
|
362
|
+
async create(actor, input) {
|
|
363
|
+
const now = dependencies.now()
|
|
364
|
+
const workspaceId = dependencies.createId('workspace')
|
|
365
|
+
const memberId = dependencies.createId('teamMember')
|
|
366
|
+
|
|
367
|
+
return dependencies.transaction(async ({ tx, events }) => {
|
|
368
|
+
let workspace: repository.WorkspaceRecord
|
|
369
|
+
|
|
370
|
+
try {
|
|
371
|
+
workspace = await repository.insertWorkspace(tx, {
|
|
372
|
+
id: workspaceId,
|
|
373
|
+
name: input.name,
|
|
374
|
+
slug: input.slug,
|
|
375
|
+
timezone: input.timezone,
|
|
376
|
+
})
|
|
377
|
+
} catch (error: unknown) {
|
|
378
|
+
if (postgresErrorCode(error) === UNIQUE_VIOLATION) {
|
|
379
|
+
throw AppError.conflict('That workspace address is taken', [
|
|
380
|
+
{ field: 'slug', message: 'Already in use' },
|
|
381
|
+
])
|
|
382
|
+
}
|
|
383
|
+
|
|
384
|
+
throw error
|
|
385
|
+
}
|
|
386
|
+
|
|
387
|
+
await repository.insertMember(tx, {
|
|
388
|
+
id: memberId,
|
|
389
|
+
workspaceId,
|
|
390
|
+
userId: actor.userId,
|
|
391
|
+
role: 'owner',
|
|
392
|
+
joinedAt: now,
|
|
393
|
+
})
|
|
394
|
+
|
|
395
|
+
await repository.insertHandbookPages(
|
|
396
|
+
tx,
|
|
397
|
+
STARTER_HANDBOOK_PAGES.map((page, index) => ({
|
|
398
|
+
id: dependencies.createId('handbookPage'),
|
|
399
|
+
workspaceId,
|
|
400
|
+
title: page.title,
|
|
401
|
+
slug: page.slug,
|
|
402
|
+
sortOrder: index,
|
|
403
|
+
body: starterHandbookBody(page.title),
|
|
404
|
+
updatedBy: memberId,
|
|
405
|
+
})),
|
|
406
|
+
)
|
|
407
|
+
|
|
408
|
+
await repository.insertPipelineStages(
|
|
409
|
+
tx,
|
|
410
|
+
Object.entries(STARTER_PIPELINE_STAGES).flatMap(([kind, stages]) =>
|
|
411
|
+
stages.map((stage, index) => ({
|
|
412
|
+
id: dependencies.createId('pipelineStage'),
|
|
413
|
+
workspaceId,
|
|
414
|
+
kind,
|
|
415
|
+
slug: stage.slug,
|
|
416
|
+
label: stage.label,
|
|
417
|
+
open: stage.open,
|
|
418
|
+
sortOrder: index,
|
|
419
|
+
})),
|
|
420
|
+
),
|
|
421
|
+
)
|
|
422
|
+
|
|
423
|
+
// The session that created the workspace should land in it.
|
|
424
|
+
await authRepository.setActiveWorkspace(tx, actor.sessionId, workspaceId)
|
|
425
|
+
|
|
426
|
+
events.emit('workspace.created', { workspaceId, slug: workspace.slug })
|
|
427
|
+
events.emit('member.joined', { workspaceId, memberId, userId: actor.userId })
|
|
428
|
+
|
|
429
|
+
return toWorkspaceView(workspace)
|
|
430
|
+
})
|
|
431
|
+
},
|
|
432
|
+
|
|
433
|
+
async get(actor, workspaceId) {
|
|
434
|
+
await requireMembership(actor, workspaceId, 'member')
|
|
435
|
+
const workspace = await repository.findWorkspace(dependencies.db, workspaceId)
|
|
436
|
+
|
|
437
|
+
if (workspace === undefined) {
|
|
438
|
+
throw AppError.notFound('Workspace not found')
|
|
439
|
+
}
|
|
440
|
+
|
|
441
|
+
return toWorkspaceView(workspace)
|
|
442
|
+
},
|
|
443
|
+
|
|
444
|
+
async update(actor, workspaceId, changes) {
|
|
445
|
+
await requireMembership(actor, workspaceId, 'admin')
|
|
446
|
+
|
|
447
|
+
let updated: repository.WorkspaceRecord | undefined
|
|
448
|
+
|
|
449
|
+
try {
|
|
450
|
+
updated = await repository.updateWorkspace(dependencies.db, workspaceId, {
|
|
451
|
+
...changes,
|
|
452
|
+
updatedAt: dependencies.now(),
|
|
453
|
+
})
|
|
454
|
+
} catch (error: unknown) {
|
|
455
|
+
if (postgresErrorCode(error) === UNIQUE_VIOLATION) {
|
|
456
|
+
throw AppError.conflict('That workspace address is taken', [
|
|
457
|
+
{ field: 'slug', message: 'Already in use' },
|
|
458
|
+
])
|
|
459
|
+
}
|
|
460
|
+
|
|
461
|
+
throw error
|
|
462
|
+
}
|
|
463
|
+
|
|
464
|
+
if (updated === undefined) {
|
|
465
|
+
throw AppError.notFound('Workspace not found')
|
|
466
|
+
}
|
|
467
|
+
|
|
468
|
+
return toWorkspaceView(updated)
|
|
469
|
+
},
|
|
470
|
+
|
|
471
|
+
async remove(actor, workspaceId, confirmSlug) {
|
|
472
|
+
// Owner only. A workspace key resolves as an admin and can never reach
|
|
473
|
+
// this, which is deliberate: an agent's credential does not get to end the
|
|
474
|
+
// workspace it lives in.
|
|
475
|
+
await requireMembership(actor, workspaceId, 'owner')
|
|
476
|
+
|
|
477
|
+
const workspace = await repository.findWorkspace(dependencies.db, workspaceId)
|
|
478
|
+
|
|
479
|
+
if (workspace === undefined) {
|
|
480
|
+
throw AppError.notFound('Workspace not found')
|
|
481
|
+
}
|
|
482
|
+
|
|
483
|
+
if (confirmSlug !== workspace.slug) {
|
|
484
|
+
throw AppError.validationFailed('Confirm the deletion by naming the workspace', [
|
|
485
|
+
{ field: 'slug', message: `Expected "${workspace.slug}"` },
|
|
486
|
+
])
|
|
487
|
+
}
|
|
488
|
+
|
|
489
|
+
await dependencies.transaction(async ({ tx, events }) => {
|
|
490
|
+
await repository.deleteWorkspace(tx, workspaceId)
|
|
491
|
+
|
|
492
|
+
events.emit('workspace.deleted', { workspaceId, slug: workspace.slug })
|
|
493
|
+
})
|
|
494
|
+
},
|
|
495
|
+
|
|
496
|
+
async listMembers(actor, workspaceId) {
|
|
497
|
+
await requireMembership(actor, workspaceId, 'member')
|
|
498
|
+
const records = await repository.listMembers(dependencies.db, workspaceId)
|
|
499
|
+
|
|
500
|
+
return records.map(toMemberView)
|
|
501
|
+
},
|
|
502
|
+
|
|
503
|
+
async setMemberRole(actor, workspaceId, memberId, role) {
|
|
504
|
+
const caller = await requireMembership(actor, workspaceId, 'admin')
|
|
505
|
+
const target = await requireTarget(workspaceId, memberId)
|
|
506
|
+
|
|
507
|
+
if (role === 'owner') {
|
|
508
|
+
if (caller.role !== 'owner') {
|
|
509
|
+
throw new AppError('forbidden', 'Only the owner can hand ownership to somebody else')
|
|
510
|
+
}
|
|
511
|
+
|
|
512
|
+
const currentOwner = await repository.findOwner(dependencies.db, workspaceId)
|
|
513
|
+
|
|
514
|
+
if (currentOwner === undefined) {
|
|
515
|
+
throw new Error(`Workspace ${workspaceId} has an owner-role caller but no owner row`)
|
|
516
|
+
}
|
|
517
|
+
|
|
518
|
+
if (currentOwner.id === target.id) {
|
|
519
|
+
return toMemberView(await requireMemberWithUser(workspaceId, target.id))
|
|
520
|
+
}
|
|
521
|
+
|
|
522
|
+
return toMemberView(await transferOwnership(workspaceId, currentOwner, target))
|
|
523
|
+
}
|
|
524
|
+
|
|
525
|
+
// Demoting the owner by naming their row would leave the workspace without
|
|
526
|
+
// one. Transferring is the only way ownership moves, and it fills the seat
|
|
527
|
+
// in the same write that empties it.
|
|
528
|
+
if (target.role === 'owner') {
|
|
529
|
+
throw AppError.conflict(
|
|
530
|
+
'The owner cannot be demoted. Give ownership to another member instead',
|
|
531
|
+
)
|
|
532
|
+
}
|
|
533
|
+
|
|
534
|
+
await repository.updateMemberRole(dependencies.db, target.id, role, dependencies.now())
|
|
535
|
+
|
|
536
|
+
return toMemberView(await requireMemberWithUser(workspaceId, target.id))
|
|
537
|
+
},
|
|
538
|
+
|
|
539
|
+
async removeMember(actor, workspaceId, memberId) {
|
|
540
|
+
await requireMembership(actor, workspaceId, 'admin')
|
|
541
|
+
const target = await requireTarget(workspaceId, memberId)
|
|
542
|
+
|
|
543
|
+
if (target.role === 'owner') {
|
|
544
|
+
throw AppError.conflict(
|
|
545
|
+
'The owner cannot be removed. Give ownership to another member first',
|
|
546
|
+
)
|
|
547
|
+
}
|
|
548
|
+
|
|
549
|
+
// `schema.md`: removing a member is restricted while they own records.
|
|
550
|
+
// Reported before the delete so every referencing type can be named, which
|
|
551
|
+
// is what the caller needs to know what to reassign.
|
|
552
|
+
const references = await repository.countMemberReferences(dependencies.db, target.id)
|
|
553
|
+
|
|
554
|
+
if (references.length > 0) {
|
|
555
|
+
throw AppError.conflict(
|
|
556
|
+
'This member still owns records. Reassign them first',
|
|
557
|
+
references.map((reference) => ({
|
|
558
|
+
field: reference.type,
|
|
559
|
+
message: `Owns ${String(reference.count)}`,
|
|
560
|
+
})),
|
|
561
|
+
)
|
|
562
|
+
}
|
|
563
|
+
|
|
564
|
+
try {
|
|
565
|
+
await dependencies.transaction(async ({ tx, events }) => {
|
|
566
|
+
await repository.deleteMember(tx, target.id)
|
|
567
|
+
|
|
568
|
+
events.emit('member.removed', { workspaceId, memberId: target.id, userId: target.userId })
|
|
569
|
+
})
|
|
570
|
+
} catch (error: unknown) {
|
|
571
|
+
// A record assigned to them between the count and this delete. The
|
|
572
|
+
// constraint answers the same question the count did, so the caller gets
|
|
573
|
+
// the same refusal rather than a 500; it just cannot name the type.
|
|
574
|
+
if (isReferenceViolation(error)) {
|
|
575
|
+
throw AppError.conflict('This member owns records that were assigned while removing them')
|
|
576
|
+
}
|
|
577
|
+
|
|
578
|
+
throw error
|
|
579
|
+
}
|
|
580
|
+
},
|
|
581
|
+
|
|
582
|
+
async invite(actor, workspaceId, email, role, urlTemplate) {
|
|
583
|
+
const inviter = await requireMembership(actor, workspaceId, 'admin')
|
|
584
|
+
const address = email.trim().toLowerCase()
|
|
585
|
+
const now = dependencies.now()
|
|
586
|
+
|
|
587
|
+
// Both refusals come before the seat check, so an address that could never
|
|
588
|
+
// be invited is told that rather than told the workspace is full.
|
|
589
|
+
await requireStranger(workspaceId, address)
|
|
590
|
+
|
|
591
|
+
const existing = await repository.listInvitesForEmail(dependencies.db, workspaceId, address)
|
|
592
|
+
|
|
593
|
+
// Open, not merely present: an expired invitation cannot be accepted, so
|
|
594
|
+
// refusing on one would leave an address permanently un-invitable by
|
|
595
|
+
// anyone who did not think to look for the Resend button.
|
|
596
|
+
if (existing.some((invitation) => invitation.expiresAt > now)) {
|
|
597
|
+
throw AppError.conflict('That address has already been invited to this workspace', [
|
|
598
|
+
{ field: 'email', message: 'Already invited' },
|
|
599
|
+
])
|
|
600
|
+
}
|
|
601
|
+
|
|
602
|
+
await requireSeat(workspaceId)
|
|
603
|
+
|
|
604
|
+
const token = newToken()
|
|
605
|
+
const invite = await dependencies.transaction(async ({ tx, events }) => {
|
|
606
|
+
// The expired invitations this one replaces. Kept to one row per address
|
|
607
|
+
// so the list never shows the same person twice, which is the confusion
|
|
608
|
+
// the guards above exist to remove.
|
|
609
|
+
if (existing.length > 0) {
|
|
610
|
+
await repository.deleteInvitesForEmail(tx, workspaceId, address)
|
|
611
|
+
}
|
|
612
|
+
|
|
613
|
+
const created = await repository.insertInvite(tx, {
|
|
614
|
+
id: dependencies.createId('invite'),
|
|
615
|
+
workspaceId,
|
|
616
|
+
email: address,
|
|
617
|
+
role,
|
|
618
|
+
invitedBy: inviter.memberId,
|
|
619
|
+
status: 'pending',
|
|
620
|
+
tokenHash: hashToken(token),
|
|
621
|
+
expiresAt: new Date(now.getTime() + INVITE_LIFETIME_MS),
|
|
622
|
+
})
|
|
623
|
+
|
|
624
|
+
events.emit('member.invited', { workspaceId, inviteId: created.id, email: created.email })
|
|
625
|
+
|
|
626
|
+
return created
|
|
627
|
+
})
|
|
628
|
+
|
|
629
|
+
// Sent after commit, so a rolled-back invite never reaches an inbox.
|
|
630
|
+
await sendInviteEmail(invite.email, token, urlTemplate)
|
|
631
|
+
|
|
632
|
+
return toInviteView(invite, now)
|
|
633
|
+
},
|
|
634
|
+
|
|
635
|
+
async listInvites(actor, workspaceId) {
|
|
636
|
+
await requireMembership(actor, workspaceId, 'admin')
|
|
637
|
+
const records = await repository.listInvites(dependencies.db, workspaceId)
|
|
638
|
+
const now = dependencies.now()
|
|
639
|
+
|
|
640
|
+
return records.map((record) => toInviteView(record, now))
|
|
641
|
+
},
|
|
642
|
+
|
|
643
|
+
async resendInvite(actor, workspaceId, inviteId, urlTemplate) {
|
|
644
|
+
await requireMembership(actor, workspaceId, 'admin')
|
|
645
|
+
const invite = await requireInvite(workspaceId, inviteId)
|
|
646
|
+
|
|
647
|
+
// The row may predate the guard `invite()` applies at creation: somebody
|
|
648
|
+
// who joined since then would get a fresh, working-looking link whose
|
|
649
|
+
// accept can only answer 409.
|
|
650
|
+
await requireStranger(workspaceId, invite.email)
|
|
651
|
+
|
|
652
|
+
// A new token, not the old one again: the address in the first email may
|
|
653
|
+
// have been forwarded anywhere, and reissuing retires it.
|
|
654
|
+
const now = dependencies.now()
|
|
655
|
+
const token = newToken()
|
|
656
|
+
const updated = await repository.updateInvite(dependencies.db, invite.id, {
|
|
657
|
+
tokenHash: hashToken(token),
|
|
658
|
+
expiresAt: new Date(now.getTime() + INVITE_LIFETIME_MS),
|
|
659
|
+
status: 'pending',
|
|
660
|
+
updatedAt: now,
|
|
661
|
+
})
|
|
662
|
+
|
|
663
|
+
if (updated === undefined) {
|
|
664
|
+
throw AppError.notFound('Invitation not found')
|
|
665
|
+
}
|
|
666
|
+
|
|
667
|
+
await sendInviteEmail(updated.email, token, urlTemplate)
|
|
668
|
+
|
|
669
|
+
return toInviteView(updated, now)
|
|
670
|
+
},
|
|
671
|
+
|
|
672
|
+
async revokeInvite(actor, workspaceId, inviteId) {
|
|
673
|
+
await requireMembership(actor, workspaceId, 'admin')
|
|
674
|
+
const invite = await requireInvite(workspaceId, inviteId)
|
|
675
|
+
|
|
676
|
+
// Deleted rather than marked: the row is what the token resolves through,
|
|
677
|
+
// so removing it is what actually stops the link in the sent email.
|
|
678
|
+
await repository.deleteInvite(dependencies.db, invite.id)
|
|
679
|
+
},
|
|
680
|
+
|
|
681
|
+
async acceptInvite(actor, token) {
|
|
682
|
+
const now = dependencies.now()
|
|
683
|
+
const invite = await repository.findInviteByTokenHash(dependencies.db, hashToken(token))
|
|
684
|
+
|
|
685
|
+
if (invite === undefined || invite.status !== 'pending' || invite.expiresAt <= now) {
|
|
686
|
+
throw AppError.unauthorized('That invitation is invalid or has expired')
|
|
687
|
+
}
|
|
688
|
+
|
|
689
|
+
const existing = await authRepository.findMembership(
|
|
690
|
+
dependencies.db,
|
|
691
|
+
invite.workspaceId,
|
|
692
|
+
actor.userId,
|
|
693
|
+
)
|
|
694
|
+
|
|
695
|
+
// The invitation is left alone. A link is forwarded often enough that the
|
|
696
|
+
// address on this one may not be the caller's, and revoking somebody
|
|
697
|
+
// else's invitation because you clicked their link would be worse than
|
|
698
|
+
// the refusal.
|
|
699
|
+
if (existing !== undefined) {
|
|
700
|
+
throw AppError.conflict('You already belong to that workspace')
|
|
701
|
+
}
|
|
702
|
+
|
|
703
|
+
const joiner = await authRepository.findUserById(dependencies.db, actor.userId)
|
|
704
|
+
|
|
705
|
+
if (joiner === undefined) {
|
|
706
|
+
throw new Error(`Session ${actor.sessionId} outlived the user row behind it`)
|
|
707
|
+
}
|
|
708
|
+
|
|
709
|
+
// Ownership is never invited, only created or transferred. The column's
|
|
710
|
+
// check constraint says the same; this is the service-side half of it.
|
|
711
|
+
const role: MemberRole = invite.role === 'admin' ? 'admin' : 'member'
|
|
712
|
+
const memberId = dependencies.createId('teamMember')
|
|
713
|
+
|
|
714
|
+
return dependencies.transaction(async ({ tx, events }) => {
|
|
715
|
+
try {
|
|
716
|
+
await repository.insertMember(tx, {
|
|
717
|
+
id: memberId,
|
|
718
|
+
workspaceId: invite.workspaceId,
|
|
719
|
+
userId: actor.userId,
|
|
720
|
+
role,
|
|
721
|
+
joinedAt: now,
|
|
722
|
+
})
|
|
723
|
+
} catch (error: unknown) {
|
|
724
|
+
// The membership check above answers this for every caller who is not
|
|
725
|
+
// racing a second accept of their own. This is what catches that one.
|
|
726
|
+
if (postgresErrorCode(error) === UNIQUE_VIOLATION) {
|
|
727
|
+
throw AppError.conflict('You already belong to that workspace')
|
|
728
|
+
}
|
|
729
|
+
|
|
730
|
+
throw error
|
|
731
|
+
}
|
|
732
|
+
|
|
733
|
+
await repository.deleteInvite(tx, invite.id)
|
|
734
|
+
|
|
735
|
+
// Any other invitation to the joiner's own address, which their joining
|
|
736
|
+
// has just killed: accepting one is now the refusal above, and until it
|
|
737
|
+
// expires it holds a seat and lists them beside their own membership.
|
|
738
|
+
// Accepting a token addressed to somebody else is how one survives the
|
|
739
|
+
// line before it.
|
|
740
|
+
await repository.deleteInvitesForEmail(tx, invite.workspaceId, joiner.email)
|
|
741
|
+
|
|
742
|
+
await authRepository.setActiveWorkspace(tx, actor.sessionId, invite.workspaceId)
|
|
743
|
+
|
|
744
|
+
const workspace = await repository.findWorkspace(tx, invite.workspaceId)
|
|
745
|
+
|
|
746
|
+
if (workspace === undefined) {
|
|
747
|
+
throw AppError.notFound('Workspace not found')
|
|
748
|
+
}
|
|
749
|
+
|
|
750
|
+
events.emit('member.joined', {
|
|
751
|
+
workspaceId: invite.workspaceId,
|
|
752
|
+
memberId,
|
|
753
|
+
userId: actor.userId,
|
|
754
|
+
})
|
|
755
|
+
|
|
756
|
+
return toWorkspaceView(workspace)
|
|
757
|
+
})
|
|
758
|
+
},
|
|
759
|
+
|
|
760
|
+
async listModuleSettings(actor, workspaceId) {
|
|
761
|
+
await requireMembership(actor, workspaceId, 'member')
|
|
762
|
+
|
|
763
|
+
return Promise.all(
|
|
764
|
+
dependencies.toggleableModuleIds.map(async (moduleId) => {
|
|
765
|
+
const entitlement = await dependencies.entitlements.check(workspaceId, moduleCapabilityName(moduleId))
|
|
766
|
+
|
|
767
|
+
return {
|
|
768
|
+
moduleId,
|
|
769
|
+
enabled: entitlement.kind === 'flag' ? entitlement.granted : true,
|
|
770
|
+
locked: dependencies.moduleConfigOverrides?.[moduleId] !== undefined,
|
|
771
|
+
}
|
|
772
|
+
}),
|
|
773
|
+
)
|
|
774
|
+
},
|
|
775
|
+
|
|
776
|
+
async setModuleEnabled(actor, workspaceId, moduleId, enabled) {
|
|
777
|
+
await requireMembership(actor, workspaceId, 'admin')
|
|
778
|
+
|
|
779
|
+
if (!dependencies.toggleableModuleIds.includes(moduleId)) {
|
|
780
|
+
throw AppError.notFound('Module not found')
|
|
781
|
+
}
|
|
782
|
+
|
|
783
|
+
if (dependencies.moduleConfigOverrides?.[moduleId] !== undefined) {
|
|
784
|
+
throw AppError.conflict('This module is locked by the deployment configuration')
|
|
785
|
+
}
|
|
786
|
+
|
|
787
|
+
await repository.upsertModuleSetting(dependencies.db, {
|
|
788
|
+
id: dependencies.createId('moduleSetting'),
|
|
789
|
+
workspaceId,
|
|
790
|
+
moduleId,
|
|
791
|
+
enabled,
|
|
792
|
+
updatedAt: dependencies.now(),
|
|
793
|
+
})
|
|
794
|
+
|
|
795
|
+
return { moduleId, enabled, locked: false }
|
|
796
|
+
},
|
|
797
|
+
}
|
|
798
|
+
}
|