@kelpie/server 0.11.0 → 0.13.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/app.d.ts +13 -0
- package/dist/app.d.ts.map +1 -1
- package/dist/app.js +8 -1
- package/dist/app.js.map +1 -1
- package/dist/boot.d.ts.map +1 -1
- package/dist/boot.js +1 -0
- package/dist/boot.js.map +1 -1
- package/dist/index.d.ts +3 -3
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/lib/apiKeyScopes.d.ts.map +1 -1
- package/dist/lib/apiKeyScopes.js +6 -0
- package/dist/lib/apiKeyScopes.js.map +1 -1
- package/dist/lib/columns.d.ts +6 -0
- package/dist/lib/columns.d.ts.map +1 -1
- package/dist/lib/columns.js +5 -3
- package/dist/lib/columns.js.map +1 -1
- package/dist/lib/config.d.ts +17 -0
- package/dist/lib/config.d.ts.map +1 -1
- package/dist/lib/config.js +3 -0
- package/dist/lib/config.js.map +1 -1
- package/dist/lib/egress.d.ts.map +1 -1
- package/dist/lib/egress.js +8 -4
- package/dist/lib/egress.js.map +1 -1
- package/dist/lib/errors.d.ts +18 -0
- package/dist/lib/errors.d.ts.map +1 -1
- package/dist/lib/errors.js +25 -0
- package/dist/lib/errors.js.map +1 -1
- package/dist/lib/ids.d.ts +11 -0
- package/dist/lib/ids.d.ts.map +1 -1
- package/dist/lib/ids.js +11 -0
- package/dist/lib/ids.js.map +1 -1
- package/dist/lib/kelpieConfigFile.d.ts +15 -1
- package/dist/lib/kelpieConfigFile.d.ts.map +1 -1
- package/dist/lib/kelpieConfigFile.js +33 -1
- package/dist/lib/kelpieConfigFile.js.map +1 -1
- package/dist/modules/agent-tasks/catalog.d.ts.map +1 -1
- package/dist/modules/agent-tasks/catalog.js +32 -1
- package/dist/modules/agent-tasks/catalog.js.map +1 -1
- package/dist/modules/agent-tasks/index.d.ts.map +1 -1
- package/dist/modules/agent-tasks/index.js +1 -0
- package/dist/modules/agent-tasks/index.js.map +1 -1
- package/dist/modules/agent-tasks/resolve.d.ts.map +1 -1
- package/dist/modules/agent-tasks/resolve.js +5 -0
- package/dist/modules/agent-tasks/resolve.js.map +1 -1
- package/dist/modules/agent-tasks/routes.d.ts +2 -0
- package/dist/modules/agent-tasks/routes.d.ts.map +1 -1
- package/dist/modules/attachedRecords.d.ts +22 -8
- package/dist/modules/attachedRecords.d.ts.map +1 -1
- package/dist/modules/attachedRecords.js +42 -5
- package/dist/modules/attachedRecords.js.map +1 -1
- package/dist/modules/auth/index.d.ts.map +1 -1
- package/dist/modules/auth/index.js +22 -4
- package/dist/modules/auth/index.js.map +1 -1
- package/dist/modules/auth/repository.d.ts +16 -1
- package/dist/modules/auth/repository.d.ts.map +1 -1
- package/dist/modules/auth/repository.js +21 -2
- package/dist/modules/auth/repository.js.map +1 -1
- package/dist/modules/auth/routes.d.ts.map +1 -1
- package/dist/modules/auth/routes.js +32 -6
- package/dist/modules/auth/routes.js.map +1 -1
- package/dist/modules/auth/schema.d.ts +18 -1
- package/dist/modules/auth/schema.d.ts.map +1 -1
- package/dist/modules/auth/schema.js +12 -1
- package/dist/modules/auth/schema.js.map +1 -1
- package/dist/modules/auth/service.d.ts +46 -0
- package/dist/modules/auth/service.d.ts.map +1 -1
- package/dist/modules/auth/service.js +167 -10
- package/dist/modules/auth/service.js.map +1 -1
- package/dist/modules/auth/session.d.ts +12 -0
- package/dist/modules/auth/session.d.ts.map +1 -1
- package/dist/modules/auth/session.js +12 -0
- package/dist/modules/auth/session.js.map +1 -1
- package/dist/modules/companies/repository.d.ts.map +1 -1
- package/dist/modules/companies/repository.js +1 -1
- package/dist/modules/companies/repository.js.map +1 -1
- package/dist/modules/companies/routes.d.ts +2 -4
- package/dist/modules/companies/routes.d.ts.map +1 -1
- package/dist/modules/companies/routes.js +6 -11
- package/dist/modules/companies/routes.js.map +1 -1
- package/dist/modules/companies/schema.d.ts +13 -28
- package/dist/modules/companies/schema.d.ts.map +1 -1
- package/dist/modules/companies/schema.js +2 -2
- package/dist/modules/companies/schema.js.map +1 -1
- package/dist/modules/companies/service.d.ts +2 -3
- package/dist/modules/companies/service.d.ts.map +1 -1
- package/dist/modules/companies/service.js +4 -7
- package/dist/modules/companies/service.js.map +1 -1
- package/dist/modules/core.d.ts.map +1 -1
- package/dist/modules/core.js +2 -0
- package/dist/modules/core.js.map +1 -1
- package/dist/modules/custom-fields/repository.d.ts.map +1 -1
- package/dist/modules/custom-fields/repository.js +2 -0
- package/dist/modules/custom-fields/repository.js.map +1 -1
- package/dist/modules/custom-fields/routes.d.ts +1 -0
- package/dist/modules/custom-fields/routes.d.ts.map +1 -1
- package/dist/modules/dashboard/index.d.ts.map +1 -1
- package/dist/modules/dashboard/index.js +1 -0
- package/dist/modules/dashboard/index.js.map +1 -1
- package/dist/modules/dashboard/repository.d.ts +13 -0
- package/dist/modules/dashboard/repository.d.ts.map +1 -1
- package/dist/modules/dashboard/repository.js +36 -0
- package/dist/modules/dashboard/repository.js.map +1 -1
- package/dist/modules/dashboard/routes.d.ts.map +1 -1
- package/dist/modules/dashboard/routes.js +13 -0
- package/dist/modules/dashboard/routes.js.map +1 -1
- package/dist/modules/dashboard/service.d.ts +11 -0
- package/dist/modules/dashboard/service.d.ts.map +1 -1
- package/dist/modules/dashboard/service.js +24 -1
- package/dist/modules/dashboard/service.js.map +1 -1
- package/dist/modules/decisions/repository.d.ts.map +1 -1
- package/dist/modules/decisions/repository.js +2 -0
- package/dist/modules/decisions/repository.js.map +1 -1
- package/dist/modules/decisions/routes.d.ts +2 -0
- package/dist/modules/decisions/routes.d.ts.map +1 -1
- package/dist/modules/events/attendances.d.ts +35 -0
- package/dist/modules/events/attendances.d.ts.map +1 -0
- package/dist/modules/events/attendances.js +157 -0
- package/dist/modules/events/attendances.js.map +1 -0
- package/dist/modules/events/catalog.d.ts +35 -0
- package/dist/modules/events/catalog.d.ts.map +1 -0
- package/dist/modules/events/catalog.js +11 -0
- package/dist/modules/events/catalog.js.map +1 -0
- package/dist/modules/events/index.d.ts +10 -0
- package/dist/modules/events/index.d.ts.map +1 -0
- package/dist/modules/events/index.js +47 -0
- package/dist/modules/events/index.js.map +1 -0
- package/dist/modules/events/repository.d.ts +67 -0
- package/dist/modules/events/repository.d.ts.map +1 -0
- package/dist/modules/events/repository.js +212 -0
- package/dist/modules/events/repository.js.map +1 -0
- package/dist/modules/events/routes.d.ts +136 -0
- package/dist/modules/events/routes.d.ts.map +1 -0
- package/dist/modules/events/routes.js +280 -0
- package/dist/modules/events/routes.js.map +1 -0
- package/dist/modules/events/schema.d.ts +626 -0
- package/dist/modules/events/schema.d.ts.map +1 -0
- package/dist/modules/events/schema.js +93 -0
- package/dist/modules/events/schema.js.map +1 -0
- package/dist/modules/events/service.d.ts +68 -0
- package/dist/modules/events/service.d.ts.map +1 -0
- package/dist/modules/events/service.js +262 -0
- package/dist/modules/events/service.js.map +1 -0
- package/dist/modules/events/tools.d.ts +8 -0
- package/dist/modules/events/tools.d.ts.map +1 -0
- package/dist/modules/events/tools.js +80 -0
- package/dist/modules/events/tools.js.map +1 -0
- package/dist/modules/forms/applySubmissionFields.d.ts.map +1 -1
- package/dist/modules/forms/applySubmissionFields.js +7 -5
- package/dist/modules/forms/applySubmissionFields.js.map +1 -1
- package/dist/modules/forms/fillAddresses.d.ts +4 -0
- package/dist/modules/forms/fillAddresses.d.ts.map +1 -0
- package/dist/modules/forms/fillAddresses.js +93 -0
- package/dist/modules/forms/fillAddresses.js.map +1 -0
- package/dist/modules/forms/repository.d.ts +2 -2
- package/dist/modules/forms/repository.d.ts.map +1 -1
- package/dist/modules/forms/repository.js.map +1 -1
- package/dist/modules/forms/routes.d.ts +2 -0
- package/dist/modules/forms/routes.d.ts.map +1 -1
- package/dist/modules/forms/routes.js +2 -2
- package/dist/modules/forms/routes.js.map +1 -1
- package/dist/modules/forms/schema.js +2 -2
- package/dist/modules/forms/schema.js.map +1 -1
- package/dist/modules/forms/service.js +2 -2
- package/dist/modules/forms/service.js.map +1 -1
- package/dist/modules/forms/submission.d.ts +1 -0
- package/dist/modules/forms/submission.d.ts.map +1 -1
- package/dist/modules/forms/submission.js +27 -4
- package/dist/modules/forms/submission.js.map +1 -1
- package/dist/modules/hiring/roles.d.ts.map +1 -1
- package/dist/modules/hiring/roles.js +2 -1
- package/dist/modules/hiring/roles.js.map +1 -1
- package/dist/modules/import-export/addresses.d.ts +22 -0
- package/dist/modules/import-export/addresses.d.ts.map +1 -0
- package/dist/modules/import-export/addresses.js +83 -0
- package/dist/modules/import-export/addresses.js.map +1 -0
- package/dist/modules/import-export/drafts.d.ts +3 -4
- package/dist/modules/import-export/drafts.d.ts.map +1 -1
- package/dist/modules/import-export/drafts.js +4 -5
- package/dist/modules/import-export/drafts.js.map +1 -1
- package/dist/modules/import-export/exportRows.d.ts.map +1 -1
- package/dist/modules/import-export/exportRows.js +3 -3
- package/dist/modules/import-export/exportRows.js.map +1 -1
- package/dist/modules/import-export/plan.d.ts.map +1 -1
- package/dist/modules/import-export/plan.js +17 -2
- package/dist/modules/import-export/plan.js.map +1 -1
- package/dist/modules/import-export/presets.d.ts.map +1 -1
- package/dist/modules/import-export/presets.js +52 -7
- package/dist/modules/import-export/presets.js.map +1 -1
- package/dist/modules/import-export/repository.d.ts +3 -4
- package/dist/modules/import-export/repository.d.ts.map +1 -1
- package/dist/modules/import-export/repository.js +2 -3
- package/dist/modules/import-export/repository.js.map +1 -1
- package/dist/modules/import-export/writes.d.ts.map +1 -1
- package/dist/modules/import-export/writes.js +8 -4
- package/dist/modules/import-export/writes.js.map +1 -1
- package/dist/modules/lists/routes.d.ts +4 -0
- package/dist/modules/lists/routes.d.ts.map +1 -1
- package/dist/modules/notes/routes.d.ts +2 -0
- package/dist/modules/notes/routes.d.ts.map +1 -1
- package/dist/modules/people/repository.d.ts.map +1 -1
- package/dist/modules/people/repository.js +1 -1
- package/dist/modules/people/repository.js.map +1 -1
- package/dist/modules/people/routes.d.ts +2 -2
- package/dist/modules/people/routes.js +6 -6
- package/dist/modules/people/routes.js.map +1 -1
- package/dist/modules/people/schema.d.ts +17 -14
- package/dist/modules/people/schema.d.ts.map +1 -1
- package/dist/modules/people/schema.js +6 -4
- package/dist/modules/people/schema.js.map +1 -1
- package/dist/modules/people/service.d.ts +2 -2
- package/dist/modules/people/service.d.ts.map +1 -1
- package/dist/modules/people/service.js +5 -4
- package/dist/modules/people/service.js.map +1 -1
- package/dist/modules/plans/repository.d.ts +2 -2
- package/dist/modules/plans/repository.d.ts.map +1 -1
- package/dist/modules/plans/routes.d.ts +1 -0
- package/dist/modules/plans/routes.d.ts.map +1 -1
- package/dist/modules/plans/routes.js +4 -4
- package/dist/modules/plans/routes.js.map +1 -1
- package/dist/modules/plans/schema.d.ts +2 -2
- package/dist/modules/plans/schema.d.ts.map +1 -1
- package/dist/modules/plans/schema.js +3 -3
- package/dist/modules/plans/schema.js.map +1 -1
- package/dist/modules/plans/service.d.ts +2 -2
- package/dist/modules/plans/service.d.ts.map +1 -1
- package/dist/modules/plans/service.js.map +1 -1
- package/dist/modules/plans/tools.js +2 -2
- package/dist/modules/plans/tools.js.map +1 -1
- package/dist/modules/recordTargets.d.ts.map +1 -1
- package/dist/modules/recordTargets.js +11 -0
- package/dist/modules/recordTargets.js.map +1 -1
- package/dist/modules/references.d.ts.map +1 -1
- package/dist/modules/references.js +2 -0
- package/dist/modules/references.js.map +1 -1
- package/dist/modules/sample-data/fixture.d.ts +26 -4
- package/dist/modules/sample-data/fixture.d.ts.map +1 -1
- package/dist/modules/sample-data/fixture.js +157 -23
- package/dist/modules/sample-data/fixture.js.map +1 -1
- package/dist/modules/sample-data/index.d.ts +5 -2
- package/dist/modules/sample-data/index.d.ts.map +1 -1
- package/dist/modules/sample-data/index.js +7 -2
- package/dist/modules/sample-data/index.js.map +1 -1
- package/dist/modules/sample-data/routes.d.ts.map +1 -1
- package/dist/modules/sample-data/routes.js +2 -0
- package/dist/modules/sample-data/routes.js.map +1 -1
- package/dist/modules/sample-data/service.d.ts +11 -3
- package/dist/modules/sample-data/service.d.ts.map +1 -1
- package/dist/modules/sample-data/service.js +452 -363
- package/dist/modules/sample-data/service.js.map +1 -1
- package/dist/modules/sample-data/tools.d.ts.map +1 -1
- package/dist/modules/sample-data/tools.js +4 -3
- package/dist/modules/sample-data/tools.js.map +1 -1
- package/dist/modules/search/index.d.ts +1 -1
- package/dist/modules/search/index.d.ts.map +1 -1
- package/dist/modules/search/index.js +2 -1
- package/dist/modules/search/index.js.map +1 -1
- package/dist/modules/search/repository.d.ts +1 -0
- package/dist/modules/search/repository.d.ts.map +1 -1
- package/dist/modules/search/repository.js +22 -0
- package/dist/modules/search/repository.js.map +1 -1
- package/dist/modules/search/service.d.ts +2 -2
- package/dist/modules/search/service.d.ts.map +1 -1
- package/dist/modules/search/service.js +4 -3
- package/dist/modules/search/service.js.map +1 -1
- package/dist/modules/smtp-email/index.d.ts +12 -4
- package/dist/modules/smtp-email/index.d.ts.map +1 -1
- package/dist/modules/smtp-email/index.js +25 -5
- package/dist/modules/smtp-email/index.js.map +1 -1
- package/dist/modules/workspace/repository.d.ts +2 -0
- package/dist/modules/workspace/repository.d.ts.map +1 -1
- package/dist/modules/workspace/repository.js +12 -0
- package/dist/modules/workspace/repository.js.map +1 -1
- package/dist/modules/workspace/routes.d.ts.map +1 -1
- package/dist/modules/workspace/routes.js +13 -0
- package/dist/modules/workspace/routes.js.map +1 -1
- package/dist/modules/workspace/service.d.ts +10 -0
- package/dist/modules/workspace/service.d.ts.map +1 -1
- package/dist/modules/workspace/service.js +34 -10
- package/dist/modules/workspace/service.js.map +1 -1
- package/dist/modules/workspace/starters.d.ts +17 -2
- package/dist/modules/workspace/starters.d.ts.map +1 -1
- package/dist/modules/workspace/starters.js +141 -14
- package/dist/modules/workspace/starters.js.map +1 -1
- package/dist/modules/workspace/workspaceAccessMiddleware.d.ts.map +1 -1
- package/dist/modules/workspace/workspaceAccessMiddleware.js +3 -4
- package/dist/modules/workspace/workspaceAccessMiddleware.js.map +1 -1
- package/dist/runtime/events.d.ts +1 -1
- package/dist/runtime/events.d.ts.map +1 -1
- package/dist/runtime/events.js +2 -0
- package/dist/runtime/events.js.map +1 -1
- package/dist/runtime/module.d.ts +71 -1
- package/dist/runtime/module.d.ts.map +1 -1
- package/dist/runtime/registry.d.ts.map +1 -1
- package/dist/runtime/registry.js +142 -9
- package/dist/runtime/registry.js.map +1 -1
- package/dist/schema/index.d.ts +1 -0
- package/dist/schema/index.d.ts.map +1 -1
- package/dist/schema/index.js +1 -0
- package/dist/schema/index.js.map +1 -1
- package/dist/testing/app.d.ts +8 -0
- package/dist/testing/app.d.ts.map +1 -1
- package/dist/testing/app.js +6 -1
- package/dist/testing/app.js.map +1 -1
- package/dist/testing/client.d.ts.map +1 -1
- package/dist/testing/client.js +9 -1
- package/dist/testing/client.js.map +1 -1
- package/migrations/0043_external_sign_in.sql +2 -0
- package/migrations/0044_events.sql +79 -0
- package/migrations/0045_addresses.sql +66 -0
- package/migrations/0046_drop_company_website.sql +66 -0
- package/migrations/meta/_journal.json +28 -0
- package/package.json +3 -3
- package/src/app.ts +25 -1
- package/src/boot.ts +1 -0
- package/src/index.ts +13 -1
- package/src/lib/apiKeyScopes.ts +6 -0
- package/src/lib/columns.ts +12 -3
- package/src/lib/config.ts +21 -0
- package/src/lib/egress.ts +8 -4
- package/src/lib/errors.ts +37 -0
- package/src/lib/ids.ts +11 -0
- package/src/lib/kelpieConfigFile.ts +69 -1
- package/src/modules/agent-tasks/catalog.ts +33 -1
- package/src/modules/agent-tasks/index.ts +1 -0
- package/src/modules/agent-tasks/resolve.ts +11 -0
- package/src/modules/attachedRecords.ts +85 -13
- package/src/modules/auth/index.ts +26 -4
- package/src/modules/auth/repository.ts +36 -4
- package/src/modules/auth/routes.ts +46 -9
- package/src/modules/auth/schema.ts +12 -1
- package/src/modules/auth/service.ts +261 -10
- package/src/modules/auth/session.ts +14 -0
- package/src/modules/companies/repository.ts +1 -0
- package/src/modules/companies/routes.ts +6 -11
- package/src/modules/companies/schema.ts +3 -3
- package/src/modules/companies/service.ts +6 -10
- package/src/modules/core.ts +2 -0
- package/src/modules/custom-fields/repository.ts +2 -0
- package/src/modules/dashboard/index.ts +1 -0
- package/src/modules/dashboard/repository.ts +64 -0
- package/src/modules/dashboard/routes.ts +15 -0
- package/src/modules/dashboard/service.ts +48 -0
- package/src/modules/decisions/repository.ts +2 -0
- package/src/modules/events/attendances.ts +245 -0
- package/src/modules/events/catalog.ts +36 -0
- package/src/modules/events/index.ts +54 -0
- package/src/modules/events/repository.ts +396 -0
- package/src/modules/events/routes.ts +405 -0
- package/src/modules/events/schema.ts +148 -0
- package/src/modules/events/service.ts +443 -0
- package/src/modules/events/tools.ts +118 -0
- package/src/modules/forms/applySubmissionFields.ts +7 -5
- package/src/modules/forms/fillAddresses.ts +185 -0
- package/src/modules/forms/repository.ts +3 -3
- package/src/modules/forms/routes.ts +2 -2
- package/src/modules/forms/schema.ts +2 -2
- package/src/modules/forms/service.ts +2 -2
- package/src/modules/forms/submission.ts +34 -4
- package/src/modules/hiring/roles.ts +2 -1
- package/src/modules/import-export/addresses.ts +150 -0
- package/src/modules/import-export/drafts.ts +7 -9
- package/src/modules/import-export/exportRows.ts +3 -3
- package/src/modules/import-export/plan.ts +30 -2
- package/src/modules/import-export/presets.ts +55 -7
- package/src/modules/import-export/repository.ts +5 -7
- package/src/modules/import-export/writes.ts +8 -4
- package/src/modules/people/repository.ts +1 -0
- package/src/modules/people/routes.ts +6 -6
- package/src/modules/people/schema.ts +7 -5
- package/src/modules/people/service.ts +7 -5
- package/src/modules/plans/repository.ts +2 -2
- package/src/modules/plans/routes.ts +6 -6
- package/src/modules/plans/schema.ts +4 -4
- package/src/modules/plans/service.ts +3 -3
- package/src/modules/plans/tools.ts +2 -2
- package/src/modules/recordTargets.ts +14 -0
- package/src/modules/references.ts +2 -0
- package/src/modules/sample-data/fixture.ts +208 -27
- package/src/modules/sample-data/index.ts +7 -2
- package/src/modules/sample-data/routes.ts +2 -0
- package/src/modules/sample-data/service.ts +166 -49
- package/src/modules/sample-data/tools.ts +4 -3
- package/src/modules/search/index.ts +2 -1
- package/src/modules/search/repository.ts +32 -1
- package/src/modules/search/service.ts +6 -4
- package/src/modules/smtp-email/index.ts +32 -10
- package/src/modules/workspace/repository.ts +18 -0
- package/src/modules/workspace/routes.ts +16 -0
- package/src/modules/workspace/service.ts +59 -14
- package/src/modules/workspace/starters.ts +275 -14
- package/src/modules/workspace/workspaceAccessMiddleware.ts +3 -4
- package/src/runtime/events.ts +2 -0
- package/src/runtime/module.ts +78 -1
- package/src/runtime/registry.ts +176 -8
- package/src/schema/index.ts +1 -0
- package/src/testing/app.ts +14 -1
- package/src/testing/client.ts +11 -1
package/src/runtime/registry.ts
CHANGED
|
@@ -13,12 +13,15 @@ import type { EntitlementRegistry } from './entitlements.ts'
|
|
|
13
13
|
import { createEventBus } from './events.ts'
|
|
14
14
|
import type { EventBus } from './events.ts'
|
|
15
15
|
import type {
|
|
16
|
+
CompletedSignIn,
|
|
17
|
+
ExternalSignInHandler,
|
|
16
18
|
KelpieModule,
|
|
17
19
|
McpTool,
|
|
18
20
|
ModuleCatalogEntry,
|
|
19
21
|
ModuleContext,
|
|
20
22
|
ModuleServices,
|
|
21
23
|
SchemaContribution,
|
|
24
|
+
VerifiedIdentity,
|
|
22
25
|
} from './module.ts'
|
|
23
26
|
import { createModuleConfigProvider, moduleCapabilityName, validateModuleConfig } from './moduleConfig.ts'
|
|
24
27
|
import { ModuleBootError, orderModules } from './order.ts'
|
|
@@ -84,6 +87,117 @@ function assertMountablePath(moduleId: string, kind: string, path: string): void
|
|
|
84
87
|
}
|
|
85
88
|
}
|
|
86
89
|
|
|
90
|
+
/** Verb methods a module can call on the router — full Hono set. */
|
|
91
|
+
const ROUTER_VERB_METHODS = ['get', 'post', 'put', 'patch', 'delete', 'options', 'all'] as const
|
|
92
|
+
type RouterVerbMethod = (typeof ROUTER_VERB_METHODS)[number]
|
|
93
|
+
|
|
94
|
+
function isRouterVerbMethod(name: string): name is RouterVerbMethod {
|
|
95
|
+
return (ROUTER_VERB_METHODS as readonly string[]).includes(name)
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
/**
|
|
99
|
+
* Wraps a Hono router so every route the module registers runs `gate` first,
|
|
100
|
+
* and only that module's own routes. The straightforward alternative —
|
|
101
|
+
* `router.use('*', gate)` — attaches at `/v1/*` on the app once the router is
|
|
102
|
+
* mounted (Hono flattens sub-routers onto the parent prefix), so the gate
|
|
103
|
+
* fires for every module's routes, not just this module's. Prepending the gate
|
|
104
|
+
* to each declared route keeps the check local.
|
|
105
|
+
*
|
|
106
|
+
* The full router surface is covered so a future contributor cannot silently
|
|
107
|
+
* reintroduce the leak by reaching for a method that was not wrapped:
|
|
108
|
+
*
|
|
109
|
+
* - HTTP verbs and `on`: prepend `gate`, then the module's handlers.
|
|
110
|
+
* - `use(pattern, ...)` at a specific path: prepend `gate`, then the mw.
|
|
111
|
+
* - `route(subPath, subApp)`: recursively wrap `subApp` before mounting, so
|
|
112
|
+
* every route it contributes still runs the gate first.
|
|
113
|
+
*
|
|
114
|
+
* And the calls that cannot be made module-local through wrapping fail at
|
|
115
|
+
* boot with a message naming the module, rather than shipping a subtle leak:
|
|
116
|
+
*
|
|
117
|
+
* - `use()` with no path, `use('*')`, `use('/*')`, `use('/')`: any of these
|
|
118
|
+
* register a middleware at `/v1/*` on the parent app once the router is
|
|
119
|
+
* mounted — the exact bug this wrapper prevents. A module that wants to
|
|
120
|
+
* share middleware across many of its routes must name a specific path
|
|
121
|
+
* (`/things/*`) or attach the middleware per route.
|
|
122
|
+
* - `notFound` / `onError`: fire for every unmatched or failing `/v1`
|
|
123
|
+
* request once the router is flattened, so a module's handler would run
|
|
124
|
+
* for other modules' traffic. Handle failures inside the module's own
|
|
125
|
+
* route handlers instead.
|
|
126
|
+
*/
|
|
127
|
+
function gateRouter(router: Hono, moduleId: string, gate: MiddlewareHandler): Hono {
|
|
128
|
+
const proxy: Hono = new Proxy(router, {
|
|
129
|
+
get(target, property, receiver) {
|
|
130
|
+
if (typeof property !== 'string') {
|
|
131
|
+
return Reflect.get(target, property, receiver)
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
if (isRouterVerbMethod(property)) {
|
|
135
|
+
return (path: string, ...handlers: Handler[]): Hono => {
|
|
136
|
+
const method = target[property] as (path: string, ...handlers: Handler[]) => Hono
|
|
137
|
+
method.call(target, path, gate, ...handlers)
|
|
138
|
+
return proxy
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
if (property === 'on') {
|
|
143
|
+
return (
|
|
144
|
+
method: string | string[],
|
|
145
|
+
path: string | string[],
|
|
146
|
+
...handlers: Handler[]
|
|
147
|
+
): Hono => {
|
|
148
|
+
target.on(method as never, path as never, gate, ...handlers)
|
|
149
|
+
return proxy
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
if (property === 'use') {
|
|
154
|
+
return (...args: unknown[]): Hono => {
|
|
155
|
+
const first = args[0]
|
|
156
|
+
const isAppWide =
|
|
157
|
+
typeof first !== 'string' || first === '*' || first === '/*' || first === '/'
|
|
158
|
+
|
|
159
|
+
if (isAppWide) {
|
|
160
|
+
throw new ModuleBootError([
|
|
161
|
+
`module "${moduleId}" called router.use() with an app-wide pattern (${
|
|
162
|
+
typeof first === 'string' ? `"${first}"` : 'no path'
|
|
163
|
+
}). Hono flattens the module router onto "/v1", so this would fire for every module's routes. Name a specific path ("/things/*") or attach middleware per route.`,
|
|
164
|
+
])
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
const [pattern, ...handlers] = args as [string, ...MiddlewareHandler[]]
|
|
168
|
+
target.use(pattern, gate, ...handlers)
|
|
169
|
+
return proxy
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
if (property === 'route') {
|
|
174
|
+
return (path: string, subApp: Hono): Hono => {
|
|
175
|
+
// The sub-app's routes were registered on it before this call, so a
|
|
176
|
+
// proxy over `subApp` cannot retroactively prepend the gate to them.
|
|
177
|
+
// Instead attach the gate as middleware scoped to the sub-router's
|
|
178
|
+
// mount prefix on this router — once flattened onto `/v1`, the
|
|
179
|
+
// middleware covers exactly `/v1${path}/*`, which is the module's
|
|
180
|
+
// own routes. `use` must land before `route` so composition order
|
|
181
|
+
// runs the gate first.
|
|
182
|
+
target.use(`${path.replace(/\/+$/, '')}/*`, gate)
|
|
183
|
+
target.route(path, subApp)
|
|
184
|
+
return proxy
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
if (property === 'notFound' || property === 'onError') {
|
|
189
|
+
throw new ModuleBootError([
|
|
190
|
+
`module "${moduleId}" called router.${property}(). A module router's ${property} fires for every unmatched or failing "/v1" request once the router is mounted; handle failures inside the module's own route handlers instead.`,
|
|
191
|
+
])
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
return Reflect.get(target, property, receiver)
|
|
195
|
+
},
|
|
196
|
+
}) as Hono
|
|
197
|
+
|
|
198
|
+
return proxy
|
|
199
|
+
}
|
|
200
|
+
|
|
87
201
|
/**
|
|
88
202
|
* What `registerModules` needs.
|
|
89
203
|
*
|
|
@@ -180,6 +294,46 @@ class EmailSenderProxy implements EmailSender {
|
|
|
180
294
|
}
|
|
181
295
|
}
|
|
182
296
|
|
|
297
|
+
/**
|
|
298
|
+
* Completes a sign-in for an identity a module verified elsewhere.
|
|
299
|
+
*
|
|
300
|
+
* Same shape as `EmailSenderProxy`, and for the same reason: one module owns
|
|
301
|
+
* the implementation, every module reaches it through this object, and a
|
|
302
|
+
* consumer captures the proxy at register time but only calls it at request
|
|
303
|
+
* time, so registration order does not matter.
|
|
304
|
+
*
|
|
305
|
+
* Exactly one installer, unlike email's named registry: there is one `users`
|
|
306
|
+
* table and one session cookie, so "which implementation" is never a question
|
|
307
|
+
* an assembly should have to answer.
|
|
308
|
+
*/
|
|
309
|
+
class ExternalSignInProxy {
|
|
310
|
+
private target: ExternalSignInHandler | undefined = undefined
|
|
311
|
+
private installedBy: string | undefined = undefined
|
|
312
|
+
|
|
313
|
+
install(moduleId: string, handler: ExternalSignInHandler): void {
|
|
314
|
+
if (this.installedBy !== undefined) {
|
|
315
|
+
throw new ModuleBootError([
|
|
316
|
+
`module "${moduleId}" provides external sign-in, but module "${this.installedBy}" already did`,
|
|
317
|
+
])
|
|
318
|
+
}
|
|
319
|
+
|
|
320
|
+
this.target = handler
|
|
321
|
+
this.installedBy = moduleId
|
|
322
|
+
}
|
|
323
|
+
|
|
324
|
+
complete(context: Context, identity: VerifiedIdentity): Promise<CompletedSignIn> {
|
|
325
|
+
if (this.target === undefined) {
|
|
326
|
+
return Promise.reject(
|
|
327
|
+
new Error(
|
|
328
|
+
'external sign-in used before a module installed it. Is the auth module in the assembly?',
|
|
329
|
+
),
|
|
330
|
+
)
|
|
331
|
+
}
|
|
332
|
+
|
|
333
|
+
return this.target(context, identity)
|
|
334
|
+
}
|
|
335
|
+
}
|
|
336
|
+
|
|
183
337
|
/**
|
|
184
338
|
* The name the runtime uses for its built-in log sender. Reserved: a module
|
|
185
339
|
* that tries to register under this name fails boot.
|
|
@@ -204,11 +358,20 @@ function createModuleContext(
|
|
|
204
358
|
moduleCatalog: readonly ModuleCatalogEntry[],
|
|
205
359
|
emailProxy: EmailSenderProxy,
|
|
206
360
|
providers: Map<string, RegisteredProvider>,
|
|
361
|
+
externalSignIn: ExternalSignInProxy,
|
|
207
362
|
): ModuleContext {
|
|
208
363
|
return {
|
|
209
364
|
...options.services,
|
|
210
365
|
email: emailProxy,
|
|
211
366
|
|
|
367
|
+
provideExternalSignIn(handler) {
|
|
368
|
+
externalSignIn.install(module.id, handler)
|
|
369
|
+
},
|
|
370
|
+
|
|
371
|
+
completeExternalSignIn(context, identity) {
|
|
372
|
+
return externalSignIn.complete(context, identity)
|
|
373
|
+
},
|
|
374
|
+
|
|
212
375
|
provideEmailSender(name, build) {
|
|
213
376
|
if (name === LOG_PROVIDER_NAME) {
|
|
214
377
|
throw new ModuleBootError([
|
|
@@ -230,22 +393,25 @@ function createModuleContext(
|
|
|
230
393
|
routes(mount) {
|
|
231
394
|
const router = new Hono()
|
|
232
395
|
|
|
233
|
-
// Gate
|
|
234
|
-
//
|
|
235
|
-
//
|
|
236
|
-
//
|
|
396
|
+
// Gate must run before anything `mount` adds. A `router.use('*', gate)`
|
|
397
|
+
// here would attach at `/v1/*` on the app after mounting (Hono flattens
|
|
398
|
+
// the sub-router onto the parent prefix), which would fire the gate for
|
|
399
|
+
// every module's routes, not just this one's. So the gate is prepended
|
|
400
|
+
// to each individual route through `gateRouter` instead.
|
|
237
401
|
if (module.structural !== true && options.resolveActor !== undefined) {
|
|
238
402
|
const { resolveActor } = options
|
|
239
|
-
|
|
240
|
-
router.use('*', async (context, next) => {
|
|
403
|
+
const gate: MiddlewareHandler = async (context, next) => {
|
|
241
404
|
const actor = await resolveActor(context)
|
|
242
405
|
|
|
243
406
|
await requireCapability(entitlements, requireWorkspaceId(actor), moduleCapabilityName(module.id))
|
|
244
407
|
await next()
|
|
245
|
-
}
|
|
408
|
+
}
|
|
409
|
+
|
|
410
|
+
mount(gateRouter(router, module.id, gate))
|
|
411
|
+
} else {
|
|
412
|
+
mount(router)
|
|
246
413
|
}
|
|
247
414
|
|
|
248
|
-
mount(router)
|
|
249
415
|
accumulator.routers.push({ moduleId: module.id, router })
|
|
250
416
|
},
|
|
251
417
|
|
|
@@ -348,6 +514,7 @@ export async function registerModules(options: ModuleRuntimeOptions): Promise<Mo
|
|
|
348
514
|
const entitlements = options.entitlements ?? createEntitlementRegistry()
|
|
349
515
|
const emailProxy = new EmailSenderProxy()
|
|
350
516
|
const emailProviders = new Map<string, RegisteredProvider>()
|
|
517
|
+
const externalSignIn = new ExternalSignInProxy()
|
|
351
518
|
|
|
352
519
|
// The built-in log provider is always available, no module required. Named
|
|
353
520
|
// 'log' in kelpie.config.ts's email.provider picks this one. Built eagerly
|
|
@@ -429,6 +596,7 @@ export async function registerModules(options: ModuleRuntimeOptions): Promise<Mo
|
|
|
429
596
|
moduleCatalog,
|
|
430
597
|
emailProxy,
|
|
431
598
|
emailProviders,
|
|
599
|
+
externalSignIn,
|
|
432
600
|
)
|
|
433
601
|
|
|
434
602
|
try {
|
package/src/schema/index.ts
CHANGED
|
@@ -20,6 +20,7 @@ export * from '../modules/opportunities/schema.ts'
|
|
|
20
20
|
export * from '../modules/partnerships/schema.ts'
|
|
21
21
|
export * from '../modules/raises/schema.ts'
|
|
22
22
|
export * from '../modules/hiring/schema.ts'
|
|
23
|
+
export * from '../modules/events/schema.ts'
|
|
23
24
|
export * from '../modules/plans/schema.ts'
|
|
24
25
|
export * from '../modules/decisions/schema.ts'
|
|
25
26
|
export * from '../modules/notes/schema.ts'
|
package/src/testing/app.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import type { PublicRegion } from '@kelpie/schemas'
|
|
1
2
|
import type { Context, Hono } from 'hono'
|
|
2
3
|
|
|
3
4
|
import { createApp } from '../app.ts'
|
|
@@ -61,6 +62,13 @@ export interface TestAppOptions {
|
|
|
61
62
|
readonly runtimeMode?: RuntimeMode
|
|
62
63
|
/** Reported through `GET /v1/public/config`. Defaults to unset. */
|
|
63
64
|
readonly siteName?: string
|
|
65
|
+
/**
|
|
66
|
+
* Reported through `GET /v1/public/config` and consulted by the `auth`
|
|
67
|
+
* module's `signUp` and `completeExternalSignIn`. Defaults to `true` (open).
|
|
68
|
+
*/
|
|
69
|
+
readonly signupsEnabled?: boolean
|
|
70
|
+
/** Reported through `GET /v1/public/config`. Defaults to `[]`. */
|
|
71
|
+
readonly regions?: readonly PublicRegion[]
|
|
64
72
|
}
|
|
65
73
|
|
|
66
74
|
export interface TestApp {
|
|
@@ -94,7 +102,10 @@ export async function createTestApp(options: TestAppOptions = {}): Promise<TestA
|
|
|
94
102
|
...(options.entitlements === undefined ? {} : { entitlements: options.entitlements }),
|
|
95
103
|
...(options.moduleConfig === undefined ? {} : { moduleConfig: options.moduleConfig }),
|
|
96
104
|
...(options.resolveActor === undefined ? {} : { resolveActor: options.resolveActor }),
|
|
97
|
-
services
|
|
105
|
+
services: {
|
|
106
|
+
...services,
|
|
107
|
+
...(options.signupsEnabled === undefined ? {} : { signupsEnabled: options.signupsEnabled }),
|
|
108
|
+
},
|
|
98
109
|
})
|
|
99
110
|
|
|
100
111
|
const app = createApp({
|
|
@@ -108,6 +119,8 @@ export async function createTestApp(options: TestAppOptions = {}): Promise<TestA
|
|
|
108
119
|
resolveClientIp: options.resolveClientIp ?? testClientIp,
|
|
109
120
|
...(options.runtimeMode === undefined ? {} : { runtimeMode: options.runtimeMode }),
|
|
110
121
|
...(options.siteName === undefined ? {} : { siteName: options.siteName }),
|
|
122
|
+
...(options.signupsEnabled === undefined ? {} : { signupsEnabled: options.signupsEnabled }),
|
|
123
|
+
...(options.regions === undefined ? {} : { regions: options.regions }),
|
|
111
124
|
})
|
|
112
125
|
|
|
113
126
|
return { app, contributions, logLines, services }
|
package/src/testing/client.ts
CHANGED
|
@@ -132,7 +132,17 @@ export function createTestClient(app: Hono<AppBindings>, db: Database): TestClie
|
|
|
132
132
|
throw new Error(`Creating workspace ${slug} answered ${String(created.status)}`)
|
|
133
133
|
}
|
|
134
134
|
|
|
135
|
-
|
|
135
|
+
const workspaceId = readString(await created.json(), 'id')
|
|
136
|
+
const seeded = await send('POST', `/v1/workspaces/${workspaceId}/handbook/seed`, {
|
|
137
|
+
body: { handbook_template: 'startup' },
|
|
138
|
+
cookie,
|
|
139
|
+
})
|
|
140
|
+
|
|
141
|
+
if (seeded.status !== 201) {
|
|
142
|
+
throw new Error(`Seeding handbook for ${slug} answered ${String(seeded.status)}`)
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
return { cookie, workspaceId }
|
|
136
146
|
},
|
|
137
147
|
}
|
|
138
148
|
}
|