@agilesyndrome/cf-genai-base 5.0.2 → 6.0.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/CHANGELOG.md +99 -0
- package/CLI.md +9 -13
- package/CONTRACT.md +32 -15
- package/README.md +95 -28
- package/bin/cf-genai.js +24 -8
- package/dist/admin/auth.d.ts +12 -0
- package/dist/admin/auth.d.ts.map +1 -0
- package/dist/admin/auth.js +103 -0
- package/dist/admin/auth.js.map +1 -0
- package/dist/admin/index.d.ts +2 -0
- package/dist/admin/index.d.ts.map +1 -0
- package/dist/admin/index.js +2 -0
- package/dist/admin/index.js.map +1 -0
- package/dist/admin/router.d.ts +4 -0
- package/dist/admin/router.d.ts.map +1 -0
- package/dist/admin/router.js +24 -0
- package/dist/admin/router.js.map +1 -0
- package/dist/admin/types.d.ts +43 -0
- package/dist/admin/types.d.ts.map +1 -0
- package/dist/admin/types.js +2 -0
- package/dist/admin/types.js.map +1 -0
- package/dist/api/client.d.ts +34 -0
- package/dist/api/client.d.ts.map +1 -0
- package/dist/api/client.js +59 -0
- package/dist/api/client.js.map +1 -0
- package/dist/api/contracts.d.ts +31 -0
- package/dist/api/contracts.d.ts.map +1 -0
- package/dist/api/contracts.js +101 -0
- package/dist/api/contracts.js.map +1 -0
- package/dist/api/http.d.ts +12 -0
- package/dist/api/http.d.ts.map +1 -0
- package/dist/api/http.js +36 -0
- package/dist/api/http.js.map +1 -0
- package/dist/api/index.d.ts +14 -0
- package/dist/api/index.d.ts.map +1 -0
- package/dist/api/index.js +11 -0
- package/dist/api/index.js.map +1 -0
- package/dist/api/testing.d.ts +10 -0
- package/dist/api/testing.d.ts.map +1 -0
- package/dist/api/testing.js +26 -0
- package/dist/api/testing.js.map +1 -0
- package/dist/app.d.ts +21 -0
- package/dist/app.d.ts.map +1 -0
- package/dist/app.js +23 -0
- package/dist/app.js.map +1 -0
- package/dist/auth/constants.d.ts +9 -0
- package/dist/auth/constants.d.ts.map +1 -0
- package/{src → dist}/auth/constants.js +2 -2
- package/dist/auth/constants.js.map +1 -0
- package/dist/auth/domains.d.ts +3 -0
- package/dist/auth/domains.d.ts.map +1 -0
- package/dist/auth/domains.js +8 -0
- package/dist/auth/domains.js.map +1 -0
- package/dist/auth/encoding.d.ts +7 -0
- package/dist/auth/encoding.d.ts.map +1 -0
- package/dist/auth/encoding.js +41 -0
- package/dist/auth/encoding.js.map +1 -0
- package/dist/auth/groups/d1.d.ts +16 -0
- package/dist/auth/groups/d1.d.ts.map +1 -0
- package/dist/auth/groups/d1.js +66 -0
- package/dist/auth/groups/d1.js.map +1 -0
- package/dist/auth/groups/domain.d.ts +8 -0
- package/dist/auth/groups/domain.d.ts.map +1 -0
- package/dist/auth/groups/domain.js +99 -0
- package/dist/auth/groups/domain.js.map +1 -0
- package/dist/auth/groups/index.d.ts +7 -0
- package/dist/auth/groups/index.d.ts.map +1 -0
- package/dist/auth/groups/index.js +7 -0
- package/dist/auth/groups/index.js.map +1 -0
- package/dist/auth/groups/model.d.ts +38 -0
- package/dist/auth/groups/model.d.ts.map +1 -0
- package/dist/auth/groups/model.js +2 -0
- package/dist/auth/groups/model.js.map +1 -0
- package/dist/auth/groups/policy.d.ts +5 -0
- package/dist/auth/groups/policy.d.ts.map +1 -0
- package/dist/auth/groups/policy.js +8 -0
- package/dist/auth/groups/policy.js.map +1 -0
- package/dist/auth/groups/service.d.ts +20 -0
- package/dist/auth/groups/service.d.ts.map +1 -0
- package/dist/auth/groups/service.js +40 -0
- package/dist/auth/groups/service.js.map +1 -0
- package/dist/auth/groups/validation.d.ts +5 -0
- package/dist/auth/groups/validation.d.ts.map +1 -0
- package/dist/auth/groups/validation.js +22 -0
- package/dist/auth/groups/validation.js.map +1 -0
- package/dist/auth/groups/views/list.d.ts +10 -0
- package/dist/auth/groups/views/list.d.ts.map +1 -0
- package/dist/auth/groups/views/list.js +4 -0
- package/dist/auth/groups/views/list.js.map +1 -0
- package/dist/auth/identity/index.d.ts +58 -0
- package/dist/auth/identity/index.d.ts.map +1 -0
- package/dist/auth/identity/index.js +58 -0
- package/dist/auth/identity/index.js.map +1 -0
- package/dist/auth/impersonation/constants.d.ts +2 -0
- package/dist/auth/impersonation/constants.d.ts.map +1 -0
- package/dist/auth/impersonation/constants.js +2 -0
- package/dist/auth/impersonation/constants.js.map +1 -0
- package/dist/auth/impersonation/domain.d.ts +6 -0
- package/dist/auth/impersonation/domain.d.ts.map +1 -0
- package/dist/auth/impersonation/domain.js +16 -0
- package/dist/auth/impersonation/domain.js.map +1 -0
- package/dist/auth/impersonation/index.d.ts +6 -0
- package/dist/auth/impersonation/index.d.ts.map +1 -0
- package/dist/auth/impersonation/index.js +6 -0
- package/dist/auth/impersonation/index.js.map +1 -0
- package/dist/auth/impersonation/model.d.ts +12 -0
- package/dist/auth/impersonation/model.d.ts.map +1 -0
- package/dist/auth/impersonation/model.js +2 -0
- package/dist/auth/impersonation/model.js.map +1 -0
- package/dist/auth/impersonation/service.d.ts +4 -0
- package/dist/auth/impersonation/service.d.ts.map +1 -0
- package/dist/auth/impersonation/service.js +32 -0
- package/dist/auth/impersonation/service.js.map +1 -0
- package/dist/auth/impersonation/validation.d.ts +4 -0
- package/dist/auth/impersonation/validation.d.ts.map +1 -0
- package/dist/auth/impersonation/validation.js +14 -0
- package/dist/auth/impersonation/validation.js.map +1 -0
- package/dist/auth/index.d.ts +13 -0
- package/dist/auth/index.d.ts.map +1 -0
- package/dist/auth/index.js +13 -0
- package/dist/auth/index.js.map +1 -0
- package/dist/auth/oauth-single/constants.d.ts +4 -0
- package/dist/auth/oauth-single/constants.d.ts.map +1 -0
- package/dist/auth/oauth-single/constants.js +5 -0
- package/dist/auth/oauth-single/constants.js.map +1 -0
- package/dist/auth/oauth-single/cookies.d.ts +10 -0
- package/dist/auth/oauth-single/cookies.d.ts.map +1 -0
- package/dist/auth/oauth-single/cookies.js +59 -0
- package/dist/auth/oauth-single/cookies.js.map +1 -0
- package/dist/auth/oauth-single/domain.d.ts +14 -0
- package/dist/auth/oauth-single/domain.d.ts.map +1 -0
- package/dist/auth/oauth-single/domain.js +12 -0
- package/dist/auth/oauth-single/domain.js.map +1 -0
- package/dist/auth/oauth-single/index.d.ts +31 -0
- package/dist/auth/oauth-single/index.d.ts.map +1 -0
- package/dist/auth/oauth-single/index.js +215 -0
- package/dist/auth/oauth-single/index.js.map +1 -0
- package/dist/auth/oauth-single/model.d.ts +75 -0
- package/dist/auth/oauth-single/model.d.ts.map +1 -0
- package/dist/auth/oauth-single/model.js +2 -0
- package/dist/auth/oauth-single/model.js.map +1 -0
- package/dist/auth/oauth-single/protocol.d.ts +9 -0
- package/dist/auth/oauth-single/protocol.d.ts.map +1 -0
- package/dist/auth/oauth-single/protocol.js +190 -0
- package/dist/auth/oauth-single/protocol.js.map +1 -0
- package/dist/auth/oauth-single/session.d.ts +7 -0
- package/dist/auth/oauth-single/session.d.ts.map +1 -0
- package/dist/auth/oauth-single/session.js +78 -0
- package/dist/auth/oauth-single/session.js.map +1 -0
- package/dist/auth/repositories.d.ts +58 -0
- package/dist/auth/repositories.d.ts.map +1 -0
- package/dist/auth/repositories.js +31 -0
- package/dist/auth/repositories.js.map +1 -0
- package/dist/auth/scopes/d1.d.ts +17 -0
- package/dist/auth/scopes/d1.d.ts.map +1 -0
- package/dist/auth/scopes/d1.js +54 -0
- package/dist/auth/scopes/d1.js.map +1 -0
- package/dist/auth/scopes/domain.d.ts +7 -0
- package/dist/auth/scopes/domain.d.ts.map +1 -0
- package/dist/auth/scopes/domain.js +25 -0
- package/dist/auth/scopes/domain.js.map +1 -0
- package/dist/auth/scopes/index.d.ts +4 -0
- package/dist/auth/scopes/index.d.ts.map +1 -0
- package/dist/auth/scopes/index.js +4 -0
- package/dist/auth/scopes/index.js.map +1 -0
- package/dist/auth/scopes/model.d.ts +26 -0
- package/dist/auth/scopes/model.d.ts.map +1 -0
- package/dist/auth/scopes/model.js +2 -0
- package/dist/auth/scopes/model.js.map +1 -0
- package/dist/auth/scopes/policy.d.ts +3 -0
- package/dist/auth/scopes/policy.d.ts.map +1 -0
- package/dist/auth/scopes/policy.js +4 -0
- package/dist/auth/scopes/policy.js.map +1 -0
- package/dist/auth/scopes/service.d.ts +4 -0
- package/dist/auth/scopes/service.d.ts.map +1 -0
- package/dist/auth/scopes/service.js +4 -0
- package/dist/auth/scopes/service.js.map +1 -0
- package/dist/auth/scopes/validation.d.ts +6 -0
- package/dist/auth/scopes/validation.d.ts.map +1 -0
- package/dist/auth/scopes/validation.js +33 -0
- package/dist/auth/scopes/validation.js.map +1 -0
- package/dist/auth/scopes/views/list.d.ts +9 -0
- package/dist/auth/scopes/views/list.d.ts.map +1 -0
- package/dist/auth/scopes/views/list.js +4 -0
- package/dist/auth/scopes/views/list.js.map +1 -0
- package/dist/auth/subscriptions/d1.d.ts +10 -0
- package/dist/auth/subscriptions/d1.d.ts.map +1 -0
- package/dist/auth/subscriptions/d1.js +86 -0
- package/dist/auth/subscriptions/d1.js.map +1 -0
- package/dist/auth/subscriptions/domain.d.ts +10 -0
- package/dist/auth/subscriptions/domain.d.ts.map +1 -0
- package/dist/auth/subscriptions/domain.js +33 -0
- package/dist/auth/subscriptions/domain.js.map +1 -0
- package/dist/auth/subscriptions/index.d.ts +6 -0
- package/dist/auth/subscriptions/index.d.ts.map +1 -0
- package/dist/auth/subscriptions/index.js +6 -0
- package/dist/auth/subscriptions/index.js.map +1 -0
- package/dist/auth/subscriptions/model.d.ts +20 -0
- package/dist/auth/subscriptions/model.d.ts.map +1 -0
- package/dist/auth/subscriptions/model.js +2 -0
- package/dist/auth/subscriptions/model.js.map +1 -0
- package/dist/auth/subscriptions/service.d.ts +12 -0
- package/dist/auth/subscriptions/service.d.ts.map +1 -0
- package/dist/auth/subscriptions/service.js +71 -0
- package/dist/auth/subscriptions/service.js.map +1 -0
- package/dist/auth/subscriptions/validation.d.ts +3 -0
- package/dist/auth/subscriptions/validation.d.ts.map +1 -0
- package/dist/auth/subscriptions/validation.js +21 -0
- package/dist/auth/subscriptions/validation.js.map +1 -0
- package/dist/auth/tenants/d1.d.ts +12 -0
- package/dist/auth/tenants/d1.d.ts.map +1 -0
- package/dist/auth/tenants/d1.js +40 -0
- package/dist/auth/tenants/d1.js.map +1 -0
- package/dist/auth/tenants/delete.d.ts +3 -0
- package/dist/auth/tenants/delete.d.ts.map +1 -0
- package/dist/auth/tenants/delete.js +28 -0
- package/dist/auth/tenants/delete.js.map +1 -0
- package/dist/auth/tenants/domain.d.ts +8 -0
- package/dist/auth/tenants/domain.d.ts.map +1 -0
- package/dist/auth/tenants/domain.js +64 -0
- package/dist/auth/tenants/domain.js.map +1 -0
- package/dist/auth/tenants/index.d.ts +7 -0
- package/dist/auth/tenants/index.d.ts.map +1 -0
- package/dist/auth/tenants/index.js +7 -0
- package/dist/auth/tenants/index.js.map +1 -0
- package/dist/auth/tenants/model.d.ts +28 -0
- package/dist/auth/tenants/model.d.ts.map +1 -0
- package/dist/auth/tenants/model.js +2 -0
- package/dist/auth/tenants/model.js.map +1 -0
- package/dist/auth/tenants/policy.d.ts +3 -0
- package/dist/auth/tenants/policy.d.ts.map +1 -0
- package/dist/auth/tenants/policy.js +4 -0
- package/dist/auth/tenants/policy.js.map +1 -0
- package/dist/auth/tenants/service.d.ts +14 -0
- package/dist/auth/tenants/service.d.ts.map +1 -0
- package/dist/auth/tenants/service.js +37 -0
- package/dist/auth/tenants/service.js.map +1 -0
- package/dist/auth/tenants/validation.d.ts +5 -0
- package/dist/auth/tenants/validation.d.ts.map +1 -0
- package/dist/auth/tenants/validation.js +21 -0
- package/dist/auth/tenants/validation.js.map +1 -0
- package/dist/auth/tenants/views/list.d.ts +8 -0
- package/dist/auth/tenants/views/list.d.ts.map +1 -0
- package/dist/auth/tenants/views/list.js +3 -0
- package/dist/auth/tenants/views/list.js.map +1 -0
- package/dist/auth/users/access.d.ts +9 -0
- package/dist/auth/users/access.d.ts.map +1 -0
- package/dist/auth/users/access.js +53 -0
- package/dist/auth/users/access.js.map +1 -0
- package/dist/auth/users/d1.d.ts +19 -0
- package/dist/auth/users/d1.d.ts.map +1 -0
- package/dist/auth/users/d1.js +68 -0
- package/dist/auth/users/d1.js.map +1 -0
- package/dist/auth/users/domain.d.ts +13 -0
- package/dist/auth/users/domain.d.ts.map +1 -0
- package/dist/auth/users/domain.js +129 -0
- package/dist/auth/users/domain.js.map +1 -0
- package/dist/auth/users/index.d.ts +7 -0
- package/dist/auth/users/index.d.ts.map +1 -0
- package/dist/auth/users/index.js +7 -0
- package/dist/auth/users/index.js.map +1 -0
- package/dist/auth/users/model.d.ts +44 -0
- package/dist/auth/users/model.d.ts.map +1 -0
- package/dist/auth/users/model.js +2 -0
- package/dist/auth/users/model.js.map +1 -0
- package/dist/auth/users/service.d.ts +8 -0
- package/dist/auth/users/service.d.ts.map +1 -0
- package/dist/auth/users/service.js +62 -0
- package/dist/auth/users/service.js.map +1 -0
- package/dist/auth/users/validation.d.ts +4 -0
- package/dist/auth/users/validation.d.ts.map +1 -0
- package/dist/auth/users/validation.js +23 -0
- package/dist/auth/users/validation.js.map +1 -0
- package/dist/cli/cli.d.ts +9 -0
- package/dist/cli/cli.d.ts.map +1 -0
- package/dist/cli/cli.js +201 -0
- package/dist/cli/cli.js.map +1 -0
- package/dist/cli/d1.d.ts +24 -0
- package/dist/cli/d1.d.ts.map +1 -0
- package/dist/cli/d1.js +175 -0
- package/dist/cli/d1.js.map +1 -0
- package/dist/cli/operations.d.ts +3 -0
- package/dist/cli/operations.d.ts.map +1 -0
- package/dist/cli/operations.js +63 -0
- package/dist/cli/operations.js.map +1 -0
- package/dist/cli/project.d.ts +136 -0
- package/dist/cli/project.d.ts.map +1 -0
- package/dist/cli/project.js +738 -0
- package/dist/cli/project.js.map +1 -0
- package/dist/cli/status.d.ts +24 -0
- package/dist/cli/status.d.ts.map +1 -0
- package/dist/cli/status.js +55 -0
- package/dist/cli/status.js.map +1 -0
- package/dist/cli/tenants.d.ts +9 -0
- package/dist/cli/tenants.d.ts.map +1 -0
- package/dist/cli/tenants.js +32 -0
- package/dist/cli/tenants.js.map +1 -0
- package/dist/cli/types.d.ts +43 -0
- package/dist/cli/types.d.ts.map +1 -0
- package/dist/cli/types.js +2 -0
- package/dist/cli/types.js.map +1 -0
- package/dist/cli/users.d.ts +8 -0
- package/dist/cli/users.d.ts.map +1 -0
- package/dist/cli/users.js +74 -0
- package/dist/cli/users.js.map +1 -0
- package/dist/cli/version.d.ts +12 -0
- package/dist/cli/version.d.ts.map +1 -0
- package/dist/cli/version.js +60 -0
- package/dist/cli/version.js.map +1 -0
- package/dist/core/circuits/availability.d.ts +48 -0
- package/dist/core/circuits/availability.d.ts.map +1 -0
- package/dist/core/circuits/availability.js +87 -0
- package/dist/core/circuits/availability.js.map +1 -0
- package/dist/core/circuits/d1.d.ts +11 -0
- package/dist/core/circuits/d1.d.ts.map +1 -0
- package/dist/core/circuits/d1.js +83 -0
- package/dist/core/circuits/d1.js.map +1 -0
- package/dist/core/circuits/domain.d.ts +7 -0
- package/dist/core/circuits/domain.d.ts.map +1 -0
- package/dist/core/circuits/domain.js +36 -0
- package/dist/core/circuits/domain.js.map +1 -0
- package/dist/core/circuits/index.d.ts +6 -0
- package/dist/core/circuits/index.d.ts.map +1 -0
- package/dist/core/circuits/index.js +6 -0
- package/dist/core/circuits/index.js.map +1 -0
- package/dist/core/circuits/model.d.ts +50 -0
- package/dist/core/circuits/model.d.ts.map +1 -0
- package/dist/core/circuits/model.js +2 -0
- package/dist/core/circuits/model.js.map +1 -0
- package/dist/core/circuits/service.d.ts +9 -0
- package/dist/core/circuits/service.d.ts.map +1 -0
- package/dist/core/circuits/service.js +63 -0
- package/dist/core/circuits/service.js.map +1 -0
- package/dist/core/circuits/validation.d.ts +4 -0
- package/dist/core/circuits/validation.d.ts.map +1 -0
- package/dist/core/circuits/validation.js +35 -0
- package/dist/core/circuits/validation.js.map +1 -0
- package/dist/core/constants.d.ts +9 -0
- package/dist/core/constants.d.ts.map +1 -0
- package/{src → dist}/core/constants.js +2 -1
- package/dist/core/constants.js.map +1 -0
- package/dist/core/database/index.d.ts +14 -0
- package/dist/core/database/index.d.ts.map +1 -0
- package/dist/core/database/index.js +65 -0
- package/dist/core/database/index.js.map +1 -0
- package/dist/core/domains.d.ts +2 -0
- package/dist/core/domains.d.ts.map +1 -0
- package/dist/core/domains.js +7 -0
- package/dist/core/domains.js.map +1 -0
- package/dist/core/events/audit.d.ts +8 -0
- package/dist/core/events/audit.d.ts.map +1 -0
- package/dist/core/events/audit.js +27 -0
- package/dist/core/events/audit.js.map +1 -0
- package/dist/core/events/domain.d.ts +19 -0
- package/dist/core/events/domain.d.ts.map +1 -0
- package/dist/core/events/domain.js +39 -0
- package/dist/core/events/domain.js.map +1 -0
- package/dist/core/events/hub.d.ts +10 -0
- package/dist/core/events/hub.d.ts.map +1 -0
- package/dist/core/events/hub.js +56 -0
- package/dist/core/events/hub.js.map +1 -0
- package/dist/core/events/index.d.ts +57 -0
- package/dist/core/events/index.d.ts.map +1 -0
- package/dist/core/events/index.js +170 -0
- package/dist/core/events/index.js.map +1 -0
- package/dist/core/healthchecks/d1.d.ts +7 -0
- package/dist/core/healthchecks/d1.d.ts.map +1 -0
- package/dist/core/healthchecks/d1.js +43 -0
- package/dist/core/healthchecks/d1.js.map +1 -0
- package/dist/core/healthchecks/domain.d.ts +7 -0
- package/dist/core/healthchecks/domain.d.ts.map +1 -0
- package/dist/core/healthchecks/domain.js +51 -0
- package/dist/core/healthchecks/domain.js.map +1 -0
- package/dist/core/healthchecks/features.d.ts +19 -0
- package/dist/core/healthchecks/features.d.ts.map +1 -0
- package/dist/core/healthchecks/features.js +100 -0
- package/dist/core/healthchecks/features.js.map +1 -0
- package/dist/core/healthchecks/index.d.ts +6 -0
- package/dist/core/healthchecks/index.d.ts.map +1 -0
- package/dist/core/healthchecks/index.js +6 -0
- package/dist/core/healthchecks/index.js.map +1 -0
- package/dist/core/healthchecks/model.d.ts +64 -0
- package/dist/core/healthchecks/model.d.ts.map +1 -0
- package/dist/core/healthchecks/model.js +2 -0
- package/dist/core/healthchecks/model.js.map +1 -0
- package/dist/core/healthchecks/service.d.ts +8 -0
- package/dist/core/healthchecks/service.d.ts.map +1 -0
- package/dist/core/healthchecks/service.js +29 -0
- package/dist/core/healthchecks/service.js.map +1 -0
- package/dist/core/healthchecks/validation.d.ts +5 -0
- package/dist/core/healthchecks/validation.d.ts.map +1 -0
- package/dist/core/healthchecks/validation.js +51 -0
- package/dist/core/healthchecks/validation.js.map +1 -0
- package/dist/core/index.d.ts +9 -0
- package/dist/core/index.d.ts.map +1 -0
- package/dist/core/index.js +9 -0
- package/dist/core/index.js.map +1 -0
- package/dist/core/jobs/d1.d.ts +19 -0
- package/dist/core/jobs/d1.d.ts.map +1 -0
- package/dist/core/jobs/d1.js +139 -0
- package/dist/core/jobs/d1.js.map +1 -0
- package/dist/core/jobs/domain.d.ts +8 -0
- package/dist/core/jobs/domain.d.ts.map +1 -0
- package/dist/core/jobs/domain.js +59 -0
- package/dist/core/jobs/domain.js.map +1 -0
- package/dist/core/jobs/events.d.ts +3 -0
- package/dist/core/jobs/events.d.ts.map +1 -0
- package/dist/core/jobs/events.js +25 -0
- package/dist/core/jobs/events.js.map +1 -0
- package/dist/core/jobs/index.d.ts +7 -0
- package/dist/core/jobs/index.d.ts.map +1 -0
- package/dist/core/jobs/index.js +7 -0
- package/dist/core/jobs/index.js.map +1 -0
- package/dist/core/jobs/model.d.ts +86 -0
- package/dist/core/jobs/model.d.ts.map +1 -0
- package/dist/core/jobs/model.js +2 -0
- package/dist/core/jobs/model.js.map +1 -0
- package/dist/core/jobs/service.d.ts +39 -0
- package/dist/core/jobs/service.d.ts.map +1 -0
- package/dist/core/jobs/service.js +84 -0
- package/dist/core/jobs/service.js.map +1 -0
- package/dist/core/jobs/validation.d.ts +8 -0
- package/dist/core/jobs/validation.d.ts.map +1 -0
- package/dist/core/jobs/validation.js +39 -0
- package/dist/core/jobs/validation.js.map +1 -0
- package/dist/core/security/index.d.ts +30 -0
- package/dist/core/security/index.d.ts.map +1 -0
- package/dist/core/security/index.js +138 -0
- package/dist/core/security/index.js.map +1 -0
- package/dist/data/context.d.ts +20 -0
- package/dist/data/context.d.ts.map +1 -0
- package/dist/data/context.js +65 -0
- package/dist/data/context.js.map +1 -0
- package/dist/data/index.d.ts +5 -0
- package/dist/data/index.d.ts.map +1 -0
- package/{src → dist}/data/index.js +2 -0
- package/dist/data/index.js.map +1 -0
- package/dist/data/json.d.ts +3 -0
- package/dist/data/json.d.ts.map +1 -0
- package/dist/data/json.js +14 -0
- package/dist/data/json.js.map +1 -0
- package/dist/data/model.d.ts +96 -0
- package/dist/data/model.d.ts.map +1 -0
- package/dist/data/model.js +3 -0
- package/dist/data/model.js.map +1 -0
- package/dist/data/policy.d.ts +14 -0
- package/dist/data/policy.d.ts.map +1 -0
- package/dist/data/policy.js +89 -0
- package/dist/data/policy.js.map +1 -0
- package/dist/data/reader.d.ts +9 -0
- package/dist/data/reader.d.ts.map +1 -0
- package/dist/data/reader.js +203 -0
- package/dist/data/reader.js.map +1 -0
- package/dist/data/resources.d.ts +9 -0
- package/dist/data/resources.d.ts.map +1 -0
- package/dist/data/resources.js +129 -0
- package/dist/data/resources.js.map +1 -0
- package/dist/domain/app-domain.d.ts +36 -0
- package/dist/domain/app-domain.d.ts.map +1 -0
- package/dist/domain/app-domain.js +79 -0
- package/dist/domain/app-domain.js.map +1 -0
- package/dist/domain/index.d.ts +3 -0
- package/dist/domain/index.d.ts.map +1 -0
- package/dist/domain/index.js +3 -0
- package/dist/domain/index.js.map +1 -0
- package/dist/domain/model.d.ts +37 -0
- package/dist/domain/model.d.ts.map +1 -0
- package/dist/domain/model.js +2 -0
- package/dist/domain/model.js.map +1 -0
- package/dist/features/index.d.ts +25 -0
- package/dist/features/index.d.ts.map +1 -0
- package/dist/features/index.js +61 -0
- package/dist/features/index.js.map +1 -0
- package/dist/features/llm/client.d.ts +3 -0
- package/dist/features/llm/client.d.ts.map +1 -0
- package/dist/features/llm/client.js +327 -0
- package/dist/features/llm/client.js.map +1 -0
- package/dist/features/llm/config.d.ts +7 -0
- package/dist/features/llm/config.d.ts.map +1 -0
- package/dist/features/llm/config.js +93 -0
- package/dist/features/llm/config.js.map +1 -0
- package/dist/features/llm/constants.d.ts +5 -0
- package/dist/features/llm/constants.d.ts.map +1 -0
- package/dist/features/llm/constants.js +6 -0
- package/dist/features/llm/constants.js.map +1 -0
- package/dist/features/llm/errors.d.ts +12 -0
- package/dist/features/llm/errors.d.ts.map +1 -0
- package/dist/features/llm/errors.js +19 -0
- package/dist/features/llm/errors.js.map +1 -0
- package/dist/features/llm/feature.d.ts +6 -0
- package/dist/features/llm/feature.d.ts.map +1 -0
- package/dist/features/llm/feature.js +37 -0
- package/dist/features/llm/feature.js.map +1 -0
- package/dist/features/llm/index.d.ts +9 -0
- package/dist/features/llm/index.d.ts.map +1 -0
- package/dist/features/llm/index.js +6 -0
- package/dist/features/llm/index.js.map +1 -0
- package/dist/features/llm/model.d.ts +171 -0
- package/dist/features/llm/model.d.ts.map +1 -0
- package/dist/features/llm/model.js +2 -0
- package/dist/features/llm/model.js.map +1 -0
- package/dist/features/llm/schema.d.ts +4 -0
- package/dist/features/llm/schema.d.ts.map +1 -0
- package/dist/features/llm/schema.js +82 -0
- package/dist/features/llm/schema.js.map +1 -0
- package/dist/features/llm/service.d.ts +29 -0
- package/dist/features/llm/service.d.ts.map +1 -0
- package/dist/features/llm/service.js +55 -0
- package/dist/features/llm/service.js.map +1 -0
- package/dist/features/messaging/constants.d.ts +3 -0
- package/dist/features/messaging/constants.d.ts.map +1 -0
- package/dist/features/messaging/constants.js +4 -0
- package/dist/features/messaging/constants.js.map +1 -0
- package/dist/features/messaging/domain.d.ts +9 -0
- package/dist/features/messaging/domain.d.ts.map +1 -0
- package/dist/features/messaging/domain.js +14 -0
- package/dist/features/messaging/domain.js.map +1 -0
- package/dist/features/messaging/feature.d.ts +7 -0
- package/dist/features/messaging/feature.d.ts.map +1 -0
- package/dist/features/messaging/feature.js +23 -0
- package/dist/features/messaging/feature.js.map +1 -0
- package/dist/features/messaging/index.d.ts +12 -0
- package/dist/features/messaging/index.d.ts.map +1 -0
- package/dist/features/messaging/index.js +8 -0
- package/dist/features/messaging/index.js.map +1 -0
- package/dist/features/messaging/jobs.d.ts +38 -0
- package/dist/features/messaging/jobs.d.ts.map +1 -0
- package/dist/features/messaging/jobs.js +40 -0
- package/dist/features/messaging/jobs.js.map +1 -0
- package/dist/features/messaging/models.d.ts +65 -0
- package/dist/features/messaging/models.d.ts.map +1 -0
- package/dist/features/messaging/models.js +97 -0
- package/dist/features/messaging/models.js.map +1 -0
- package/dist/features/messaging/resources.d.ts +8 -0
- package/dist/features/messaging/resources.d.ts.map +1 -0
- package/dist/features/messaging/resources.js +11 -0
- package/dist/features/messaging/resources.js.map +1 -0
- package/dist/features/messaging/store.d.ts +46 -0
- package/dist/features/messaging/store.d.ts.map +1 -0
- package/dist/features/messaging/store.js +208 -0
- package/dist/features/messaging/store.js.map +1 -0
- package/dist/index.d.ts +20 -0
- package/dist/index.d.ts.map +1 -0
- package/{src → dist}/index.js +7 -2
- package/dist/index.js.map +1 -0
- package/dist/input.d.ts +18 -0
- package/dist/input.d.ts.map +1 -0
- package/dist/input.js +49 -0
- package/dist/input.js.map +1 -0
- package/dist/repository/model.d.ts +61 -0
- package/dist/repository/model.d.ts.map +1 -0
- package/dist/repository/model.js +2 -0
- package/dist/repository/model.js.map +1 -0
- package/dist/repository.d.ts +11 -0
- package/dist/repository.d.ts.map +1 -0
- package/dist/repository.js +118 -0
- package/dist/repository.js.map +1 -0
- package/dist/runtime/domains.d.ts +14 -0
- package/dist/runtime/domains.d.ts.map +1 -0
- package/dist/runtime/domains.js +42 -0
- package/dist/runtime/domains.js.map +1 -0
- package/dist/runtime/features.d.ts +10 -0
- package/dist/runtime/features.d.ts.map +1 -0
- package/dist/runtime/features.js +37 -0
- package/dist/runtime/features.js.map +1 -0
- package/dist/runtime/health.d.ts +6 -0
- package/dist/runtime/health.d.ts.map +1 -0
- package/dist/runtime/health.js +28 -0
- package/dist/runtime/health.js.map +1 -0
- package/dist/runtime/hono.d.ts +30 -0
- package/dist/runtime/hono.d.ts.map +1 -0
- package/dist/runtime/hono.js +50 -0
- package/dist/runtime/hono.js.map +1 -0
- package/dist/runtime/model.d.ts +133 -0
- package/dist/runtime/model.d.ts.map +1 -0
- package/dist/runtime/model.js +2 -0
- package/dist/runtime/model.js.map +1 -0
- package/dist/runtime/responses.d.ts +9 -0
- package/dist/runtime/responses.d.ts.map +1 -0
- package/dist/runtime/responses.js +14 -0
- package/dist/runtime/responses.js.map +1 -0
- package/dist/runtime/worker.d.ts +10 -0
- package/dist/runtime/worker.d.ts.map +1 -0
- package/dist/runtime/worker.js +216 -0
- package/dist/runtime/worker.js.map +1 -0
- package/dist/ui/index.d.ts +3 -0
- package/dist/ui/index.d.ts.map +1 -0
- package/dist/ui/index.js +3 -0
- package/dist/ui/index.js.map +1 -0
- package/dist/ui/react/admin-access.d.ts +2 -0
- package/dist/ui/react/admin-access.d.ts.map +1 -0
- package/dist/ui/react/admin-access.js +47 -0
- package/dist/ui/react/admin-access.js.map +1 -0
- package/dist/ui/react/admin-audit.d.ts +2 -0
- package/dist/ui/react/admin-audit.d.ts.map +1 -0
- package/dist/ui/react/admin-audit.js +13 -0
- package/dist/ui/react/admin-audit.js.map +1 -0
- package/dist/ui/react/admin-catalogs.d.ts +6 -0
- package/dist/ui/react/admin-catalogs.d.ts.map +1 -0
- package/dist/ui/react/admin-catalogs.js +37 -0
- package/dist/ui/react/admin-catalogs.js.map +1 -0
- package/dist/ui/react/admin-dashboard.d.ts +39 -0
- package/dist/ui/react/admin-dashboard.d.ts.map +1 -0
- package/dist/ui/react/admin-dashboard.js +135 -0
- package/dist/ui/react/admin-dashboard.js.map +1 -0
- package/dist/ui/react/admin-details.d.ts +27 -0
- package/dist/ui/react/admin-details.d.ts.map +1 -0
- package/dist/ui/react/admin-details.js +82 -0
- package/dist/ui/react/admin-details.js.map +1 -0
- package/dist/ui/react/admin-shell.d.ts +20 -0
- package/dist/ui/react/admin-shell.d.ts.map +1 -0
- package/dist/ui/react/admin-shell.js +24 -0
- package/dist/ui/react/admin-shell.js.map +1 -0
- package/dist/ui/react/bootstrap.d.ts +9 -0
- package/dist/ui/react/bootstrap.d.ts.map +1 -0
- package/dist/ui/react/bootstrap.js +45 -0
- package/dist/ui/react/bootstrap.js.map +1 -0
- package/dist/ui/react/foundation.d.ts +35 -0
- package/dist/ui/react/foundation.d.ts.map +1 -0
- package/dist/ui/react/foundation.js +62 -0
- package/dist/ui/react/foundation.js.map +1 -0
- package/dist/ui/react/index.d.ts +12 -0
- package/dist/ui/react/index.d.ts.map +1 -0
- package/dist/ui/react/index.js +12 -0
- package/dist/ui/react/index.js.map +1 -0
- package/dist/ui/react/jobs.d.ts +62 -0
- package/dist/ui/react/jobs.d.ts.map +1 -0
- package/dist/ui/react/jobs.js +114 -0
- package/dist/ui/react/jobs.js.map +1 -0
- package/dist/ui/react/live-events.d.ts +18 -0
- package/dist/ui/react/live-events.d.ts.map +1 -0
- package/dist/ui/react/live-events.js +94 -0
- package/dist/ui/react/live-events.js.map +1 -0
- package/dist/ui/react/types.d.ts +79 -0
- package/dist/ui/react/types.d.ts.map +1 -0
- package/dist/ui/react/types.js +32 -0
- package/dist/ui/react/types.js.map +1 -0
- package/dist/ui/ssr.d.ts +55 -0
- package/dist/ui/ssr.d.ts.map +1 -0
- package/dist/ui/ssr.js +30 -0
- package/dist/ui/ssr.js.map +1 -0
- package/{src → dist}/ui/styles.css +22 -1
- package/migrations/0007_messaging.sql +52 -0
- package/migrations/0008_messaging_tenant_integrity.sql +44 -0
- package/migrations/0009_healthcheck_measurements.sql +3 -0
- package/migrations/0010_admin_dashboard_refinements.sql +24 -0
- package/package.json +162 -21
- package/changelog.md +0 -25
- package/src/admin/index.js +0 -1
- package/src/admin/routes.js +0 -64
- package/src/api/client.js +0 -8
- package/src/api/contracts.js +0 -24
- package/src/api/index.js +0 -7
- package/src/api/jobs.js +0 -37
- package/src/api/testing.js +0 -13
- package/src/app.js +0 -5
- package/src/auth/encoding.js +0 -6
- package/src/auth/groups.js +0 -5
- package/src/auth/impersonation.js +0 -15
- package/src/auth/index.js +0 -8
- package/src/auth/oauth-single.js +0 -204
- package/src/auth/scopes.js +0 -32
- package/src/auth/subscriptions.js +0 -42
- package/src/auth/tenants.js +0 -34
- package/src/auth/users.js +0 -40
- package/src/cli/cli.js +0 -133
- package/src/cli/d1.js +0 -165
- package/src/cli/operations.js +0 -34
- package/src/cli/project.js +0 -560
- package/src/cli/status.js +0 -46
- package/src/cli/tenants.js +0 -16
- package/src/cli/users.js +0 -34
- package/src/cli/version.js +0 -54
- package/src/core/circuits.js +0 -134
- package/src/core/d1.js +0 -54
- package/src/core/event-hub.js +0 -29
- package/src/core/events.js +0 -63
- package/src/core/identity.js +0 -39
- package/src/core/index.js +0 -7
- package/src/core/jobs.js +0 -185
- package/src/core/security.js +0 -88
- package/src/data/context.js +0 -16
- package/src/data/reader.js +0 -63
- package/src/data/resources.js +0 -42
- package/src/repository.js +0 -63
- package/src/runtime/features.js +0 -17
- package/src/runtime/health.js +0 -17
- package/src/runtime/worker.js +0 -58
- package/src/ui/index.js +0 -1
- package/src/ui/react/admin-access.jsx +0 -29
- package/src/ui/react/admin-catalogs.jsx +0 -39
- package/src/ui/react/admin-shell.jsx +0 -17
- package/src/ui/react/foundation.jsx +0 -40
- package/src/ui/react/index.jsx +0 -6
- package/src/ui/react/jobs.jsx +0 -63
- package/src/ui/react/live-events.jsx +0 -55
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
-- Shared storage for the opt-in cf-genai-base messaging feature.
|
|
2
|
+
CREATE TABLE IF NOT EXISTS messaging_conversations (
|
|
3
|
+
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
4
|
+
tenant_id TEXT NOT NULL REFERENCES auth_tenants(id) ON DELETE CASCADE,
|
|
5
|
+
context TEXT NOT NULL,
|
|
6
|
+
title TEXT,
|
|
7
|
+
created_by_type TEXT,
|
|
8
|
+
created_by_key TEXT,
|
|
9
|
+
created_by_name TEXT,
|
|
10
|
+
created_at TEXT NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
11
|
+
updated_at TEXT NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
12
|
+
UNIQUE(tenant_id, context),
|
|
13
|
+
UNIQUE(tenant_id, id),
|
|
14
|
+
UNIQUE(tenant_id, id, context)
|
|
15
|
+
);
|
|
16
|
+
|
|
17
|
+
CREATE TABLE IF NOT EXISTS messaging_conversation_participants (
|
|
18
|
+
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
19
|
+
tenant_id TEXT NOT NULL REFERENCES auth_tenants(id) ON DELETE CASCADE,
|
|
20
|
+
conversation_id INTEGER NOT NULL,
|
|
21
|
+
participant_type TEXT NOT NULL,
|
|
22
|
+
participant_key TEXT NOT NULL,
|
|
23
|
+
display_name TEXT NOT NULL,
|
|
24
|
+
metadata_json TEXT NOT NULL DEFAULT '{}',
|
|
25
|
+
created_at TEXT NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
26
|
+
UNIQUE(tenant_id, conversation_id, participant_type, participant_key),
|
|
27
|
+
FOREIGN KEY (tenant_id, conversation_id)
|
|
28
|
+
REFERENCES messaging_conversations(tenant_id, id) ON DELETE CASCADE
|
|
29
|
+
);
|
|
30
|
+
|
|
31
|
+
CREATE TABLE IF NOT EXISTS messaging_messages (
|
|
32
|
+
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
33
|
+
tenant_id TEXT NOT NULL REFERENCES auth_tenants(id) ON DELETE CASCADE,
|
|
34
|
+
conversation_id INTEGER NOT NULL,
|
|
35
|
+
context TEXT NOT NULL,
|
|
36
|
+
sender_type TEXT NOT NULL,
|
|
37
|
+
sender_key TEXT NOT NULL,
|
|
38
|
+
sender_name TEXT NOT NULL,
|
|
39
|
+
body TEXT NOT NULL,
|
|
40
|
+
message_type TEXT NOT NULL DEFAULT 'text',
|
|
41
|
+
response_type TEXT,
|
|
42
|
+
audience_json TEXT NOT NULL DEFAULT '[]',
|
|
43
|
+
metadata_json TEXT NOT NULL DEFAULT '{}',
|
|
44
|
+
created_at TEXT NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
45
|
+
FOREIGN KEY (tenant_id, conversation_id, context)
|
|
46
|
+
REFERENCES messaging_conversations(tenant_id, id, context) ON DELETE CASCADE
|
|
47
|
+
);
|
|
48
|
+
|
|
49
|
+
CREATE INDEX IF NOT EXISTS idx_messaging_conversations_context
|
|
50
|
+
ON messaging_conversations(tenant_id, context);
|
|
51
|
+
CREATE INDEX IF NOT EXISTS idx_messaging_messages_thread
|
|
52
|
+
ON messaging_messages(tenant_id, conversation_id, id);
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
-- Backstop existing databases created before messaging used composite foreign keys.
|
|
2
|
+
CREATE TRIGGER IF NOT EXISTS messaging_participants_tenant_insert
|
|
3
|
+
BEFORE INSERT ON messaging_conversation_participants
|
|
4
|
+
WHEN NOT EXISTS (
|
|
5
|
+
SELECT 1 FROM messaging_conversations
|
|
6
|
+
WHERE id=NEW.conversation_id AND tenant_id=NEW.tenant_id
|
|
7
|
+
)
|
|
8
|
+
BEGIN
|
|
9
|
+
SELECT RAISE(ABORT, 'conversation tenant mismatch');
|
|
10
|
+
END;
|
|
11
|
+
|
|
12
|
+
CREATE TRIGGER IF NOT EXISTS messaging_participants_tenant_update
|
|
13
|
+
BEFORE UPDATE OF tenant_id, conversation_id ON messaging_conversation_participants
|
|
14
|
+
WHEN NOT EXISTS (
|
|
15
|
+
SELECT 1 FROM messaging_conversations
|
|
16
|
+
WHERE id=NEW.conversation_id AND tenant_id=NEW.tenant_id
|
|
17
|
+
)
|
|
18
|
+
BEGIN
|
|
19
|
+
SELECT RAISE(ABORT, 'conversation tenant mismatch');
|
|
20
|
+
END;
|
|
21
|
+
|
|
22
|
+
CREATE TRIGGER IF NOT EXISTS messaging_messages_context_insert
|
|
23
|
+
BEFORE INSERT ON messaging_messages
|
|
24
|
+
WHEN NOT EXISTS (
|
|
25
|
+
SELECT 1 FROM messaging_conversations
|
|
26
|
+
WHERE id=NEW.conversation_id
|
|
27
|
+
AND tenant_id=NEW.tenant_id
|
|
28
|
+
AND context=NEW.context
|
|
29
|
+
)
|
|
30
|
+
BEGIN
|
|
31
|
+
SELECT RAISE(ABORT, 'conversation tenant or context mismatch');
|
|
32
|
+
END;
|
|
33
|
+
|
|
34
|
+
CREATE TRIGGER IF NOT EXISTS messaging_messages_context_update
|
|
35
|
+
BEFORE UPDATE OF tenant_id, conversation_id, context ON messaging_messages
|
|
36
|
+
WHEN NOT EXISTS (
|
|
37
|
+
SELECT 1 FROM messaging_conversations
|
|
38
|
+
WHERE id=NEW.conversation_id
|
|
39
|
+
AND tenant_id=NEW.tenant_id
|
|
40
|
+
AND context=NEW.context
|
|
41
|
+
)
|
|
42
|
+
BEGIN
|
|
43
|
+
SELECT RAISE(ABORT, 'conversation tenant or context mismatch');
|
|
44
|
+
END;
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
ALTER TABLE auth_users ADD COLUMN active INTEGER NOT NULL DEFAULT 1 CHECK (active IN (0,1));
|
|
2
|
+
ALTER TABLE auth_tenants ADD COLUMN active INTEGER NOT NULL DEFAULT 1 CHECK (active IN (0,1));
|
|
3
|
+
ALTER TABLE auth_groups ADD COLUMN active INTEGER NOT NULL DEFAULT 1 CHECK (active IN (0,1));
|
|
4
|
+
ALTER TABLE auth_scopes ADD COLUMN active INTEGER NOT NULL DEFAULT 1 CHECK (active IN (0,1));
|
|
5
|
+
|
|
6
|
+
CREATE TABLE IF NOT EXISTS auth_group_scopes (
|
|
7
|
+
group_name TEXT NOT NULL REFERENCES auth_groups(name) ON DELETE CASCADE,
|
|
8
|
+
scope_name TEXT NOT NULL REFERENCES auth_scopes(name) ON DELETE CASCADE,
|
|
9
|
+
granted_by TEXT,
|
|
10
|
+
granted_at TEXT NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
11
|
+
PRIMARY KEY (group_name, scope_name)
|
|
12
|
+
);
|
|
13
|
+
CREATE INDEX IF NOT EXISTS auth_group_scopes_scope_idx ON auth_group_scopes(scope_name);
|
|
14
|
+
|
|
15
|
+
CREATE TABLE IF NOT EXISTS core_audit_log (
|
|
16
|
+
id TEXT PRIMARY KEY,
|
|
17
|
+
who TEXT NOT NULL,
|
|
18
|
+
operation TEXT NOT NULL,
|
|
19
|
+
resource TEXT NOT NULL,
|
|
20
|
+
details_json TEXT NOT NULL DEFAULT '{}',
|
|
21
|
+
created_at TEXT NOT NULL DEFAULT CURRENT_TIMESTAMP
|
|
22
|
+
);
|
|
23
|
+
CREATE INDEX IF NOT EXISTS core_audit_log_created_idx ON core_audit_log(created_at DESC);
|
|
24
|
+
CREATE INDEX IF NOT EXISTS core_audit_log_who_idx ON core_audit_log(who);
|
package/package.json
CHANGED
|
@@ -1,25 +1,142 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@agilesyndrome/cf-genai-base",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "6.0.0",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"bin": {
|
|
6
6
|
"cf-genai": "bin/cf-genai.js"
|
|
7
7
|
},
|
|
8
8
|
"exports": {
|
|
9
|
-
".":
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
"./
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
"./
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
9
|
+
".": {
|
|
10
|
+
"types": "./dist/index.d.ts",
|
|
11
|
+
"import": "./dist/index.js",
|
|
12
|
+
"default": "./dist/index.js"
|
|
13
|
+
},
|
|
14
|
+
"./auth": {
|
|
15
|
+
"types": "./dist/auth/index.d.ts",
|
|
16
|
+
"import": "./dist/auth/index.js",
|
|
17
|
+
"default": "./dist/auth/index.js"
|
|
18
|
+
},
|
|
19
|
+
"./admin": {
|
|
20
|
+
"types": "./dist/admin/index.d.ts",
|
|
21
|
+
"import": "./dist/admin/index.js",
|
|
22
|
+
"default": "./dist/admin/index.js"
|
|
23
|
+
},
|
|
24
|
+
"./data": {
|
|
25
|
+
"types": "./dist/data/index.d.ts",
|
|
26
|
+
"import": "./dist/data/index.js",
|
|
27
|
+
"default": "./dist/data/index.js"
|
|
28
|
+
},
|
|
29
|
+
"./api": {
|
|
30
|
+
"types": "./dist/api/index.d.ts",
|
|
31
|
+
"import": "./dist/api/index.js",
|
|
32
|
+
"default": "./dist/api/index.js"
|
|
33
|
+
},
|
|
34
|
+
"./event-hub": {
|
|
35
|
+
"types": "./dist/core/events/hub.d.ts",
|
|
36
|
+
"import": "./dist/core/events/hub.js",
|
|
37
|
+
"default": "./dist/core/events/hub.js"
|
|
38
|
+
},
|
|
39
|
+
"./repository": {
|
|
40
|
+
"types": "./dist/repository.d.ts",
|
|
41
|
+
"import": "./dist/repository.js",
|
|
42
|
+
"default": "./dist/repository.js"
|
|
43
|
+
},
|
|
44
|
+
"./app": {
|
|
45
|
+
"types": "./dist/app.d.ts",
|
|
46
|
+
"import": "./dist/app.js",
|
|
47
|
+
"default": "./dist/app.js"
|
|
48
|
+
},
|
|
49
|
+
"./domain": {
|
|
50
|
+
"types": "./dist/domain/index.d.ts",
|
|
51
|
+
"import": "./dist/domain/index.js",
|
|
52
|
+
"default": "./dist/domain/index.js"
|
|
53
|
+
},
|
|
54
|
+
"./core": {
|
|
55
|
+
"types": "./dist/core/index.d.ts",
|
|
56
|
+
"import": "./dist/core/index.js",
|
|
57
|
+
"default": "./dist/core/index.js"
|
|
58
|
+
},
|
|
59
|
+
"./core/circuits": {
|
|
60
|
+
"types": "./dist/core/circuits/index.d.ts",
|
|
61
|
+
"import": "./dist/core/circuits/index.js",
|
|
62
|
+
"default": "./dist/core/circuits/index.js"
|
|
63
|
+
},
|
|
64
|
+
"./core/database": {
|
|
65
|
+
"types": "./dist/core/database/index.d.ts",
|
|
66
|
+
"import": "./dist/core/database/index.js",
|
|
67
|
+
"default": "./dist/core/database/index.js"
|
|
68
|
+
},
|
|
69
|
+
"./core/events": {
|
|
70
|
+
"types": "./dist/core/events/index.d.ts",
|
|
71
|
+
"import": "./dist/core/events/index.js",
|
|
72
|
+
"default": "./dist/core/events/index.js"
|
|
73
|
+
},
|
|
74
|
+
"./core/healthchecks": {
|
|
75
|
+
"types": "./dist/core/healthchecks/index.d.ts",
|
|
76
|
+
"import": "./dist/core/healthchecks/index.js",
|
|
77
|
+
"default": "./dist/core/healthchecks/index.js"
|
|
78
|
+
},
|
|
79
|
+
"./core/jobs": {
|
|
80
|
+
"types": "./dist/core/jobs/index.d.ts",
|
|
81
|
+
"import": "./dist/core/jobs/index.js",
|
|
82
|
+
"default": "./dist/core/jobs/index.js"
|
|
83
|
+
},
|
|
84
|
+
"./core/security": {
|
|
85
|
+
"types": "./dist/core/security/index.d.ts",
|
|
86
|
+
"import": "./dist/core/security/index.js",
|
|
87
|
+
"default": "./dist/core/security/index.js"
|
|
88
|
+
},
|
|
89
|
+
"./auth/identity": {
|
|
90
|
+
"types": "./dist/auth/identity/index.d.ts",
|
|
91
|
+
"import": "./dist/auth/identity/index.js",
|
|
92
|
+
"default": "./dist/auth/identity/index.js"
|
|
93
|
+
},
|
|
94
|
+
"./ui": {
|
|
95
|
+
"types": "./dist/ui/index.d.ts",
|
|
96
|
+
"import": "./dist/ui/index.js",
|
|
97
|
+
"default": "./dist/ui/index.js"
|
|
98
|
+
},
|
|
99
|
+
"./ui/ssr": {
|
|
100
|
+
"types": "./dist/ui/ssr.d.ts",
|
|
101
|
+
"import": "./dist/ui/ssr.js",
|
|
102
|
+
"default": "./dist/ui/ssr.js"
|
|
103
|
+
},
|
|
104
|
+
"./ui/react": {
|
|
105
|
+
"types": "./dist/ui/react/index.d.ts",
|
|
106
|
+
"import": "./dist/ui/react/index.js",
|
|
107
|
+
"default": "./dist/ui/react/index.js"
|
|
108
|
+
},
|
|
109
|
+
"./ui/styles.css": "./dist/ui/styles.css",
|
|
110
|
+
"./features": {
|
|
111
|
+
"types": "./dist/features/index.d.ts",
|
|
112
|
+
"import": "./dist/features/index.js",
|
|
113
|
+
"default": "./dist/features/index.js"
|
|
114
|
+
},
|
|
115
|
+
"./features/llm": {
|
|
116
|
+
"types": "./dist/features/llm/index.d.ts",
|
|
117
|
+
"import": "./dist/features/llm/index.js",
|
|
118
|
+
"default": "./dist/features/llm/index.js"
|
|
119
|
+
},
|
|
120
|
+
"./input": {
|
|
121
|
+
"types": "./dist/input.d.ts",
|
|
122
|
+
"import": "./dist/input.js",
|
|
123
|
+
"default": "./dist/input.js"
|
|
124
|
+
},
|
|
125
|
+
"./features/messaging": {
|
|
126
|
+
"types": "./dist/features/messaging/index.d.ts",
|
|
127
|
+
"import": "./dist/features/messaging/index.js",
|
|
128
|
+
"default": "./dist/features/messaging/index.js"
|
|
129
|
+
},
|
|
130
|
+
"./cli": {
|
|
131
|
+
"types": "./dist/cli/cli.d.ts",
|
|
132
|
+
"import": "./dist/cli/cli.js",
|
|
133
|
+
"default": "./dist/cli/cli.js"
|
|
134
|
+
},
|
|
135
|
+
"./cli/*": {
|
|
136
|
+
"types": "./dist/cli/*.d.ts",
|
|
137
|
+
"import": "./dist/cli/*.js",
|
|
138
|
+
"default": "./dist/cli/*.js"
|
|
139
|
+
}
|
|
23
140
|
},
|
|
24
141
|
"description": "Cloudflare Worker lifecycle, security, administration, and operational CLI helpers.",
|
|
25
142
|
"engines": {
|
|
@@ -27,7 +144,8 @@
|
|
|
27
144
|
},
|
|
28
145
|
"license": "MIT",
|
|
29
146
|
"peerDependencies": {
|
|
30
|
-
"react": "^19.0.0"
|
|
147
|
+
"react": "^19.0.0",
|
|
148
|
+
"react-dom": "^19.0.0"
|
|
31
149
|
},
|
|
32
150
|
"publishConfig": {
|
|
33
151
|
"access": "public",
|
|
@@ -35,11 +153,11 @@
|
|
|
35
153
|
},
|
|
36
154
|
"files": [
|
|
37
155
|
"bin",
|
|
38
|
-
"
|
|
156
|
+
"dist",
|
|
39
157
|
"migrations",
|
|
40
158
|
"README.md",
|
|
41
159
|
"CLI.md",
|
|
42
|
-
"
|
|
160
|
+
"CHANGELOG.md",
|
|
43
161
|
"CONTRACT.md",
|
|
44
162
|
"LICENSE"
|
|
45
163
|
],
|
|
@@ -49,8 +167,31 @@
|
|
|
49
167
|
},
|
|
50
168
|
"homepage": "https://github.com/agilesyndrome/cf-genai-base#readme",
|
|
51
169
|
"scripts": {
|
|
52
|
-
"
|
|
53
|
-
"
|
|
54
|
-
"
|
|
170
|
+
"prepare": "node scripts/setup-git-hooks.mjs",
|
|
171
|
+
"clean": "node scripts/clean-dist.mjs",
|
|
172
|
+
"typecheck": "tsc --noEmit -p tsconfig.json",
|
|
173
|
+
"check": "npm run typecheck && npm run format:check && npm run lint:source",
|
|
174
|
+
"lint:source": "node scripts/lint-source.mjs",
|
|
175
|
+
"format": "node scripts/format-source.mjs --write",
|
|
176
|
+
"format:check": "node scripts/format-source.mjs && npm run lint:source -- --format-only",
|
|
177
|
+
"compile": "tsc -p tsconfig.build.json",
|
|
178
|
+
"assets": "node scripts/copy-build-assets.mjs",
|
|
179
|
+
"prepack": "npm run clean && npm run compile && npm run assets",
|
|
180
|
+
"verify:build": "node scripts/verify-build.mjs",
|
|
181
|
+
"test": "node --import tsx --test tests/*.test.mjs",
|
|
182
|
+
"test:integration": "node --import tsx --test examples/todo-list/test/integration.test.mjs",
|
|
183
|
+
"build": "npm run check && npm run prepack && npm test && npm run test:integration && npm run verify:build && npm pack --dry-run --ignore-scripts --loglevel=error"
|
|
184
|
+
},
|
|
185
|
+
"devDependencies": {
|
|
186
|
+
"@cloudflare/workers-types": "^5.20260917.1",
|
|
187
|
+
"@types/node": "^22.20.3",
|
|
188
|
+
"@types/react": "^19.3.0",
|
|
189
|
+
"@types/react-dom": "^19.1.9",
|
|
190
|
+
"react-dom": "^19.0.0",
|
|
191
|
+
"tsx": "^4.23.13",
|
|
192
|
+
"typescript": "^7.0.2"
|
|
193
|
+
},
|
|
194
|
+
"dependencies": {
|
|
195
|
+
"hono": "^4.13.8"
|
|
55
196
|
}
|
|
56
197
|
}
|
package/changelog.md
DELETED
|
@@ -1,25 +0,0 @@
|
|
|
1
|
-
# Changelog
|
|
2
|
-
|
|
3
|
-
## Unreleased
|
|
4
|
-
|
|
5
|
-
- Fold the complete `cf-genai` operational CLI into this package so Worker,
|
|
6
|
-
admin, healthcheck, circuit-breaker, D1, project, and release tooling share a
|
|
7
|
-
single version and installation.
|
|
8
|
-
- Publish the `cf-genai` executable and the programmatic `/cli` entrypoint from
|
|
9
|
-
`@agilesyndrome/cf-genai-base`.
|
|
10
|
-
- Make base CI validate the bundled CLI directly instead of downloading the
|
|
11
|
-
retired `@agilesyndrome/cf-genai-cli` package.
|
|
12
|
-
|
|
13
|
-
## 5.0.0
|
|
14
|
-
|
|
15
|
-
- Replace `@agilesyndrome/cf-genai-base/authorization` imports with `/auth`.
|
|
16
|
-
- Replace direct `src/core.js` imports with `src/core/index.js` or the package `/core` entrypoint.
|
|
17
|
-
- Replace direct `src/data.js` imports with `src/data/index.js` or the package `/data` entrypoint.
|
|
18
|
-
- Replace direct `src/api/router.js` imports with `src/api/contracts.js` for route definitions and dispatch.
|
|
19
|
-
- Update internal imports to the canonical folder modules; the old facade files are removed.
|
|
20
|
-
- Update package consumers and lockfiles to version `5.0.0`.
|
|
21
|
-
- Replace server-rendered admin HTML and custom elements with the React UI entrypoint; apps own the shell and theme around base's admin components.
|
|
22
|
-
- Apply `migrations/0006_jobs.sql`; features now use generic durable job helpers and `GET /api/jobs` instead of inventing job tables and status endpoints.
|
|
23
|
-
- Configure an `EVENT_HUB` Durable Object and export `EventHub` from `@agilesyndrome/cf-genai-base/event-hub` to enable authenticated live job events over WebSockets.
|
|
24
|
-
- Dispatch long-running work through a Cloudflare Workflow with `dispatchJob`; execute its durable lifecycle with `executeJob` instead of relying on request-lifetime background work.
|
|
25
|
-
- Remove the lowercase `admin_token` environment alias; use `ADMIN_TOKEN` only.
|
package/src/admin/index.js
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export * from "./routes.js";
|
package/src/admin/routes.js
DELETED
|
@@ -1,64 +0,0 @@
|
|
|
1
|
-
import { createAuthorizationTenant, createImpersonationToken, ensureScopes, ensureUser, getAuthorizationTenant, getAuthorizationUser, hasScope, listAuthorizationScopes, listAuthorizationTenants, listAuthorizationUsers, listGroups, listUserGroups, listUserGrants, listUserTenants, replaceUserGroups, replaceUserTenants, replaceUserGrants, updateAuthorizationTenant } from "../auth/index.js";
|
|
2
|
-
import { getCircuitBreaker, listCircuitBreakers, listFeatureCatalog, listFeatureHealth, listHealthchecks, requestActor, setCircuitBreaker, updateHealthcheck } from "../core/index.js";
|
|
3
|
-
|
|
4
|
-
export async function adminBoundary(request, env, ctx, next, state, { provider, authorize, scopes, scopeRoutes, features }) {
|
|
5
|
-
const url = new URL(request.url);
|
|
6
|
-
if (!isAdminPath(url.pathname)) return next(request);
|
|
7
|
-
const strategy = String(env?.AUTH_STRATEGY || "http_basic").trim().toLowerCase();
|
|
8
|
-
if (strategy === "http_basic") { const user = basicUser(request, env); if (!user) return adminUnauthorized(request); state.user = user; }
|
|
9
|
-
else if (strategy === "oauth") { const user = Object.hasOwn(state, "user") ? state.user : provider?.getUser ? await provider.getUser(request, env) : null; if (!user) return oauthUnauthorized(request, url); state.user = user; }
|
|
10
|
-
else return new Response("Unsupported AUTH_STRATEGY", { status: 500, headers: { "Cache-Control": "no-store" } });
|
|
11
|
-
if (["POST", "PUT", "PATCH", "DELETE"].includes(request.method) && url.pathname.startsWith("/api/")) { const origin = request.headers.get("Origin"); if (!origin || (() => { try { return new URL(origin).origin !== url.origin; } catch { return true; } })()) return Response.json({ error: "A same-origin request is required." }, { status: 403, headers: { "Cache-Control": "no-store" } }); }
|
|
12
|
-
const who = state.user?.auth_strategy === "http_basic" ? "user:admin" : `user:${state.user?.sub || "unknown"}`;
|
|
13
|
-
await ensureScopes(env, scopes, { who });
|
|
14
|
-
state.authUser = state.user?.authUser || await ensureUser(env, state.user, { who }); state.requestedBy = requestActor(state);
|
|
15
|
-
const requiredScope = requiredScopeFor(url.pathname, scopeRoutes); const scopeAllowed = !requiredScope || await hasScope(env, state.user, requiredScope, { who: requestActor(state) });
|
|
16
|
-
if (!scopeAllowed || (authorize && state.user.auth_strategy !== "http_basic" && !(await authorize({ request, url, user: state.user, env, ctx, state })))) return url.pathname.startsWith("/api/") ? Response.json({ error: "Administrator access is required." }, { status: 403, headers: { "Cache-Control": "no-store" } }) : new Response("Administrator access is required.", { status: 403, headers: { "Cache-Control": "no-store" } });
|
|
17
|
-
const platformResponse = await authorizationApi(request, env, url, state, features); if (platformResponse) return platformResponse;
|
|
18
|
-
return next(request);
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
async function authorizationApi(request, env, url, state, features = []) {
|
|
22
|
-
const grantsMatch = url.pathname.match(/\/api\/admin\/users\/([^/]+)\/scopes$/);
|
|
23
|
-
const platformPath = url.pathname === "/api/admin/users" || url.pathname === "/api/admin/tenants" || url.pathname.startsWith("/api/admin/tenants/") || url.pathname === "/api/admin/scopes" || url.pathname === "/api/admin/groups" || url.pathname.startsWith("/api/admin/users/") || url.pathname.startsWith("/api/admin/impersonate") || url.pathname === "/api/admin/status" || url.pathname === "/api/admin/features" || url.pathname === "/api/admin/healthchecks" || url.pathname === "/api/admin/circuit-breakers" || url.pathname.startsWith("/api/admin/healthchecks/") || url.pathname.startsWith("/api/admin/circuit-breakers/") || Boolean(grantsMatch);
|
|
24
|
-
if (!platformPath) return null;
|
|
25
|
-
if (!(state.user.auth_strategy === "http_basic" || (state.authUser && state.authUser.is_admin))) return Response.json({ error: "Administrator access is required." }, { status: 403, headers: { "Cache-Control": "no-store" } });
|
|
26
|
-
const who = { who: requestActor(state) };
|
|
27
|
-
if (url.pathname === "/api/admin/impersonate/clear" && request.method === "POST") return new Response(JSON.stringify({ ok: true }), { headers: { "content-type": "application/json; charset=utf-8", "Set-Cookie": "__Host-cfgenai_impersonation=; Max-Age=0; Path=/; Secure; HttpOnly; SameSite=Lax" } });
|
|
28
|
-
if (url.pathname === "/api/admin/users" && request.method === "GET") return Response.json({ users: await listAuthorizationUsers(env, who) });
|
|
29
|
-
if (url.pathname === "/api/admin/tenants" && request.method === "GET") return Response.json({ tenants: await listAuthorizationTenants(env, who) });
|
|
30
|
-
if (url.pathname === "/api/admin/tenants" && request.method === "POST") { const body = await request.json().catch(() => null); if (!body?.id || !body?.name) return Response.json({ error: "id and name are required" }, { status: 400 }); try { return Response.json({ tenant: await createAuthorizationTenant(env, body.id, body.name, who) }, { status: 201 }); } catch (error) { return Response.json({ error: error.message }, { status: 400 }); } }
|
|
31
|
-
const tenantMatch = url.pathname.match(/^\/api\/admin\/tenants\/([^/]+)$/);
|
|
32
|
-
if (tenantMatch && request.method === "GET") return Response.json({ tenant: await getAuthorizationTenant(env, decodeURIComponent(tenantMatch[1]), who) });
|
|
33
|
-
if (tenantMatch && request.method === "PUT") { const body = await request.json().catch(() => null); if (!body?.name) return Response.json({ error: "name is required" }, { status: 400 }); return Response.json({ tenant: await updateAuthorizationTenant(env, decodeURIComponent(tenantMatch[1]), body.name, who) }); }
|
|
34
|
-
const impersonateMatch = url.pathname.match(/^\/api\/admin\/users\/([^/]+)\/impersonate$/);
|
|
35
|
-
if (impersonateMatch && request.method === "POST") { const targetUser = await getAuthorizationUser(env, decodeURIComponent(impersonateMatch[1]), who); if (!targetUser) return Response.json({ error: "User not found." }, { status: 404 }); const token = await createImpersonationToken(env, state.authUser?.id || state.user?.sub || "admin", targetUser.id); return new Response(JSON.stringify({ ok: true, user: { id: targetUser.id, email: targetUser.email, display_name: targetUser.display_name }, expires_in: 900 }), { headers: { "content-type": "application/json; charset=utf-8", "Set-Cookie": `__Host-cfgenai_impersonation=${token}; Max-Age=900; Path=/; Secure; HttpOnly; SameSite=Lax` } }); }
|
|
36
|
-
if (url.pathname === "/api/admin/scopes" && request.method === "GET") return Response.json({ scopes: await listAuthorizationScopes(env, who) });
|
|
37
|
-
if (url.pathname === "/api/admin/status" && request.method === "GET") return Response.json({ features: await listFeatureHealth(env, who) });
|
|
38
|
-
if (url.pathname === "/api/admin/features" && request.method === "GET") return Response.json({ features: await listFeatureCatalog(env, features, who) });
|
|
39
|
-
if (url.pathname === "/api/admin/groups" && request.method === "GET") return Response.json({ groups: await listGroups(env, who) });
|
|
40
|
-
if (url.pathname === "/api/admin/healthchecks" && request.method === "GET") return Response.json({ healthchecks: await listHealthchecks(env, who) });
|
|
41
|
-
if (url.pathname === "/api/admin/circuit-breakers" && request.method === "GET") return Response.json({ circuit_breakers: await listCircuitBreakers(env, who) });
|
|
42
|
-
const healthcheckMatch = url.pathname.match(/\/api\/admin\/healthchecks\/([^/]+)$/);
|
|
43
|
-
if (healthcheckMatch && request.method === "PUT") { const body = await request.json().catch(() => null); if (!body?.state) return Response.json({ error: "state is required" }, { status: 400 }); const healthcheck = await updateHealthcheck(env, decodeURIComponent(healthcheckMatch[1]), body.state, who); return healthcheck ? Response.json({ healthcheck }) : Response.json({ error: "Healthcheck not found" }, { status: 404 }); }
|
|
44
|
-
const breakerMatch = url.pathname.match(/\/api\/admin\/circuit-breakers\/([^/]+)$/);
|
|
45
|
-
if (breakerMatch && request.method === "GET") return Response.json({ circuit_breaker: await getCircuitBreaker(env, decodeURIComponent(breakerMatch[1]), who) });
|
|
46
|
-
if (breakerMatch && request.method === "PUT") { const body = await request.json().catch(() => null); if (!body?.state) return Response.json({ error: "state is required" }, { status: 400 }); const breaker = await setCircuitBreaker(env, decodeURIComponent(breakerMatch[1]), body.state, who); return breaker ? Response.json({ circuit_breaker: breaker }) : Response.json({ error: "Circuit breaker not found" }, { status: 404 }); }
|
|
47
|
-
const groupsMatch = url.pathname.match(/\/api\/admin\/users\/([^/]+)\/groups$/);
|
|
48
|
-
if (groupsMatch && request.method === "GET") return Response.json({ groups: await listUserGroups(env, decodeURIComponent(groupsMatch[1]), who) });
|
|
49
|
-
if (groupsMatch && request.method === "PUT") { const body = await request.json().catch(() => null); if (!body || !Array.isArray(body.groups)) return Response.json({ error: "groups must be an array" }, { status: 400 }); return Response.json({ groups: await replaceUserGroups(env, decodeURIComponent(groupsMatch[1]), body.groups, state.authUser && state.authUser.id, who) }); }
|
|
50
|
-
const tenantsMatch = url.pathname.match(/\/api\/admin\/users\/([^/]+)\/tenants$/);
|
|
51
|
-
if (tenantsMatch && request.method === "GET") return Response.json({ tenants: await listUserTenants(env, decodeURIComponent(tenantsMatch[1]), who) });
|
|
52
|
-
if (tenantsMatch && request.method === "PUT") { const body = await request.json().catch(() => null); if (!body || !Array.isArray(body.tenants)) return Response.json({ error: "tenants must be an array" }, { status: 400 }); return Response.json({ tenants: await replaceUserTenants(env, decodeURIComponent(tenantsMatch[1]), body.tenants, who) }); }
|
|
53
|
-
if (grantsMatch && request.method === "GET") return Response.json({ grants: await listUserGrants(env, decodeURIComponent(grantsMatch[1]), who) });
|
|
54
|
-
if (grantsMatch && request.method === "PUT") { const body = await request.json().catch(() => null); if (!body || !Array.isArray(body.scopes)) return Response.json({ error: "scopes must be an array" }, { status: 400 }); const grants = await replaceUserGrants(env, decodeURIComponent(grantsMatch[1]), body.scopes, state.authUser && state.authUser.id, who); return Response.json({ grants }); }
|
|
55
|
-
return null;
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
function isAdminPath(pathname) { return pathname === "/admin" || pathname.startsWith("/admin/") || pathname === "/api/admin" || pathname.startsWith("/api/admin/"); }
|
|
59
|
-
function requiredScopeFor(pathname, routes) { const route = routes.find((entry) => typeof entry.match === "function" ? entry.match(pathname) : pathname === entry.path || pathname.startsWith(String(entry.path || "") + "/")); return route && route.scope ? route.scope : null; }
|
|
60
|
-
function basicUser(request, env) { const token = String(env?.ADMIN_TOKEN || ""); if (!token) return null; const header = request.headers.get("Authorization") || ""; if (!header.toLowerCase().startsWith("basic ")) return null; let decoded; try { decoded = atob(header.slice(6).trim()); } catch { return null; } const separator = decoded.indexOf(":"); if (separator < 0 || !constantTimeEqual(decoded.slice(0, separator), "admin") || !constantTimeEqual(decoded.slice(separator + 1), token)) return null; return { sub: "basic:admin", email: "", name: "admin", roles: ["admin"], auth_strategy: "http_basic" }; }
|
|
61
|
-
function adminUnauthorized(request) { const headers = { "Cache-Control": "no-store", "WWW-Authenticate": "Basic realm=\"admin\", charset=\"UTF-8\"" }; return new URL(request.url).pathname.startsWith("/api/") ? Response.json({ error: "Authentication is required." }, { status: 401, headers }) : new Response("Authentication is required.", { status: 401, headers }); }
|
|
62
|
-
function oauthUnauthorized(request, url) { if (url.pathname.startsWith("/api/")) return Response.json({ error: "Authentication is required." }, { status: 401, headers: { "Cache-Control": "no-store" } }); return Response.redirect(url.origin + "/auth/login?return_to=" + encodeURIComponent(safeReturnTo(url.pathname + url.search)), 302); }
|
|
63
|
-
function safeReturnTo(value) { return value?.startsWith("/") && !value.startsWith("//") && !value.startsWith("/auth/") ? value : "/"; }
|
|
64
|
-
function constantTimeEqual(a, b) { const aa = new TextEncoder().encode(a), bb = new TextEncoder().encode(b); let n = aa.length ^ bb.length; for (let i = 0; i < Math.max(aa.length, bb.length); i++) n |= (aa[i] || 0) ^ (bb[i] || 0); return n === 0; }
|
package/src/api/client.js
DELETED
|
@@ -1,8 +0,0 @@
|
|
|
1
|
-
export async function apiFetch(input, options = {}) {
|
|
2
|
-
const response = await fetch(input, { credentials: "same-origin", headers: { Accept: "application/json", ...(options.body ? { "Content-Type": "application/json" } : {}), ...(options.headers || {}) }, ...options });
|
|
3
|
-
const payload = await response.clone().json().catch(() => null);
|
|
4
|
-
if (!response.ok) { const error = new Error(payload?.error || `Request failed (${response.status})`); error.status = response.status; error.requestId = response.headers.get("X-Request-ID") || payload?.request_id || null; throw error; }
|
|
5
|
-
return payload === null ? response : payload;
|
|
6
|
-
}
|
|
7
|
-
|
|
8
|
-
export function apiJson(input, payload, options = {}) { return apiFetch(input, { ...options, method: options.method || "POST", body: JSON.stringify(payload) }); }
|
package/src/api/contracts.js
DELETED
|
@@ -1,24 +0,0 @@
|
|
|
1
|
-
import { json, requestIdentity, sameOrigin } from "../core/index.js";
|
|
2
|
-
import { hasScope } from "../auth/index.js";
|
|
3
|
-
|
|
4
|
-
export function defineRoute({ method = "GET", path, auth = "public", scope = null, csrf = false, handler } = {}) {
|
|
5
|
-
if (!path || typeof handler !== "function") throw new TypeError("API routes require path and handler");
|
|
6
|
-
return { method: String(method).toUpperCase(), path: String(path), auth, scope, csrf, handler };
|
|
7
|
-
}
|
|
8
|
-
|
|
9
|
-
export function matchRoute(request, route) {
|
|
10
|
-
const url = new URL(request.url); const methods = Array.isArray(route.method) ? route.method : [route.method];
|
|
11
|
-
return methods.map((method) => String(method).toUpperCase()).includes(request.method.toUpperCase()) && (typeof route.path === "function" ? route.path(url.pathname, request) : route.path === url.pathname);
|
|
12
|
-
}
|
|
13
|
-
|
|
14
|
-
export async function dispatchRoutes(request, env, ctx, state, routes = []) {
|
|
15
|
-
for (const route of routes) if (matchRoute(request, route)) {
|
|
16
|
-
const identity = requestIdentity(state);
|
|
17
|
-
if (route.auth === "user" && !identity.isAuthenticated) return json({ error: "Authentication is required." }, 401);
|
|
18
|
-
if (route.auth === "admin" && !identity.isAdmin) return json({ error: "Administrator access is required." }, 403);
|
|
19
|
-
if (route.csrf && !sameOrigin(request)) return json({ error: "A same-origin request is required." }, 403);
|
|
20
|
-
if (route.scope && !(await hasScope(env, state?.user || state?.authUser, route.scope, { who: identity.who }))) return json({ error: "Required scope is missing." }, 403);
|
|
21
|
-
return route.handler({ request, env, ctx, state, route, identity });
|
|
22
|
-
}
|
|
23
|
-
return null;
|
|
24
|
-
}
|
package/src/api/index.js
DELETED
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
export { Event, emitEvent, json, readJson, readJsonClone, requireAdmin, requireFeatureCircuit, requireUser, sameOrigin, secureJson, secureText, userId, requestContext, requestIdentity } from "../core/index.js";
|
|
2
|
-
export { defineRepository, createRepositories, RepositoryError } from "../repository.js";
|
|
3
|
-
export { defineRoute, matchRoute, dispatchRoutes } from "./contracts.js";
|
|
4
|
-
export { apiFetch, apiJson } from "./client.js";
|
|
5
|
-
export { jobResponse, liveEventsResponse } from "./jobs.js";
|
|
6
|
-
export { defineApp } from "../app.js";
|
|
7
|
-
export { assertSecurityHeaders, assertJsonError } from "./testing.js";
|
package/src/api/jobs.js
DELETED
|
@@ -1,37 +0,0 @@
|
|
|
1
|
-
import { getJob, listJobEvents, listJobs } from "../core/jobs.js";
|
|
2
|
-
import { requestIdentity } from "../core/identity.js";
|
|
3
|
-
import { secureJson } from "../core/security.js";
|
|
4
|
-
|
|
5
|
-
export async function jobResponse(request, env, state) {
|
|
6
|
-
const pathname = new URL(request.url).pathname;
|
|
7
|
-
if (pathname !== "/api/jobs" && !pathname.startsWith("/api/jobs/")) return null;
|
|
8
|
-
if (request.method !== "GET") return secureJson({ error: "Method not allowed" }, 405, { Allow: "GET" });
|
|
9
|
-
const identity = requestIdentity(state);
|
|
10
|
-
const ownerId = identity.authUser?.id || state?.user?.sub || (state?.user?.auth_strategy === "http_basic" ? "basic:admin" : null);
|
|
11
|
-
if (!ownerId) return secureJson({ error: "Authentication is required." }, 401);
|
|
12
|
-
const url = new URL(request.url);
|
|
13
|
-
const match = url.pathname.match(/^\/api\/jobs\/([^/]+)(?:\/events)?$/);
|
|
14
|
-
const isEvents = url.pathname.endsWith("/events");
|
|
15
|
-
if (!match) {
|
|
16
|
-
const jobs = await listJobs(env, { ownerId, type: url.searchParams.get("type") || undefined, status: url.searchParams.get("status") || undefined, limit: url.searchParams.get("limit") || 50 }, { who: identity.who });
|
|
17
|
-
return secureJson({ jobs });
|
|
18
|
-
}
|
|
19
|
-
const job = await getJob(env, decodeURIComponent(match[1]), { who: identity.who });
|
|
20
|
-
if (!job || (job.ownerId !== ownerId && !identity.isAdmin)) return secureJson({ error: "Job not found" }, 404);
|
|
21
|
-
if (isEvents) return secureJson({ events: await listJobEvents(env, job.id, { who: identity.who }) });
|
|
22
|
-
return secureJson({ job });
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
export async function liveEventsResponse(request, env, state, bindingName = "EVENT_HUB") {
|
|
26
|
-
const url = new URL(request.url);
|
|
27
|
-
if (url.pathname !== "/api/events") return null;
|
|
28
|
-
const identity = requestIdentity(state);
|
|
29
|
-
const ownerId = identity.authUser?.id || state?.user?.sub || (state?.user?.auth_strategy === "http_basic" ? "basic:admin" : null);
|
|
30
|
-
if (!ownerId) return secureJson({ error: "Authentication is required." }, 401);
|
|
31
|
-
const namespace = env?.[bindingName];
|
|
32
|
-
if (!namespace || typeof namespace.idFromName !== "function") return secureJson({ error: "Live events are not configured." }, 501);
|
|
33
|
-
if (request.headers.get("Upgrade")?.toLowerCase() !== "websocket") return secureJson({ error: "WebSocket upgrade required." }, 426, { Upgrade: "websocket" });
|
|
34
|
-
const room = `user:${ownerId}`;
|
|
35
|
-
const stub = namespace.get(namespace.idFromName(room));
|
|
36
|
-
return stub.fetch("https://cf-genai-event-hub/connect", { headers: { Upgrade: "websocket" } });
|
|
37
|
-
}
|
package/src/api/testing.js
DELETED
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
export function assertSecurityHeaders(response) {
|
|
2
|
-
for (const header of ["Content-Security-Policy", "X-Content-Type-Options", "X-Frame-Options", "Referrer-Policy", "Permissions-Policy", "Strict-Transport-Security"]) {
|
|
3
|
-
if (!response?.headers?.get(header)) throw new Error(`Missing security header: ${header}`);
|
|
4
|
-
}
|
|
5
|
-
return response;
|
|
6
|
-
}
|
|
7
|
-
|
|
8
|
-
export async function assertJsonError(response, status) {
|
|
9
|
-
if (response.status !== status) throw new Error(`Expected ${status}, received ${response.status}`);
|
|
10
|
-
const payload = await response.clone().json();
|
|
11
|
-
if (!payload?.error) throw new Error("Expected a JSON error envelope");
|
|
12
|
-
return payload;
|
|
13
|
-
}
|
package/src/app.js
DELETED
|
@@ -1,5 +0,0 @@
|
|
|
1
|
-
export function defineApp({ name, ui = true, api = true, admin = true, features = [], repositories = [] } = {}) {
|
|
2
|
-
if (!/^[a-z][a-z0-9-]*$/.test(String(name || ""))) throw new TypeError("Apps require a safe name");
|
|
3
|
-
if (!ui && !api) throw new TypeError("An app must expose ui or api");
|
|
4
|
-
return { name: String(name), ui: Boolean(ui), api: Boolean(api), admin: Boolean(admin), features: [...features], repositories: [...repositories] };
|
|
5
|
-
}
|
package/src/auth/encoding.js
DELETED
|
@@ -1,6 +0,0 @@
|
|
|
1
|
-
export function parseJsonValue(value) { try { return JSON.parse(value); } catch { return value; } }
|
|
2
|
-
export function deepEqual(left, right) { return JSON.stringify(left) === JSON.stringify(right); }
|
|
3
|
-
export async function signValue(value, secret) { const key = await crypto.subtle.importKey("raw", new TextEncoder().encode(String(secret)), { name: "HMAC", hash: "SHA-256" }, false, ["sign"]); const signature = await crypto.subtle.sign("HMAC", key, new TextEncoder().encode(value)); return base64url(new Uint8Array(signature)); }
|
|
4
|
-
export function base64url(bytes) { return btoa(String.fromCharCode(...bytes)).replaceAll("+", "-").replaceAll("/", "_").replaceAll("=", ""); }
|
|
5
|
-
export function base64urlDecode(value) { const padded = value.replaceAll("-", "+").replaceAll("_", "/") + "=".repeat((4 - value.length % 4) % 4); return Uint8Array.from(atob(padded), (char) => char.charCodeAt(0)); }
|
|
6
|
-
export function constantTimeEqual(left, right) { const a = new TextEncoder().encode(String(left)), b = new TextEncoder().encode(String(right)); let result = a.length ^ b.length; for (let index = 0; index < Math.max(a.length, b.length); index += 1) result |= (a[index] || 0) ^ (b[index] || 0); return result === 0; }
|
package/src/auth/groups.js
DELETED
|
@@ -1,5 +0,0 @@
|
|
|
1
|
-
import { createD1 } from "../core/d1.js";
|
|
2
|
-
|
|
3
|
-
export async function listGroups(env, { who = "system:read" } = {}) { const result = await createD1(env, { who }).prepare("SELECT name,display_name,description,created_at,updated_at FROM auth_groups ORDER BY display_name COLLATE NOCASE").all(); return result.results || []; }
|
|
4
|
-
export async function listUserGroups(env, userId, { who = "system:read" } = {}) { const result = await createD1(env, { who }).prepare("SELECT group_name,granted_at FROM auth_user_groups WHERE user_id=? ORDER BY group_name").bind(userId).all(); return result.results || []; }
|
|
5
|
-
export async function replaceUserGroups(env, userId, groups, grantedBy, { who = "system:read" } = {}) { const db = createD1(env, { who }); await db.batch([db.prepare("DELETE FROM auth_user_groups WHERE user_id=?").bind(userId), ...[...new Set(groups)].map((group) => db.prepare("INSERT INTO auth_user_groups (user_id,group_name,granted_by) VALUES (?,?,?)").bind(userId, group, grantedBy || null))]); return listUserGroups(env, userId, { who }); }
|
|
@@ -1,15 +0,0 @@
|
|
|
1
|
-
import { base64url, base64urlDecode, constantTimeEqual, signValue } from "./encoding.js";
|
|
2
|
-
|
|
3
|
-
export async function createImpersonationToken(env, adminUserId, targetUserId, { ttlSeconds = 900 } = {}) {
|
|
4
|
-
if (!env?.AUTH_SESSION_SECRET) throw new Error("AUTH_SESSION_SECRET is required for impersonation.");
|
|
5
|
-
const payload = { adminUserId: String(adminUserId || "admin"), targetUserId: String(targetUserId), exp: Math.floor(Date.now() / 1000) + Math.min(Math.max(Number(ttlSeconds) || 900, 60), 3600) };
|
|
6
|
-
const encoded = base64url(new TextEncoder().encode(JSON.stringify(payload)));
|
|
7
|
-
return `${encoded}.${await signValue(encoded, env?.AUTH_SESSION_SECRET || "")}`;
|
|
8
|
-
}
|
|
9
|
-
|
|
10
|
-
export async function verifyImpersonationToken(token, env) {
|
|
11
|
-
if (!env?.AUTH_SESSION_SECRET) return null;
|
|
12
|
-
const [encoded, signature] = String(token || "").split(".");
|
|
13
|
-
if (!encoded || !signature || !constantTimeEqual(signature, await signValue(encoded, env?.AUTH_SESSION_SECRET || ""))) return null;
|
|
14
|
-
try { const payload = JSON.parse(new TextDecoder().decode(base64urlDecode(encoded))); return payload.exp > Date.now() / 1000 && payload.targetUserId ? payload : null; } catch { return null; }
|
|
15
|
-
}
|
package/src/auth/index.js
DELETED
|
@@ -1,8 +0,0 @@
|
|
|
1
|
-
export * from "./constants.js";
|
|
2
|
-
export * from "./scopes.js";
|
|
3
|
-
export * from "./users.js";
|
|
4
|
-
export * from "./tenants.js";
|
|
5
|
-
export * from "./groups.js";
|
|
6
|
-
export * from "./subscriptions.js";
|
|
7
|
-
export * from "./impersonation.js";
|
|
8
|
-
export * from "./oauth-single.js";
|