@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,104 @@
|
|
|
1
|
+
import type { Column, SQL } from 'drizzle-orm';
|
|
2
|
+
/**
|
|
3
|
+
* Cursor pagination from `api.md`: `?limit=` and `?cursor=`, an opaque cursor,
|
|
4
|
+
* and `{ data, next_cursor }` on the wire.
|
|
5
|
+
*
|
|
6
|
+
* The cursor is a keyset rather than an offset. It carries the sort value and id
|
|
7
|
+
* of the last row on the page, so a page boundary stays put when rows are
|
|
8
|
+
* inserted or deleted underneath a client. Offsets skip and repeat rows when that
|
|
9
|
+
* happens, which for a CRM that agents write to is not a rare case.
|
|
10
|
+
*
|
|
11
|
+
* A cursor is bound to the sort it was issued under. Reusing one against a
|
|
12
|
+
* different `?sort=` is a client bug, and it is reported as one rather than
|
|
13
|
+
* silently paging through a different order.
|
|
14
|
+
*/
|
|
15
|
+
export declare const DEFAULT_PAGE_SIZE = 50;
|
|
16
|
+
export declare const MAX_PAGE_SIZE = 200;
|
|
17
|
+
/** A field a list may be ordered by, and how its value survives a round trip through a cursor. */
|
|
18
|
+
export interface SortableField<TRecord> {
|
|
19
|
+
readonly column: Column;
|
|
20
|
+
/** Reads the cursor value out of the last row of a page. */
|
|
21
|
+
readonly valueOf: (record: TRecord) => string;
|
|
22
|
+
/** Turns that string back into something comparable against the column. */
|
|
23
|
+
readonly parse: (value: string) => Date | string | number;
|
|
24
|
+
}
|
|
25
|
+
/** The documented sort fields of one resource, keyed by their wire name. */
|
|
26
|
+
export type SortableFields<TRecord> = Readonly<Record<string, SortableField<TRecord>>>;
|
|
27
|
+
/** Where the previous page stopped. */
|
|
28
|
+
export interface CursorPosition {
|
|
29
|
+
readonly value: Date | string | number;
|
|
30
|
+
readonly id: string;
|
|
31
|
+
}
|
|
32
|
+
export interface ListWindow<TRecord> {
|
|
33
|
+
/** How many rows the caller asked for. */
|
|
34
|
+
readonly limit: number;
|
|
35
|
+
/** What to ask the database for: one more than `limit`, to detect a next page. */
|
|
36
|
+
readonly fetchLimit: number;
|
|
37
|
+
/** The canonical sort spec, `-created_at` style. Cursors are bound to it. */
|
|
38
|
+
readonly sort: string;
|
|
39
|
+
readonly field: SortableField<TRecord>;
|
|
40
|
+
readonly descending: boolean;
|
|
41
|
+
readonly position: CursorPosition | undefined;
|
|
42
|
+
}
|
|
43
|
+
export interface Page<TRecord> {
|
|
44
|
+
readonly items: readonly TRecord[];
|
|
45
|
+
readonly nextCursor: string | null;
|
|
46
|
+
}
|
|
47
|
+
export interface ListQueryParameters {
|
|
48
|
+
readonly limit?: string | undefined;
|
|
49
|
+
readonly sort?: string | undefined;
|
|
50
|
+
readonly cursor?: string | undefined;
|
|
51
|
+
}
|
|
52
|
+
export declare function textSort<TRecord>(column: Column, valueOf: (record: TRecord) => string): SortableField<TRecord>;
|
|
53
|
+
export declare function integerSort<TRecord>(column: Column, valueOf: (record: TRecord) => number): SortableField<TRecord>;
|
|
54
|
+
export declare function timestampSort<TRecord>(column: Column, valueOf: (record: TRecord) => Date): SortableField<TRecord>;
|
|
55
|
+
/**
|
|
56
|
+
* Reads `?limit=` against the `api.md` range.
|
|
57
|
+
*
|
|
58
|
+
* Exported for the endpoints that take the same parameter without being paged
|
|
59
|
+
* lists. The dashboard is the case: it caps several embedded lists at once and
|
|
60
|
+
* issues no cursor, but the ceiling a caller may ask for is the same one.
|
|
61
|
+
*
|
|
62
|
+
* @throws AppError 422 for anything but a whole number in range.
|
|
63
|
+
*/
|
|
64
|
+
export declare function readPageSize(raw: string | undefined): number;
|
|
65
|
+
/**
|
|
66
|
+
* Reads `?limit=`, `?sort=` and `?cursor=` into a window a repository can apply.
|
|
67
|
+
*
|
|
68
|
+
* @param defaultSort The resource's own default, `-created_at` style. Naming a
|
|
69
|
+
* field the resource does not declare is a programming error, not a request
|
|
70
|
+
* error, so it throws rather than producing a 422.
|
|
71
|
+
* @throws AppError 422 for an out-of-range limit, an undocumented sort field, or
|
|
72
|
+
* a cursor that is unreadable or belongs to a different sort order.
|
|
73
|
+
*/
|
|
74
|
+
export declare function readListWindow<TRecord>(query: ListQueryParameters, fields: SortableFields<TRecord>, defaultSort: string): ListWindow<TRecord>;
|
|
75
|
+
/**
|
|
76
|
+
* The keyset predicate: everything after the cursor's row in the window's order.
|
|
77
|
+
*
|
|
78
|
+
* Values go through `sql.param` with their own column as the encoder. A bare
|
|
79
|
+
* `${value}` in a template reaches the driver unconverted, and postgres.js has no
|
|
80
|
+
* column to infer from, so a `Date` arrives where it wants a string.
|
|
81
|
+
*
|
|
82
|
+
* @returns undefined on the first page, where there is nothing to seek past.
|
|
83
|
+
*/
|
|
84
|
+
export declare function keysetCondition<TRecord>(window: ListWindow<TRecord>, idColumn: Column): SQL | undefined;
|
|
85
|
+
/**
|
|
86
|
+
* The ordering, id included. Without the id tiebreak two rows sharing a sort
|
|
87
|
+
* value could straddle a page boundary in either order, and one of them would be
|
|
88
|
+
* lost or repeated.
|
|
89
|
+
*/
|
|
90
|
+
export declare function orderByWindow<TRecord>(window: ListWindow<TRecord>, idColumn: Column): SQL[];
|
|
91
|
+
/**
|
|
92
|
+
* Trims the extra row a repository fetched and turns it into a next cursor.
|
|
93
|
+
*
|
|
94
|
+
* @param rows Up to `window.fetchLimit` rows, in the window's order.
|
|
95
|
+
*/
|
|
96
|
+
export declare function toPage<TRecord>(rows: readonly TRecord[], window: ListWindow<TRecord>, idOf: (record: TRecord) => string): Page<TRecord>;
|
|
97
|
+
/**
|
|
98
|
+
* Re-shapes the items of a page, leaving the cursor alone.
|
|
99
|
+
*
|
|
100
|
+
* A service pages over stored rows and answers with views, and the cursor is
|
|
101
|
+
* built from the row it came from, not from what the caller is handed back.
|
|
102
|
+
*/
|
|
103
|
+
export declare function mapPage<TFrom, TTo>(page: Page<TFrom>, render: (item: TFrom) => TTo): Page<TTo>;
|
|
104
|
+
//# sourceMappingURL=pagination.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pagination.d.ts","sourceRoot":"","sources":["../../src/lib/pagination.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,189 @@
|
|
|
1
|
+
import { asc, desc, sql } from 'drizzle-orm';
|
|
2
|
+
import { z } from 'zod';
|
|
3
|
+
import { AppError } from './errors.js';
|
|
4
|
+
/**
|
|
5
|
+
* Cursor pagination from `api.md`: `?limit=` and `?cursor=`, an opaque cursor,
|
|
6
|
+
* and `{ data, next_cursor }` on the wire.
|
|
7
|
+
*
|
|
8
|
+
* The cursor is a keyset rather than an offset. It carries the sort value and id
|
|
9
|
+
* of the last row on the page, so a page boundary stays put when rows are
|
|
10
|
+
* inserted or deleted underneath a client. Offsets skip and repeat rows when that
|
|
11
|
+
* happens, which for a CRM that agents write to is not a rare case.
|
|
12
|
+
*
|
|
13
|
+
* A cursor is bound to the sort it was issued under. Reusing one against a
|
|
14
|
+
* different `?sort=` is a client bug, and it is reported as one rather than
|
|
15
|
+
* silently paging through a different order.
|
|
16
|
+
*/
|
|
17
|
+
export const DEFAULT_PAGE_SIZE = 50;
|
|
18
|
+
export const MAX_PAGE_SIZE = 200;
|
|
19
|
+
/** The cursor payload. It is client-supplied, so it is parsed, never trusted. */
|
|
20
|
+
const cursorSchema = z.strictObject({
|
|
21
|
+
sort: z.string().min(1),
|
|
22
|
+
value: z.string(),
|
|
23
|
+
id: z.string().min(1),
|
|
24
|
+
});
|
|
25
|
+
function invalidCursor(reason) {
|
|
26
|
+
return AppError.validationFailed('That cursor is not one this API issued', [
|
|
27
|
+
{ field: 'cursor', message: reason },
|
|
28
|
+
]);
|
|
29
|
+
}
|
|
30
|
+
export function textSort(column, valueOf) {
|
|
31
|
+
return { column, valueOf, parse: (value) => value };
|
|
32
|
+
}
|
|
33
|
+
export function integerSort(column, valueOf) {
|
|
34
|
+
return {
|
|
35
|
+
column,
|
|
36
|
+
valueOf: (record) => String(valueOf(record)),
|
|
37
|
+
parse: (value) => {
|
|
38
|
+
const parsed = Number(value);
|
|
39
|
+
if (!Number.isInteger(parsed)) {
|
|
40
|
+
throw invalidCursor('Its position is not a whole number');
|
|
41
|
+
}
|
|
42
|
+
return parsed;
|
|
43
|
+
},
|
|
44
|
+
};
|
|
45
|
+
}
|
|
46
|
+
export function timestampSort(column, valueOf) {
|
|
47
|
+
return {
|
|
48
|
+
column,
|
|
49
|
+
valueOf: (record) => valueOf(record).toISOString(),
|
|
50
|
+
parse: (value) => {
|
|
51
|
+
const parsed = new Date(value);
|
|
52
|
+
if (Number.isNaN(parsed.getTime())) {
|
|
53
|
+
throw invalidCursor('Its position is not a timestamp');
|
|
54
|
+
}
|
|
55
|
+
return parsed;
|
|
56
|
+
},
|
|
57
|
+
};
|
|
58
|
+
}
|
|
59
|
+
function encodeCursor(sort, value, id) {
|
|
60
|
+
return Buffer.from(JSON.stringify({ sort, value, id }), 'utf8').toString('base64url');
|
|
61
|
+
}
|
|
62
|
+
function decodeCursor(raw) {
|
|
63
|
+
let payload;
|
|
64
|
+
try {
|
|
65
|
+
payload = JSON.parse(Buffer.from(raw, 'base64url').toString('utf8'));
|
|
66
|
+
}
|
|
67
|
+
catch {
|
|
68
|
+
// Base64 and JSON both refuse the same way here: the string did not come
|
|
69
|
+
// from `encodeCursor`. The client cannot act on which of the two failed.
|
|
70
|
+
throw invalidCursor('It is not readable');
|
|
71
|
+
}
|
|
72
|
+
const parsed = cursorSchema.safeParse(payload);
|
|
73
|
+
if (!parsed.success) {
|
|
74
|
+
throw invalidCursor('It does not carry a position');
|
|
75
|
+
}
|
|
76
|
+
return parsed.data;
|
|
77
|
+
}
|
|
78
|
+
/**
|
|
79
|
+
* Reads `?limit=` against the `api.md` range.
|
|
80
|
+
*
|
|
81
|
+
* Exported for the endpoints that take the same parameter without being paged
|
|
82
|
+
* lists. The dashboard is the case: it caps several embedded lists at once and
|
|
83
|
+
* issues no cursor, but the ceiling a caller may ask for is the same one.
|
|
84
|
+
*
|
|
85
|
+
* @throws AppError 422 for anything but a whole number in range.
|
|
86
|
+
*/
|
|
87
|
+
export function readPageSize(raw) {
|
|
88
|
+
if (raw === undefined) {
|
|
89
|
+
return DEFAULT_PAGE_SIZE;
|
|
90
|
+
}
|
|
91
|
+
const limit = Number(raw);
|
|
92
|
+
if (!Number.isInteger(limit) || limit < 1 || limit > MAX_PAGE_SIZE) {
|
|
93
|
+
throw AppError.validationFailed('That page size is out of range', [
|
|
94
|
+
{ field: 'limit', message: `Use a whole number from 1 to ${String(MAX_PAGE_SIZE)}` },
|
|
95
|
+
]);
|
|
96
|
+
}
|
|
97
|
+
return limit;
|
|
98
|
+
}
|
|
99
|
+
/**
|
|
100
|
+
* Reads `?limit=`, `?sort=` and `?cursor=` into a window a repository can apply.
|
|
101
|
+
*
|
|
102
|
+
* @param defaultSort The resource's own default, `-created_at` style. Naming a
|
|
103
|
+
* field the resource does not declare is a programming error, not a request
|
|
104
|
+
* error, so it throws rather than producing a 422.
|
|
105
|
+
* @throws AppError 422 for an out-of-range limit, an undocumented sort field, or
|
|
106
|
+
* a cursor that is unreadable or belongs to a different sort order.
|
|
107
|
+
*/
|
|
108
|
+
export function readListWindow(query, fields, defaultSort) {
|
|
109
|
+
const sort = query.sort ?? defaultSort;
|
|
110
|
+
const descending = sort.startsWith('-');
|
|
111
|
+
const name = descending ? sort.slice(1) : sort;
|
|
112
|
+
const field = fields[name];
|
|
113
|
+
if (field === undefined) {
|
|
114
|
+
const documented = Object.keys(fields).sort().join(', ');
|
|
115
|
+
if (query.sort === undefined) {
|
|
116
|
+
throw new Error(`Default sort "${defaultSort}" is not one of: ${documented}`);
|
|
117
|
+
}
|
|
118
|
+
throw AppError.validationFailed('That sort field is not available on this resource', [
|
|
119
|
+
{ field: 'sort', message: `Sort by one of: ${documented}` },
|
|
120
|
+
]);
|
|
121
|
+
}
|
|
122
|
+
const position = (() => {
|
|
123
|
+
if (query.cursor === undefined) {
|
|
124
|
+
return undefined;
|
|
125
|
+
}
|
|
126
|
+
const decoded = decodeCursor(query.cursor);
|
|
127
|
+
if (decoded.sort !== sort) {
|
|
128
|
+
throw invalidCursor(`It was issued for sort=${decoded.sort}`);
|
|
129
|
+
}
|
|
130
|
+
return { value: field.parse(decoded.value), id: decoded.id };
|
|
131
|
+
})();
|
|
132
|
+
const limit = readPageSize(query.limit);
|
|
133
|
+
return { limit, fetchLimit: limit + 1, sort, field, descending, position };
|
|
134
|
+
}
|
|
135
|
+
/**
|
|
136
|
+
* The keyset predicate: everything after the cursor's row in the window's order.
|
|
137
|
+
*
|
|
138
|
+
* Values go through `sql.param` with their own column as the encoder. A bare
|
|
139
|
+
* `${value}` in a template reaches the driver unconverted, and postgres.js has no
|
|
140
|
+
* column to infer from, so a `Date` arrives where it wants a string.
|
|
141
|
+
*
|
|
142
|
+
* @returns undefined on the first page, where there is nothing to seek past.
|
|
143
|
+
*/
|
|
144
|
+
export function keysetCondition(window, idColumn) {
|
|
145
|
+
if (window.position === undefined) {
|
|
146
|
+
return undefined;
|
|
147
|
+
}
|
|
148
|
+
const { column } = window.field;
|
|
149
|
+
const after = sql.param(window.position.value, column);
|
|
150
|
+
const afterId = sql.param(window.position.id, idColumn);
|
|
151
|
+
return window.descending
|
|
152
|
+
? sql `(${column} < ${after} or (${column} = ${after} and ${idColumn} < ${afterId}))`
|
|
153
|
+
: sql `(${column} > ${after} or (${column} = ${after} and ${idColumn} > ${afterId}))`;
|
|
154
|
+
}
|
|
155
|
+
/**
|
|
156
|
+
* The ordering, id included. Without the id tiebreak two rows sharing a sort
|
|
157
|
+
* value could straddle a page boundary in either order, and one of them would be
|
|
158
|
+
* lost or repeated.
|
|
159
|
+
*/
|
|
160
|
+
export function orderByWindow(window, idColumn) {
|
|
161
|
+
const direction = window.descending ? desc : asc;
|
|
162
|
+
return [direction(window.field.column), direction(idColumn)];
|
|
163
|
+
}
|
|
164
|
+
/**
|
|
165
|
+
* Trims the extra row a repository fetched and turns it into a next cursor.
|
|
166
|
+
*
|
|
167
|
+
* @param rows Up to `window.fetchLimit` rows, in the window's order.
|
|
168
|
+
*/
|
|
169
|
+
export function toPage(rows, window, idOf) {
|
|
170
|
+
if (rows.length < window.fetchLimit) {
|
|
171
|
+
return { items: rows, nextCursor: null };
|
|
172
|
+
}
|
|
173
|
+
const items = rows.slice(0, window.limit);
|
|
174
|
+
const last = items.at(-1);
|
|
175
|
+
if (last === undefined) {
|
|
176
|
+
throw new Error('unreachable: a full page cannot be empty');
|
|
177
|
+
}
|
|
178
|
+
return { items, nextCursor: encodeCursor(window.sort, window.field.valueOf(last), idOf(last)) };
|
|
179
|
+
}
|
|
180
|
+
/**
|
|
181
|
+
* Re-shapes the items of a page, leaving the cursor alone.
|
|
182
|
+
*
|
|
183
|
+
* A service pages over stored rows and answers with views, and the cursor is
|
|
184
|
+
* built from the row it came from, not from what the caller is handed back.
|
|
185
|
+
*/
|
|
186
|
+
export function mapPage(page, render) {
|
|
187
|
+
return { items: page.items.map(render), nextCursor: page.nextCursor };
|
|
188
|
+
}
|
|
189
|
+
//# sourceMappingURL=pagination.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pagination.js","sourceRoot":"","sources":["../../src/lib/pagination.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { MINIMUM_PASSWORD_LENGTH } from '@kelpie/schemas';
|
|
2
|
+
/**
|
|
3
|
+
* Password hashing. Argon2id, the parameters the library defaults to, which
|
|
4
|
+
* follow the OWASP recommendation at time of writing.
|
|
5
|
+
*
|
|
6
|
+
* The algorithm and its parameters are embedded in the hash string, so raising
|
|
7
|
+
* the cost later does not invalidate existing hashes: they verify with the
|
|
8
|
+
* parameters they were made with, and `needsRehash` says when to upgrade one.
|
|
9
|
+
*/
|
|
10
|
+
/**
|
|
11
|
+
* Rejected before hashing. Argon2 will happily hash an empty string.
|
|
12
|
+
*
|
|
13
|
+
* The number lives in `@kelpie/schemas` because the browser's change-password
|
|
14
|
+
* form states the rule before submitting, and two copies would be two rules.
|
|
15
|
+
* Re-exported here so callers keep reading it off the module that enforces it.
|
|
16
|
+
*/
|
|
17
|
+
export { MINIMUM_PASSWORD_LENGTH };
|
|
18
|
+
export declare class WeakPasswordError extends Error {
|
|
19
|
+
constructor(message: string);
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* @throws WeakPasswordError when the password is too short to be worth hashing.
|
|
23
|
+
*/
|
|
24
|
+
export declare function hashPassword(plaintext: string): Promise<string>;
|
|
25
|
+
/**
|
|
26
|
+
* Constant-time within argon2 itself. Returns false rather than throwing on a
|
|
27
|
+
* malformed stored hash, because a corrupted row must not become a login bypass
|
|
28
|
+
* or a 500 that distinguishes it from a wrong password.
|
|
29
|
+
*/
|
|
30
|
+
export declare function verifyPassword(storedHash: string, plaintext: string): Promise<boolean>;
|
|
31
|
+
export declare function isPasswordStrongEnough(plaintext: string): boolean;
|
|
32
|
+
//# sourceMappingURL=passwords.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"passwords.d.ts","sourceRoot":"","sources":["../../src/lib/passwords.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,uBAAuB,EAAE,MAAM,iBAAiB,CAAA;AAGzD;;;;;;;GAOG;AAEH;;;;;;GAMG;AACH,OAAO,EAAE,uBAAuB,EAAE,CAAA;AAElC,qBAAa,iBAAkB,SAAQ,KAAK;IAC1C,YAAY,OAAO,EAAE,MAAM,EAG1B;CACF;AAED;;GAEG;AACH,wBAAsB,YAAY,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAMrE;AAED;;;;GAIG;AACH,wBAAsB,cAAc,CAAC,UAAU,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAO5F;AAED,wBAAgB,sBAAsB,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAEjE"}
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import { MINIMUM_PASSWORD_LENGTH } from '@kelpie/schemas';
|
|
2
|
+
import { hash, verify } from '@node-rs/argon2';
|
|
3
|
+
/**
|
|
4
|
+
* Password hashing. Argon2id, the parameters the library defaults to, which
|
|
5
|
+
* follow the OWASP recommendation at time of writing.
|
|
6
|
+
*
|
|
7
|
+
* The algorithm and its parameters are embedded in the hash string, so raising
|
|
8
|
+
* the cost later does not invalidate existing hashes: they verify with the
|
|
9
|
+
* parameters they were made with, and `needsRehash` says when to upgrade one.
|
|
10
|
+
*/
|
|
11
|
+
/**
|
|
12
|
+
* Rejected before hashing. Argon2 will happily hash an empty string.
|
|
13
|
+
*
|
|
14
|
+
* The number lives in `@kelpie/schemas` because the browser's change-password
|
|
15
|
+
* form states the rule before submitting, and two copies would be two rules.
|
|
16
|
+
* Re-exported here so callers keep reading it off the module that enforces it.
|
|
17
|
+
*/
|
|
18
|
+
export { MINIMUM_PASSWORD_LENGTH };
|
|
19
|
+
export class WeakPasswordError extends Error {
|
|
20
|
+
constructor(message) {
|
|
21
|
+
super(message);
|
|
22
|
+
this.name = 'WeakPasswordError';
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* @throws WeakPasswordError when the password is too short to be worth hashing.
|
|
27
|
+
*/
|
|
28
|
+
export async function hashPassword(plaintext) {
|
|
29
|
+
if (plaintext.length < MINIMUM_PASSWORD_LENGTH) {
|
|
30
|
+
throw new WeakPasswordError(`Password must be at least ${MINIMUM_PASSWORD_LENGTH} characters`);
|
|
31
|
+
}
|
|
32
|
+
return hash(plaintext);
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* Constant-time within argon2 itself. Returns false rather than throwing on a
|
|
36
|
+
* malformed stored hash, because a corrupted row must not become a login bypass
|
|
37
|
+
* or a 500 that distinguishes it from a wrong password.
|
|
38
|
+
*/
|
|
39
|
+
export async function verifyPassword(storedHash, plaintext) {
|
|
40
|
+
try {
|
|
41
|
+
return await verify(storedHash, plaintext);
|
|
42
|
+
}
|
|
43
|
+
catch {
|
|
44
|
+
// A hash argon2 cannot parse is not a match. The row is corrupt, not correct.
|
|
45
|
+
return false;
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
export function isPasswordStrongEnough(plaintext) {
|
|
49
|
+
return plaintext.length >= MINIMUM_PASSWORD_LENGTH;
|
|
50
|
+
}
|
|
51
|
+
//# sourceMappingURL=passwords.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"passwords.js","sourceRoot":"","sources":["../../src/lib/passwords.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,uBAAuB,EAAE,MAAM,iBAAiB,CAAA;AACzD,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,iBAAiB,CAAA;AAE9C;;;;;;;GAOG;AAEH;;;;;;GAMG;AACH,OAAO,EAAE,uBAAuB,EAAE,CAAA;AAElC,MAAM,OAAO,iBAAkB,SAAQ,KAAK;IAC1C,YAAY,OAAe;QACzB,KAAK,CAAC,OAAO,CAAC,CAAA;QACd,IAAI,CAAC,IAAI,GAAG,mBAAmB,CAAA;IACjC,CAAC;CACF;AAED;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,YAAY,CAAC,SAAiB;IAClD,IAAI,SAAS,CAAC,MAAM,GAAG,uBAAuB,EAAE,CAAC;QAC/C,MAAM,IAAI,iBAAiB,CAAC,6BAA6B,uBAAuB,aAAa,CAAC,CAAA;IAChG,CAAC;IAED,OAAO,IAAI,CAAC,SAAS,CAAC,CAAA;AACxB,CAAC;AAED;;;;GAIG;AACH,MAAM,CAAC,KAAK,UAAU,cAAc,CAAC,UAAkB,EAAE,SAAiB;IACxE,IAAI,CAAC;QACH,OAAO,MAAM,MAAM,CAAC,UAAU,EAAE,SAAS,CAAC,CAAA;IAC5C,CAAC;IAAC,MAAM,CAAC;QACP,8EAA8E;QAC9E,OAAO,KAAK,CAAA;IACd,CAAC;AACH,CAAC;AAED,MAAM,UAAU,sBAAsB,CAAC,SAAiB;IACtD,OAAO,SAAS,CAAC,MAAM,IAAI,uBAAuB,CAAA;AACpD,CAAC"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { Column, SQL } from 'drizzle-orm';
|
|
2
|
+
/** Wraps a search term as a LIKE pattern, escaping anything the user did not mean as a wildcard. */
|
|
3
|
+
export declare function containsPattern(term: string): string;
|
|
4
|
+
/**
|
|
5
|
+
* True when any element of a `text[]` column matches the pattern.
|
|
6
|
+
*
|
|
7
|
+
* `tags @> '{…}'` would only find whole-tag equality, and the filter box is a
|
|
8
|
+
* substring filter.
|
|
9
|
+
*/
|
|
10
|
+
export declare function arrayContainsPattern(column: Column, pattern: string): SQL;
|
|
11
|
+
//# sourceMappingURL=search.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"search.d.ts","sourceRoot":"","sources":["../../src/lib/search.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,aAAa,CAAA;AAc9C,oGAAoG;AACpG,wBAAgB,eAAe,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAEpD;AAED;;;;;GAKG;AACH,wBAAgB,oBAAoB,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,GAAG,CAEzE"}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { sql } from 'drizzle-orm';
|
|
2
|
+
/**
|
|
3
|
+
* The `?q=` free-text filter from `api.md`: a case-insensitive substring match
|
|
4
|
+
* over the fields the mockup's `FilterBar` matches for that object.
|
|
5
|
+
*
|
|
6
|
+
* Substring matching, not full-text search. A user typing three characters into a
|
|
7
|
+
* filter box expects to see partial words, which `to_tsquery` will not give them.
|
|
8
|
+
* Search across resources is its own feature with its own index.
|
|
9
|
+
*/
|
|
10
|
+
/** `%`, `_` and `\` steer LIKE. A user typing one means the character, not the pattern. */
|
|
11
|
+
const LIKE_WILDCARDS = /[\\%_]/gu;
|
|
12
|
+
/** Wraps a search term as a LIKE pattern, escaping anything the user did not mean as a wildcard. */
|
|
13
|
+
export function containsPattern(term) {
|
|
14
|
+
return `%${term.trim().replace(LIKE_WILDCARDS, (match) => `\\${match}`)}%`;
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* True when any element of a `text[]` column matches the pattern.
|
|
18
|
+
*
|
|
19
|
+
* `tags @> '{…}'` would only find whole-tag equality, and the filter box is a
|
|
20
|
+
* substring filter.
|
|
21
|
+
*/
|
|
22
|
+
export function arrayContainsPattern(column, pattern) {
|
|
23
|
+
return sql `exists (select 1 from unnest(${column}) as element where element ilike ${pattern})`;
|
|
24
|
+
}
|
|
25
|
+
//# sourceMappingURL=search.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"search.js","sourceRoot":"","sources":["../../src/lib/search.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,GAAG,EAAE,MAAM,aAAa,CAAA;AAGjC;;;;;;;GAOG;AAEH,2FAA2F;AAC3F,MAAM,cAAc,GAAG,UAAU,CAAA;AAEjC,oGAAoG;AACpG,MAAM,UAAU,eAAe,CAAC,IAAY;IAC1C,OAAO,IAAI,IAAI,CAAC,IAAI,EAAE,CAAC,OAAO,CAAC,cAAc,EAAE,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,KAAK,EAAE,CAAC,GAAG,CAAA;AAC5E,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,oBAAoB,CAAC,MAAc,EAAE,OAAe;IAClE,OAAO,GAAG,CAAA,gCAAgC,MAAM,oCAAoC,OAAO,GAAG,CAAA;AAChG,CAAC"}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
/** Thrown when sealed text cannot be read back: wrong key, or tampered ciphertext. */
|
|
3
|
+
export declare class SecretDecryptionError extends Error {
|
|
4
|
+
constructor(reason: string, options?: {
|
|
5
|
+
cause?: unknown;
|
|
6
|
+
});
|
|
7
|
+
}
|
|
8
|
+
export interface SecretCipher {
|
|
9
|
+
/** @returns `v1.<base64url iv>.<base64url tag>.<base64url ciphertext>`, safe to store as text. */
|
|
10
|
+
seal(plaintext: string): string;
|
|
11
|
+
/**
|
|
12
|
+
* Reads a stored value, trying the current key and then the previous one.
|
|
13
|
+
*
|
|
14
|
+
* @throws SecretDecryptionError when the text is malformed, tampered with, or
|
|
15
|
+
* sealed under a key this cipher does not hold.
|
|
16
|
+
*/
|
|
17
|
+
open(sealed: string): string;
|
|
18
|
+
/**
|
|
19
|
+
* The same value sealed under the current key, or undefined when it already is.
|
|
20
|
+
*
|
|
21
|
+
* This is what makes a re-seal pass idempotent: it is the only way to tell
|
|
22
|
+
* "readable because it is current" from "readable because the previous key is
|
|
23
|
+
* still configured", which `open` deliberately hides from everything else.
|
|
24
|
+
*
|
|
25
|
+
* @throws SecretDecryptionError when neither key opens it.
|
|
26
|
+
*/
|
|
27
|
+
reseal(sealed: string): string | undefined;
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* The environment slice a module needs to build a cipher. Modules validate it
|
|
31
|
+
* through `context.config`, so a missing or malformed key stops boot with the
|
|
32
|
+
* module named rather than failing on the first delivery attempt.
|
|
33
|
+
*/
|
|
34
|
+
export declare const secretEncryptionConfigSchema: z.ZodObject<{
|
|
35
|
+
SECRET_ENCRYPTION_KEY: z.ZodString;
|
|
36
|
+
SECRET_ENCRYPTION_KEY_PREVIOUS: z.ZodOptional<z.ZodString>;
|
|
37
|
+
}, z.core.$strip>;
|
|
38
|
+
export type SecretEncryptionConfig = z.infer<typeof secretEncryptionConfigSchema>;
|
|
39
|
+
export declare function createSecretCipher(config: SecretEncryptionConfig): SecretCipher;
|
|
40
|
+
//# sourceMappingURL=secrets.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"secrets.d.ts","sourceRoot":"","sources":["../../src/lib/secrets.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAA;AA+BvB,sFAAsF;AACtF,qBAAa,qBAAsB,SAAQ,KAAK;IAC9C,YAAY,MAAM,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE;QAAE,KAAK,CAAC,EAAE,OAAO,CAAA;KAAE,EAOxD;CACF;AAED,MAAM,WAAW,YAAY;IAC3B,kGAAkG;IAClG,IAAI,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,CAAA;IAC/B;;;;;OAKG;IACH,IAAI,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAAA;IAC5B;;;;;;;;OAQG;IACH,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAAA;CAC3C;AAID;;;;GAIG;AACH,eAAO,MAAM,4BAA4B;;;iBAmBvC,CAAA;AAMF,MAAM,MAAM,sBAAsB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,4BAA4B,CAAC,CAAA;AAqEjF,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,sBAAsB,GAAG,YAAY,CAuD/E"}
|
|
@@ -0,0 +1,152 @@
|
|
|
1
|
+
import { createCipheriv, createDecipheriv, randomBytes } from 'node:crypto';
|
|
2
|
+
import { z } from 'zod';
|
|
3
|
+
/**
|
|
4
|
+
* Reversible storage for secrets the service itself has to use again.
|
|
5
|
+
*
|
|
6
|
+
* Distinct from `lib/tokens.ts`, and the difference is what a secret is *for*.
|
|
7
|
+
* A session cookie or an API key is only ever compared against, so it is stored
|
|
8
|
+
* as a SHA-256 hash and nothing can read it back. A webhook signing secret is
|
|
9
|
+
* different: `api.md` computes the delivery signature *with* it, and the
|
|
10
|
+
* receiver holds the plaintext we showed them once, so the service must be able
|
|
11
|
+
* to produce the same bytes months later. Hashing it would make signing
|
|
12
|
+
* impossible; storing it bare would put every workspace's signing secret in any
|
|
13
|
+
* database dump.
|
|
14
|
+
*
|
|
15
|
+
* `schema.md` already anticipates this for `agent_registrations.auth_header_encrypted`,
|
|
16
|
+
* and `modules.md` for integration connection records. They share this module.
|
|
17
|
+
*/
|
|
18
|
+
/** AES-256-GCM: authenticated, so a tampered ciphertext fails rather than decodes to noise. */
|
|
19
|
+
const ALGORITHM = 'aes-256-gcm';
|
|
20
|
+
const KEY_BYTES = 32;
|
|
21
|
+
/** 96 bits, the size GCM is specified for. A fresh one per seal, never reused. */
|
|
22
|
+
const IV_BYTES = 12;
|
|
23
|
+
const TAG_BYTES = 16;
|
|
24
|
+
/**
|
|
25
|
+
* Marks the format so a future scheme can be introduced without guessing at
|
|
26
|
+
* what an existing row holds. Rotation reads the version, not the length.
|
|
27
|
+
*/
|
|
28
|
+
const FORMAT_VERSION = 'v1';
|
|
29
|
+
/** Thrown when sealed text cannot be read back: wrong key, or tampered ciphertext. */
|
|
30
|
+
export class SecretDecryptionError extends Error {
|
|
31
|
+
constructor(reason, options) {
|
|
32
|
+
super(`Could not decrypt a stored secret: ${reason}`);
|
|
33
|
+
this.name = 'SecretDecryptionError';
|
|
34
|
+
if (options?.cause !== undefined) {
|
|
35
|
+
this.cause = options.cause;
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
const KEY_MESSAGE = `must be ${String(KEY_BYTES)} bytes of base64, e.g. from: node -e "console.log(require('crypto').randomBytes(32).toString('base64'))"`;
|
|
40
|
+
/**
|
|
41
|
+
* The environment slice a module needs to build a cipher. Modules validate it
|
|
42
|
+
* through `context.config`, so a missing or malformed key stops boot with the
|
|
43
|
+
* module named rather than failing on the first delivery attempt.
|
|
44
|
+
*/
|
|
45
|
+
export const secretEncryptionConfigSchema = z.object({
|
|
46
|
+
SECRET_ENCRYPTION_KEY: z
|
|
47
|
+
.string()
|
|
48
|
+
.refine((value) => decodeKey(value) !== undefined, { message: KEY_MESSAGE }),
|
|
49
|
+
/**
|
|
50
|
+
* The key being rotated away from. Optional, and only set while a rotation is
|
|
51
|
+
* in progress: `open` falls back to it, so the service keeps signing
|
|
52
|
+
* deliveries between the moment the new key is deployed and the moment
|
|
53
|
+
* `npm run reseal` finishes. Remove it once that pass reports nothing left.
|
|
54
|
+
*
|
|
55
|
+
* Blank counts as absent. An operator ending a rotation empties the line far
|
|
56
|
+
* more often than they delete it, and refusing to boot over that would punish
|
|
57
|
+
* the tidy step of the procedure.
|
|
58
|
+
*/
|
|
59
|
+
SECRET_ENCRYPTION_KEY_PREVIOUS: z
|
|
60
|
+
.string()
|
|
61
|
+
.refine((value) => isBlank(value) || decodeKey(value) !== undefined, { message: KEY_MESSAGE })
|
|
62
|
+
.optional(),
|
|
63
|
+
});
|
|
64
|
+
function isBlank(value) {
|
|
65
|
+
return value.trim().length === 0;
|
|
66
|
+
}
|
|
67
|
+
/** @returns The key bytes, or undefined when the value is not base64 of exactly `KEY_BYTES`. */
|
|
68
|
+
function decodeKey(value) {
|
|
69
|
+
// Buffer.from is lenient: it ignores what it cannot decode rather than
|
|
70
|
+
// throwing, so the length check is the whole validation. A 64-character hex
|
|
71
|
+
// key decodes to 48 bytes and is rejected here rather than silently truncated.
|
|
72
|
+
const decoded = Buffer.from(value, 'base64');
|
|
73
|
+
return decoded.length === KEY_BYTES ? decoded : undefined;
|
|
74
|
+
}
|
|
75
|
+
/** @throws SecretDecryptionError when the text is not a `v1` sealed value. */
|
|
76
|
+
function parseSealed(sealed) {
|
|
77
|
+
const [version, rawIv, rawTag, rawCiphertext] = sealed.split('.');
|
|
78
|
+
if (version !== FORMAT_VERSION || rawIv === undefined || rawTag === undefined || rawCiphertext === undefined) {
|
|
79
|
+
throw new SecretDecryptionError('the stored value is not in the expected format');
|
|
80
|
+
}
|
|
81
|
+
const iv = Buffer.from(rawIv, 'base64url');
|
|
82
|
+
const tag = Buffer.from(rawTag, 'base64url');
|
|
83
|
+
if (iv.length !== IV_BYTES || tag.length !== TAG_BYTES) {
|
|
84
|
+
throw new SecretDecryptionError('the stored value has a malformed header');
|
|
85
|
+
}
|
|
86
|
+
return { iv, tag, ciphertext: Buffer.from(rawCiphertext, 'base64url') };
|
|
87
|
+
}
|
|
88
|
+
/** @returns The plaintext, or undefined when this key is not the one it was sealed with. */
|
|
89
|
+
function openWith(key, parts) {
|
|
90
|
+
const decipher = createDecipheriv(ALGORITHM, key, parts.iv);
|
|
91
|
+
decipher.setAuthTag(parts.tag);
|
|
92
|
+
try {
|
|
93
|
+
return Buffer.concat([decipher.update(parts.ciphertext), decipher.final()]).toString('utf8');
|
|
94
|
+
}
|
|
95
|
+
catch {
|
|
96
|
+
// GCM raises here when the tag does not match, which means either the wrong
|
|
97
|
+
// key or a modified row. Undefined rather than a throw because the caller is
|
|
98
|
+
// working through a list of keys and a miss is expected on all but one.
|
|
99
|
+
return undefined;
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
/** @throws Error when the value is not `KEY_BYTES` of base64. */
|
|
103
|
+
function requireKey(name, value) {
|
|
104
|
+
const key = decodeKey(value);
|
|
105
|
+
if (key === undefined) {
|
|
106
|
+
throw new Error(`${name} must be ${String(KEY_BYTES)} bytes of base64`);
|
|
107
|
+
}
|
|
108
|
+
return key;
|
|
109
|
+
}
|
|
110
|
+
export function createSecretCipher(config) {
|
|
111
|
+
const current = requireKey('SECRET_ENCRYPTION_KEY', config.SECRET_ENCRYPTION_KEY);
|
|
112
|
+
const previousValue = config.SECRET_ENCRYPTION_KEY_PREVIOUS;
|
|
113
|
+
// Blank counts as absent, which is how an operator normally ends a rotation.
|
|
114
|
+
const previous = previousValue === undefined || isBlank(previousValue)
|
|
115
|
+
? undefined
|
|
116
|
+
: requireKey('SECRET_ENCRYPTION_KEY_PREVIOUS', previousValue);
|
|
117
|
+
/** Current first: the common case is a value that needs no fallback at all. */
|
|
118
|
+
const keys = previous === undefined ? [current] : [current, previous];
|
|
119
|
+
function seal(plaintext) {
|
|
120
|
+
const iv = randomBytes(IV_BYTES);
|
|
121
|
+
const cipher = createCipheriv(ALGORITHM, current, iv);
|
|
122
|
+
const ciphertext = Buffer.concat([cipher.update(plaintext, 'utf8'), cipher.final()]);
|
|
123
|
+
return [
|
|
124
|
+
FORMAT_VERSION,
|
|
125
|
+
iv.toString('base64url'),
|
|
126
|
+
cipher.getAuthTag().toString('base64url'),
|
|
127
|
+
ciphertext.toString('base64url'),
|
|
128
|
+
].join('.');
|
|
129
|
+
}
|
|
130
|
+
function open(sealed) {
|
|
131
|
+
const parts = parseSealed(sealed);
|
|
132
|
+
for (const key of keys) {
|
|
133
|
+
const plaintext = openWith(key, parts);
|
|
134
|
+
if (plaintext !== undefined) {
|
|
135
|
+
return plaintext;
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
throw new SecretDecryptionError(previous === undefined
|
|
139
|
+
? 'it was sealed with a different key, or has been altered'
|
|
140
|
+
: 'neither the current nor the previous key opens it, or it has been altered');
|
|
141
|
+
}
|
|
142
|
+
function reseal(sealed) {
|
|
143
|
+
if (openWith(current, parseSealed(sealed)) !== undefined) {
|
|
144
|
+
return undefined;
|
|
145
|
+
}
|
|
146
|
+
// Not readable under the current key, so `open` either finds it under the
|
|
147
|
+
// previous one or throws, which is exactly the caller's answer either way.
|
|
148
|
+
return seal(open(sealed));
|
|
149
|
+
}
|
|
150
|
+
return { seal, open, reseal };
|
|
151
|
+
}
|
|
152
|
+
//# sourceMappingURL=secrets.js.map
|