@urateam/core 0.1.3 → 0.1.8
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/__tests__/audit/audit-e2e.test.d.ts +2 -0
- package/dist/__tests__/audit/audit-e2e.test.d.ts.map +1 -0
- package/dist/__tests__/audit/audit-e2e.test.js +56 -0
- package/dist/__tests__/audit/audit-e2e.test.js.map +1 -0
- package/dist/__tests__/audit/csv.test.d.ts +2 -0
- package/dist/__tests__/audit/csv.test.d.ts.map +1 -0
- package/dist/__tests__/audit/csv.test.js +134 -0
- package/dist/__tests__/audit/csv.test.js.map +1 -0
- package/dist/__tests__/audit/events.test.d.ts +2 -0
- package/dist/__tests__/audit/events.test.d.ts.map +1 -0
- package/dist/__tests__/audit/events.test.js +45 -0
- package/dist/__tests__/audit/events.test.js.map +1 -0
- package/dist/__tests__/audit/policy-events.test.d.ts +2 -0
- package/dist/__tests__/audit/policy-events.test.d.ts.map +1 -0
- package/dist/__tests__/audit/policy-events.test.js +49 -0
- package/dist/__tests__/audit/policy-events.test.js.map +1 -0
- package/dist/__tests__/audit/projection.test.d.ts +2 -0
- package/dist/__tests__/audit/projection.test.d.ts.map +1 -0
- package/dist/__tests__/audit/projection.test.js +76 -0
- package/dist/__tests__/audit/projection.test.js.map +1 -0
- package/dist/__tests__/audit/rbac-events.test.d.ts +2 -0
- package/dist/__tests__/audit/rbac-events.test.d.ts.map +1 -0
- package/dist/__tests__/audit/rbac-events.test.js +56 -0
- package/dist/__tests__/audit/rbac-events.test.js.map +1 -0
- package/dist/__tests__/audit/reader.test.d.ts +2 -0
- package/dist/__tests__/audit/reader.test.d.ts.map +1 -0
- package/dist/__tests__/audit/reader.test.js +133 -0
- package/dist/__tests__/audit/reader.test.js.map +1 -0
- package/dist/__tests__/audit/retention.test.d.ts +2 -0
- package/dist/__tests__/audit/retention.test.d.ts.map +1 -0
- package/dist/__tests__/audit/retention.test.js +48 -0
- package/dist/__tests__/audit/retention.test.js.map +1 -0
- package/dist/__tests__/audit/sso-events.test.d.ts +2 -0
- package/dist/__tests__/audit/sso-events.test.d.ts.map +1 -0
- package/dist/__tests__/audit/sso-events.test.js +49 -0
- package/dist/__tests__/audit/sso-events.test.js.map +1 -0
- package/dist/__tests__/audit/writer.test.d.ts +2 -0
- package/dist/__tests__/audit/writer.test.d.ts.map +1 -0
- package/dist/__tests__/audit/writer.test.js +67 -0
- package/dist/__tests__/audit/writer.test.js.map +1 -0
- package/dist/__tests__/audit-immutability.test.d.ts +2 -0
- package/dist/__tests__/audit-immutability.test.d.ts.map +1 -0
- package/dist/__tests__/audit-immutability.test.js +61 -0
- package/dist/__tests__/audit-immutability.test.js.map +1 -0
- package/dist/__tests__/audit-types.test.d.ts +2 -0
- package/dist/__tests__/audit-types.test.d.ts.map +1 -0
- package/dist/__tests__/audit-types.test.js +35 -0
- package/dist/__tests__/audit-types.test.js.map +1 -0
- package/dist/__tests__/auth/session-store.test.d.ts +2 -0
- package/dist/__tests__/auth/session-store.test.d.ts.map +1 -0
- package/dist/__tests__/auth/session-store.test.js +65 -0
- package/dist/__tests__/auth/session-store.test.js.map +1 -0
- package/dist/__tests__/auth/sso-config.test.d.ts +2 -0
- package/dist/__tests__/auth/sso-config.test.d.ts.map +1 -0
- package/dist/__tests__/auth/sso-config.test.js +75 -0
- package/dist/__tests__/auth/sso-config.test.js.map +1 -0
- package/dist/__tests__/auth/sso-feature-flag.test.d.ts +2 -0
- package/dist/__tests__/auth/sso-feature-flag.test.d.ts.map +1 -0
- package/dist/__tests__/auth/sso-feature-flag.test.js +33 -0
- package/dist/__tests__/auth/sso-feature-flag.test.js.map +1 -0
- package/dist/__tests__/auth/user-role-round-trip.test.d.ts +2 -0
- package/dist/__tests__/auth/user-role-round-trip.test.d.ts.map +1 -0
- package/dist/__tests__/auth/user-role-round-trip.test.js +30 -0
- package/dist/__tests__/auth/user-role-round-trip.test.js.map +1 -0
- package/dist/__tests__/auth/user-store.test.d.ts +2 -0
- package/dist/__tests__/auth/user-store.test.d.ts.map +1 -0
- package/dist/__tests__/auth/user-store.test.js +119 -0
- package/dist/__tests__/auth/user-store.test.js.map +1 -0
- package/dist/__tests__/auth/workos-client.test.d.ts +2 -0
- package/dist/__tests__/auth/workos-client.test.d.ts.map +1 -0
- package/dist/__tests__/auth/workos-client.test.js +17 -0
- package/dist/__tests__/auth/workos-client.test.js.map +1 -0
- package/dist/__tests__/auto-merge.test.js +2 -1
- package/dist/__tests__/auto-merge.test.js.map +1 -1
- package/dist/__tests__/cost/aggregate.test.d.ts +2 -0
- package/dist/__tests__/cost/aggregate.test.d.ts.map +1 -0
- package/dist/__tests__/cost/aggregate.test.js +358 -0
- package/dist/__tests__/cost/aggregate.test.js.map +1 -0
- package/dist/__tests__/cost/csv.test.d.ts +2 -0
- package/dist/__tests__/cost/csv.test.d.ts.map +1 -0
- package/dist/__tests__/cost/csv.test.js +109 -0
- package/dist/__tests__/cost/csv.test.js.map +1 -0
- package/dist/__tests__/cost/per-run.test.d.ts +2 -0
- package/dist/__tests__/cost/per-run.test.d.ts.map +1 -0
- package/dist/__tests__/cost/per-run.test.js +64 -0
- package/dist/__tests__/cost/per-run.test.js.map +1 -0
- package/dist/__tests__/cost/rates.test.d.ts +2 -0
- package/dist/__tests__/cost/rates.test.d.ts.map +1 -0
- package/dist/__tests__/cost/rates.test.js +47 -0
- package/dist/__tests__/cost/rates.test.js.map +1 -0
- package/dist/__tests__/cost/rollup.test.d.ts +2 -0
- package/dist/__tests__/cost/rollup.test.d.ts.map +1 -0
- package/dist/__tests__/cost/rollup.test.js +187 -0
- package/dist/__tests__/cost/rollup.test.js.map +1 -0
- package/dist/__tests__/cost-defensive.test.d.ts +2 -0
- package/dist/__tests__/cost-defensive.test.d.ts.map +1 -0
- package/dist/__tests__/cost-defensive.test.js +123 -0
- package/dist/__tests__/cost-defensive.test.js.map +1 -0
- package/dist/__tests__/cost-integration.test.d.ts +2 -0
- package/dist/__tests__/cost-integration.test.d.ts.map +1 -0
- package/dist/__tests__/cost-integration.test.js +80 -0
- package/dist/__tests__/cost-integration.test.js.map +1 -0
- package/dist/__tests__/cost-license.test.d.ts +2 -0
- package/dist/__tests__/cost-license.test.d.ts.map +1 -0
- package/dist/__tests__/cost-license.test.js +23 -0
- package/dist/__tests__/cost-license.test.js.map +1 -0
- package/dist/__tests__/cost-types.test.d.ts +2 -0
- package/dist/__tests__/cost-types.test.d.ts.map +1 -0
- package/dist/__tests__/cost-types.test.js +65 -0
- package/dist/__tests__/cost-types.test.js.map +1 -0
- package/dist/__tests__/db-audit-schema.test.d.ts +2 -0
- package/dist/__tests__/db-audit-schema.test.d.ts.map +1 -0
- package/dist/__tests__/db-audit-schema.test.js +35 -0
- package/dist/__tests__/db-audit-schema.test.js.map +1 -0
- package/dist/__tests__/db-cost-rollups-schema.test.d.ts +2 -0
- package/dist/__tests__/db-cost-rollups-schema.test.d.ts.map +1 -0
- package/dist/__tests__/db-cost-rollups-schema.test.js +28 -0
- package/dist/__tests__/db-cost-rollups-schema.test.js.map +1 -0
- package/dist/__tests__/db-rbac-schema.test.d.ts +2 -0
- package/dist/__tests__/db-rbac-schema.test.d.ts.map +1 -0
- package/dist/__tests__/db-rbac-schema.test.js +32 -0
- package/dist/__tests__/db-rbac-schema.test.js.map +1 -0
- package/dist/__tests__/db-sso-schema.test.d.ts +2 -0
- package/dist/__tests__/db-sso-schema.test.d.ts.map +1 -0
- package/dist/__tests__/db-sso-schema.test.js +48 -0
- package/dist/__tests__/db-sso-schema.test.js.map +1 -0
- package/dist/__tests__/helpers/license.d.ts +3 -0
- package/dist/__tests__/helpers/license.d.ts.map +1 -0
- package/dist/__tests__/helpers/license.js +74 -0
- package/dist/__tests__/helpers/license.js.map +1 -0
- package/dist/__tests__/license-audit-event.test.d.ts +2 -0
- package/dist/__tests__/license-audit-event.test.d.ts.map +1 -0
- package/dist/__tests__/license-audit-event.test.js +60 -0
- package/dist/__tests__/license-audit-event.test.js.map +1 -0
- package/dist/__tests__/license-end-to-end.test.d.ts +2 -0
- package/dist/__tests__/license-end-to-end.test.d.ts.map +1 -0
- package/dist/__tests__/license-end-to-end.test.js +75 -0
- package/dist/__tests__/license-end-to-end.test.js.map +1 -0
- package/dist/__tests__/license-public-key.test.d.ts +2 -0
- package/dist/__tests__/license-public-key.test.d.ts.map +1 -0
- package/dist/__tests__/license-public-key.test.js +18 -0
- package/dist/__tests__/license-public-key.test.js.map +1 -0
- package/dist/__tests__/license.test.js +195 -32
- package/dist/__tests__/license.test.js.map +1 -1
- package/dist/__tests__/pm-action-audit-events.test.d.ts +2 -0
- package/dist/__tests__/pm-action-audit-events.test.d.ts.map +1 -0
- package/dist/__tests__/pm-action-audit-events.test.js +185 -0
- package/dist/__tests__/pm-action-audit-events.test.js.map +1 -0
- package/dist/__tests__/pm-approvals.test.js +1 -1
- package/dist/__tests__/pm-approvals.test.js.map +1 -1
- package/dist/__tests__/pm-audit-retention-step.test.d.ts +2 -0
- package/dist/__tests__/pm-audit-retention-step.test.d.ts.map +1 -0
- package/dist/__tests__/pm-audit-retention-step.test.js +126 -0
- package/dist/__tests__/pm-audit-retention-step.test.js.map +1 -0
- package/dist/__tests__/pm-budget-alerts.test.d.ts +2 -0
- package/dist/__tests__/pm-budget-alerts.test.d.ts.map +1 -0
- package/dist/__tests__/pm-budget-alerts.test.js +128 -0
- package/dist/__tests__/pm-budget-alerts.test.js.map +1 -0
- package/dist/__tests__/pm-budget-refused-event.test.d.ts +2 -0
- package/dist/__tests__/pm-budget-refused-event.test.d.ts.map +1 -0
- package/dist/__tests__/pm-budget-refused-event.test.js +141 -0
- package/dist/__tests__/pm-budget-refused-event.test.js.map +1 -0
- package/dist/__tests__/pm-budget.test.js +138 -42
- package/dist/__tests__/pm-budget.test.js.map +1 -1
- package/dist/__tests__/pm-cost-rollup-step.test.d.ts +2 -0
- package/dist/__tests__/pm-cost-rollup-step.test.d.ts.map +1 -0
- package/dist/__tests__/pm-cost-rollup-step.test.js +113 -0
- package/dist/__tests__/pm-cost-rollup-step.test.js.map +1 -0
- package/dist/__tests__/pm-scheduler.test.js +48 -21
- package/dist/__tests__/pm-scheduler.test.js.map +1 -1
- package/dist/__tests__/pm-slack.test.js +37 -0
- package/dist/__tests__/pm-slack.test.js.map +1 -1
- package/dist/__tests__/pm-sso-prune-step.test.d.ts +2 -0
- package/dist/__tests__/pm-sso-prune-step.test.d.ts.map +1 -0
- package/dist/__tests__/pm-sso-prune-step.test.js +103 -0
- package/dist/__tests__/pm-sso-prune-step.test.js.map +1 -0
- package/dist/__tests__/pm-types.test.js +130 -1
- package/dist/__tests__/pm-types.test.js.map +1 -1
- package/dist/__tests__/policy/auto-merge-reviewer-gate.test.d.ts +2 -0
- package/dist/__tests__/policy/auto-merge-reviewer-gate.test.d.ts.map +1 -0
- package/dist/__tests__/policy/auto-merge-reviewer-gate.test.js +50 -0
- package/dist/__tests__/policy/auto-merge-reviewer-gate.test.js.map +1 -0
- package/dist/__tests__/policy/cost-gate.test.d.ts +2 -0
- package/dist/__tests__/policy/cost-gate.test.d.ts.map +1 -0
- package/dist/__tests__/policy/cost-gate.test.js +27 -0
- package/dist/__tests__/policy/cost-gate.test.js.map +1 -0
- package/dist/__tests__/policy/evaluate.test.d.ts +2 -0
- package/dist/__tests__/policy/evaluate.test.d.ts.map +1 -0
- package/dist/__tests__/policy/evaluate.test.js +105 -0
- package/dist/__tests__/policy/evaluate.test.js.map +1 -0
- package/dist/__tests__/policy/override.test.d.ts +2 -0
- package/dist/__tests__/policy/override.test.d.ts.map +1 -0
- package/dist/__tests__/policy/override.test.js +26 -0
- package/dist/__tests__/policy/override.test.js.map +1 -0
- package/dist/__tests__/policy/path-gate.test.d.ts +2 -0
- package/dist/__tests__/policy/path-gate.test.d.ts.map +1 -0
- package/dist/__tests__/policy/path-gate.test.js +31 -0
- package/dist/__tests__/policy/path-gate.test.js.map +1 -0
- package/dist/__tests__/policy/pr-reviewer-wiring.test.d.ts +2 -0
- package/dist/__tests__/policy/pr-reviewer-wiring.test.d.ts.map +1 -0
- package/dist/__tests__/policy/pr-reviewer-wiring.test.js +24 -0
- package/dist/__tests__/policy/pr-reviewer-wiring.test.js.map +1 -0
- package/dist/__tests__/policy/reviewer-gate.test.d.ts +2 -0
- package/dist/__tests__/policy/reviewer-gate.test.d.ts.map +1 -0
- package/dist/__tests__/policy/reviewer-gate.test.js +125 -0
- package/dist/__tests__/policy/reviewer-gate.test.js.map +1 -0
- package/dist/__tests__/policy-license.test.d.ts +2 -0
- package/dist/__tests__/policy-license.test.d.ts.map +1 -0
- package/dist/__tests__/policy-license.test.js +31 -0
- package/dist/__tests__/policy-license.test.js.map +1 -0
- package/dist/__tests__/policy-types.test.d.ts +2 -0
- package/dist/__tests__/policy-types.test.d.ts.map +1 -0
- package/dist/__tests__/policy-types.test.js +49 -0
- package/dist/__tests__/policy-types.test.js.map +1 -0
- package/dist/__tests__/ralph-gate.test.js +6 -4
- package/dist/__tests__/ralph-gate.test.js.map +1 -1
- package/dist/__tests__/rbac/bootstrap.test.d.ts +2 -0
- package/dist/__tests__/rbac/bootstrap.test.d.ts.map +1 -0
- package/dist/__tests__/rbac/bootstrap.test.js +62 -0
- package/dist/__tests__/rbac/bootstrap.test.js.map +1 -0
- package/dist/__tests__/rbac/matrix.test.d.ts +2 -0
- package/dist/__tests__/rbac/matrix.test.d.ts.map +1 -0
- package/dist/__tests__/rbac/matrix.test.js +62 -0
- package/dist/__tests__/rbac/matrix.test.js.map +1 -0
- package/dist/__tests__/rbac/user-role-store.test.d.ts +2 -0
- package/dist/__tests__/rbac/user-role-store.test.d.ts.map +1 -0
- package/dist/__tests__/rbac/user-role-store.test.js +78 -0
- package/dist/__tests__/rbac/user-role-store.test.js.map +1 -0
- package/dist/__tests__/rbac-defensive.test.d.ts +2 -0
- package/dist/__tests__/rbac-defensive.test.d.ts.map +1 -0
- package/dist/__tests__/rbac-defensive.test.js +29 -0
- package/dist/__tests__/rbac-defensive.test.js.map +1 -0
- package/dist/__tests__/rbac-integration.test.d.ts +2 -0
- package/dist/__tests__/rbac-integration.test.d.ts.map +1 -0
- package/dist/__tests__/rbac-integration.test.js +58 -0
- package/dist/__tests__/rbac-integration.test.js.map +1 -0
- package/dist/__tests__/rbac-license.test.d.ts +2 -0
- package/dist/__tests__/rbac-license.test.d.ts.map +1 -0
- package/dist/__tests__/rbac-license.test.js +27 -0
- package/dist/__tests__/rbac-license.test.js.map +1 -0
- package/dist/__tests__/reproduce-bec113-pagination-warning.test.js +14 -2
- package/dist/__tests__/reproduce-bec113-pagination-warning.test.js.map +1 -1
- package/dist/__tests__/reproduce-bec62.test.js +10 -3
- package/dist/__tests__/reproduce-bec62.test.js.map +1 -1
- package/dist/__tests__/reproduce-bec91-stuck-in-progress.test.js +24 -4
- package/dist/__tests__/reproduce-bec91-stuck-in-progress.test.js.map +1 -1
- package/dist/__tests__/server.test.js +46 -2
- package/dist/__tests__/server.test.js.map +1 -1
- package/dist/__tests__/sso-license.test.d.ts +2 -0
- package/dist/__tests__/sso-license.test.d.ts.map +1 -0
- package/dist/__tests__/sso-license.test.js +49 -0
- package/dist/__tests__/sso-license.test.js.map +1 -0
- package/dist/__tests__/start-todo.test.js +5 -0
- package/dist/__tests__/start-todo.test.js.map +1 -1
- package/dist/__tests__/webhook-handler.test.js +138 -0
- package/dist/__tests__/webhook-handler.test.js.map +1 -1
- package/dist/audit/config-fingerprint.d.ts +10 -0
- package/dist/audit/config-fingerprint.d.ts.map +1 -0
- package/dist/audit/config-fingerprint.js +20 -0
- package/dist/audit/config-fingerprint.js.map +1 -0
- package/dist/audit/csv.d.ts +8 -0
- package/dist/audit/csv.d.ts.map +1 -0
- package/dist/audit/csv.js +56 -0
- package/dist/audit/csv.js.map +1 -0
- package/dist/audit/events.d.ts +107 -0
- package/dist/audit/events.d.ts.map +1 -0
- package/dist/audit/events.js +221 -0
- package/dist/audit/events.js.map +1 -0
- package/dist/audit/index.d.ts +7 -0
- package/dist/audit/index.d.ts.map +1 -0
- package/dist/audit/index.js +7 -0
- package/dist/audit/index.js.map +1 -0
- package/dist/audit/projection.d.ts +38 -0
- package/dist/audit/projection.d.ts.map +1 -0
- package/dist/audit/projection.js +109 -0
- package/dist/audit/projection.js.map +1 -0
- package/dist/audit/reader.d.ts +42 -0
- package/dist/audit/reader.d.ts.map +1 -0
- package/dist/audit/reader.js +243 -0
- package/dist/audit/reader.js.map +1 -0
- package/dist/audit/retention.d.ts +12 -0
- package/dist/audit/retention.d.ts.map +1 -0
- package/dist/audit/retention.js +23 -0
- package/dist/audit/retention.js.map +1 -0
- package/dist/audit/writer.d.ts +26 -0
- package/dist/audit/writer.d.ts.map +1 -0
- package/dist/audit/writer.js +54 -0
- package/dist/audit/writer.js.map +1 -0
- package/dist/auth/index.d.ts +5 -0
- package/dist/auth/index.d.ts.map +1 -0
- package/dist/auth/index.js +5 -0
- package/dist/auth/index.js.map +1 -0
- package/dist/auth/session-store.d.ts +17 -0
- package/dist/auth/session-store.d.ts.map +1 -0
- package/dist/auth/session-store.js +59 -0
- package/dist/auth/session-store.js.map +1 -0
- package/dist/auth/sso-config.d.ts +14 -0
- package/dist/auth/sso-config.d.ts.map +1 -0
- package/dist/auth/sso-config.js +50 -0
- package/dist/auth/sso-config.js.map +1 -0
- package/dist/auth/user-store.d.ts +33 -0
- package/dist/auth/user-store.d.ts.map +1 -0
- package/dist/auth/user-store.js +71 -0
- package/dist/auth/user-store.js.map +1 -0
- package/dist/auth/workos-client.d.ts +46 -0
- package/dist/auth/workos-client.d.ts.map +1 -0
- package/dist/auth/workos-client.js +66 -0
- package/dist/auth/workos-client.js.map +1 -0
- package/dist/cost/aggregate.d.ts +49 -0
- package/dist/cost/aggregate.d.ts.map +1 -0
- package/dist/cost/aggregate.js +364 -0
- package/dist/cost/aggregate.js.map +1 -0
- package/dist/cost/csv.d.ts +12 -0
- package/dist/cost/csv.d.ts.map +1 -0
- package/dist/cost/csv.js +79 -0
- package/dist/cost/csv.js.map +1 -0
- package/dist/cost/index.d.ts +7 -0
- package/dist/cost/index.d.ts.map +1 -0
- package/dist/cost/index.js +7 -0
- package/dist/cost/index.js.map +1 -0
- package/dist/cost/per-run.d.ts +31 -0
- package/dist/cost/per-run.d.ts.map +1 -0
- package/dist/cost/per-run.js +35 -0
- package/dist/cost/per-run.js.map +1 -0
- package/dist/cost/rates.d.ts +27 -0
- package/dist/cost/rates.d.ts.map +1 -0
- package/dist/cost/rates.js +26 -0
- package/dist/cost/rates.js.map +1 -0
- package/dist/cost/rollup.d.ts +17 -0
- package/dist/cost/rollup.d.ts.map +1 -0
- package/dist/cost/rollup.js +164 -0
- package/dist/cost/rollup.js.map +1 -0
- package/dist/cost/types.d.ts +54 -0
- package/dist/cost/types.d.ts.map +1 -0
- package/dist/cost/types.js +2 -0
- package/dist/cost/types.js.map +1 -0
- package/dist/db/client.d.ts.map +1 -1
- package/dist/db/client.js +79 -1
- package/dist/db/client.js.map +1 -1
- package/dist/db/migrations/postgres/006_spend_caps.sql +14 -0
- package/dist/db/migrations/postgres/007_audit_events.sql +19 -0
- package/dist/db/migrations/postgres/008_cost_rollups.sql +19 -0
- package/dist/db/migrations/postgres/008_sso.sql +20 -0
- package/dist/db/migrations/sqlite/005_spend_caps.sql +16 -0
- package/dist/db/migrations/sqlite/006_audit_events.sql +19 -0
- package/dist/db/migrations/sqlite/007_cost_rollups.sql +19 -0
- package/dist/db/migrations/sqlite/007_sso.sql +20 -0
- package/dist/db/schema.d.ts +802 -0
- package/dist/db/schema.d.ts.map +1 -1
- package/dist/db/schema.js +80 -1
- package/dist/db/schema.js.map +1 -1
- package/dist/index.d.ts +7 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +8 -1
- package/dist/index.js.map +1 -1
- package/dist/license-public-key.d.ts +15 -0
- package/dist/license-public-key.d.ts.map +1 -0
- package/dist/license-public-key.js +15 -0
- package/dist/license-public-key.js.map +1 -0
- package/dist/license.d.ts +30 -5
- package/dist/license.d.ts.map +1 -1
- package/dist/license.js +142 -12
- package/dist/license.js.map +1 -1
- package/dist/pipeline/runner.d.ts +1 -7
- package/dist/pipeline/runner.d.ts.map +1 -1
- package/dist/pipeline/runner.js +168 -21
- package/dist/pipeline/runner.js.map +1 -1
- package/dist/pm/actions/promote.d.ts +3 -0
- package/dist/pm/actions/promote.d.ts.map +1 -1
- package/dist/pm/actions/promote.js +12 -0
- package/dist/pm/actions/promote.js.map +1 -1
- package/dist/pm/actions/resolve-approvals.d.ts.map +1 -1
- package/dist/pm/actions/resolve-approvals.js +16 -0
- package/dist/pm/actions/resolve-approvals.js.map +1 -1
- package/dist/pm/actions/start-todo.d.ts +3 -0
- package/dist/pm/actions/start-todo.d.ts.map +1 -1
- package/dist/pm/actions/start-todo.js +5 -1
- package/dist/pm/actions/start-todo.js.map +1 -1
- package/dist/pm/actions/triage.d.ts +3 -0
- package/dist/pm/actions/triage.d.ts.map +1 -1
- package/dist/pm/actions/triage.js +8 -0
- package/dist/pm/actions/triage.js.map +1 -1
- package/dist/pm/budget-alerts.d.ts +18 -0
- package/dist/pm/budget-alerts.d.ts.map +1 -0
- package/dist/pm/budget-alerts.js +100 -0
- package/dist/pm/budget-alerts.js.map +1 -0
- package/dist/pm/budget.d.ts +28 -5
- package/dist/pm/budget.d.ts.map +1 -1
- package/dist/pm/budget.js +115 -39
- package/dist/pm/budget.js.map +1 -1
- package/dist/pm/scheduler.d.ts +8 -4
- package/dist/pm/scheduler.d.ts.map +1 -1
- package/dist/pm/scheduler.js +128 -5
- package/dist/pm/scheduler.js.map +1 -1
- package/dist/pm/slack.d.ts.map +1 -1
- package/dist/pm/slack.js +11 -0
- package/dist/pm/slack.js.map +1 -1
- package/dist/pm/types.d.ts +36 -0
- package/dist/pm/types.d.ts.map +1 -1
- package/dist/pm/types.js +12 -0
- package/dist/pm/types.js.map +1 -1
- package/dist/policy/cost-gate.d.ts +3 -0
- package/dist/policy/cost-gate.d.ts.map +1 -0
- package/dist/policy/cost-gate.js +11 -0
- package/dist/policy/cost-gate.js.map +1 -0
- package/dist/policy/evaluate.d.ts +32 -0
- package/dist/policy/evaluate.d.ts.map +1 -0
- package/dist/policy/evaluate.js +61 -0
- package/dist/policy/evaluate.js.map +1 -0
- package/dist/policy/index.d.ts +7 -0
- package/dist/policy/index.d.ts.map +1 -0
- package/dist/policy/index.js +7 -0
- package/dist/policy/index.js.map +1 -0
- package/dist/policy/override.d.ts +23 -0
- package/dist/policy/override.d.ts.map +1 -0
- package/dist/policy/override.js +26 -0
- package/dist/policy/override.js.map +1 -0
- package/dist/policy/path-gate.d.ts +3 -0
- package/dist/policy/path-gate.d.ts.map +1 -0
- package/dist/policy/path-gate.js +20 -0
- package/dist/policy/path-gate.js.map +1 -0
- package/dist/policy/reviewer-gate.d.ts +45 -0
- package/dist/policy/reviewer-gate.d.ts.map +1 -0
- package/dist/policy/reviewer-gate.js +77 -0
- package/dist/policy/reviewer-gate.js.map +1 -0
- package/dist/policy/types.d.ts +7 -0
- package/dist/policy/types.d.ts.map +1 -0
- package/dist/policy/types.js +2 -0
- package/dist/policy/types.js.map +1 -0
- package/dist/rbac/errors.d.ts +7 -0
- package/dist/rbac/errors.d.ts.map +1 -0
- package/dist/rbac/errors.js +13 -0
- package/dist/rbac/errors.js.map +1 -0
- package/dist/rbac/index.d.ts +5 -0
- package/dist/rbac/index.d.ts.map +1 -0
- package/dist/rbac/index.js +5 -0
- package/dist/rbac/index.js.map +1 -0
- package/dist/rbac/matrix.d.ts +35 -0
- package/dist/rbac/matrix.d.ts.map +1 -0
- package/dist/rbac/matrix.js +42 -0
- package/dist/rbac/matrix.js.map +1 -0
- package/dist/rbac/types.d.ts +2 -0
- package/dist/rbac/types.d.ts.map +1 -0
- package/dist/rbac/types.js +2 -0
- package/dist/rbac/types.js.map +1 -0
- package/dist/rbac/user-role-store.d.ts +27 -0
- package/dist/rbac/user-role-store.d.ts.map +1 -0
- package/dist/rbac/user-role-store.js +148 -0
- package/dist/rbac/user-role-store.js.map +1 -0
- package/dist/repo/git.d.ts +9 -0
- package/dist/repo/git.d.ts.map +1 -1
- package/dist/repo/git.js +11 -0
- package/dist/repo/git.js.map +1 -1
- package/dist/repo/github.d.ts +4 -0
- package/dist/repo/github.d.ts.map +1 -1
- package/dist/repo/github.js +27 -0
- package/dist/repo/github.js.map +1 -1
- package/dist/repo/gitlab.d.ts +4 -0
- package/dist/repo/gitlab.d.ts.map +1 -1
- package/dist/repo/gitlab.js +7 -0
- package/dist/repo/gitlab.js.map +1 -1
- package/dist/server.d.ts +6 -0
- package/dist/server.d.ts.map +1 -1
- package/dist/server.js +16 -10
- package/dist/server.js.map +1 -1
- package/dist/types.d.ts +155 -0
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js +83 -0
- package/dist/types.js.map +1 -1
- package/dist/util/glob.d.ts +7 -0
- package/dist/util/glob.d.ts.map +1 -0
- package/dist/util/glob.js +20 -0
- package/dist/util/glob.js.map +1 -0
- package/dist/webhook/handler.d.ts +3 -0
- package/dist/webhook/handler.d.ts.map +1 -1
- package/dist/webhook/handler.js +30 -1
- package/dist/webhook/handler.js.map +1 -1
- package/package.json +2 -1
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Check whether a Linear issue carries the configured override label.
|
|
3
|
+
* Case-insensitive match.
|
|
4
|
+
*
|
|
5
|
+
* SECURITY NOTE: This bypass relies on Linear label creation being restricted
|
|
6
|
+
* to authorized team members. Operators should ensure that the configured
|
|
7
|
+
* override label (default "policy-override") can only be created and applied
|
|
8
|
+
* by principals trusted to bypass policy gates. In permissive Linear
|
|
9
|
+
* workspaces, consider using a label name that's less likely to be created
|
|
10
|
+
* accidentally, or disable the override mechanism entirely by setting
|
|
11
|
+
* `overrideLabel` to a sentinel value that no one will use.
|
|
12
|
+
*
|
|
13
|
+
* Uses Linear SDK lazy-relation method pattern — `.labels` is a method,
|
|
14
|
+
* not a property.
|
|
15
|
+
*/
|
|
16
|
+
export declare function hasOverrideLabel(issue: {
|
|
17
|
+
labels: () => Promise<{
|
|
18
|
+
nodes: Array<{
|
|
19
|
+
name: string;
|
|
20
|
+
}>;
|
|
21
|
+
}>;
|
|
22
|
+
}, labelName: string): Promise<boolean>;
|
|
23
|
+
//# sourceMappingURL=override.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"override.d.ts","sourceRoot":"","sources":["../../src/policy/override.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AACH,wBAAsB,gBAAgB,CACpC,KAAK,EAAE;IAAE,MAAM,EAAE,MAAM,OAAO,CAAC;QAAE,KAAK,EAAE,KAAK,CAAC;YAAE,IAAI,EAAE,MAAM,CAAA;SAAE,CAAC,CAAA;KAAE,CAAC,CAAA;CAAE,EACpE,SAAS,EAAE,MAAM,GAChB,OAAO,CAAC,OAAO,CAAC,CAQlB"}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Check whether a Linear issue carries the configured override label.
|
|
3
|
+
* Case-insensitive match.
|
|
4
|
+
*
|
|
5
|
+
* SECURITY NOTE: This bypass relies on Linear label creation being restricted
|
|
6
|
+
* to authorized team members. Operators should ensure that the configured
|
|
7
|
+
* override label (default "policy-override") can only be created and applied
|
|
8
|
+
* by principals trusted to bypass policy gates. In permissive Linear
|
|
9
|
+
* workspaces, consider using a label name that's less likely to be created
|
|
10
|
+
* accidentally, or disable the override mechanism entirely by setting
|
|
11
|
+
* `overrideLabel` to a sentinel value that no one will use.
|
|
12
|
+
*
|
|
13
|
+
* Uses Linear SDK lazy-relation method pattern — `.labels` is a method,
|
|
14
|
+
* not a property.
|
|
15
|
+
*/
|
|
16
|
+
export async function hasOverrideLabel(issue, labelName) {
|
|
17
|
+
try {
|
|
18
|
+
const labels = await issue.labels();
|
|
19
|
+
const target = labelName.toLowerCase();
|
|
20
|
+
return labels.nodes.some((l) => l.name.toLowerCase() === target);
|
|
21
|
+
}
|
|
22
|
+
catch {
|
|
23
|
+
return false;
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
//# sourceMappingURL=override.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"override.js","sourceRoot":"","sources":["../../src/policy/override.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AACH,MAAM,CAAC,KAAK,UAAU,gBAAgB,CACpC,KAAoE,EACpE,SAAiB;IAEjB,IAAI,CAAC;QACH,MAAM,MAAM,GAAG,MAAM,KAAK,CAAC,MAAM,EAAE,CAAC;QACpC,MAAM,MAAM,GAAG,SAAS,CAAC,WAAW,EAAE,CAAC;QACvC,OAAO,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,WAAW,EAAE,KAAK,MAAM,CAAC,CAAC;IACnE,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,KAAK,CAAC;IACf,CAAC;AACH,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"path-gate.d.ts","sourceRoot":"","sources":["../../src/policy/path-gate.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAElD,wBAAgB,qBAAqB,CACnC,YAAY,EAAE,MAAM,EAAE,EACtB,QAAQ,EAAE,MAAM,EAAE,GACjB,eAAe,EAAE,CAgBnB"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { matchesAnyPattern } from "../util/glob.js";
|
|
2
|
+
export function evaluatePathBlocklist(changedFiles, patterns) {
|
|
3
|
+
if (patterns.length === 0)
|
|
4
|
+
return [];
|
|
5
|
+
const violations = [];
|
|
6
|
+
for (const file of changedFiles) {
|
|
7
|
+
for (const pattern of patterns) {
|
|
8
|
+
if (matchesAnyPattern(file, [pattern])) {
|
|
9
|
+
violations.push({
|
|
10
|
+
gate: "path",
|
|
11
|
+
detail: `${file} matches ${pattern}`,
|
|
12
|
+
severity: "blocking",
|
|
13
|
+
payload: { path: file, pattern },
|
|
14
|
+
});
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
return violations;
|
|
19
|
+
}
|
|
20
|
+
//# sourceMappingURL=path-gate.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"path-gate.js","sourceRoot":"","sources":["../../src/policy/path-gate.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,MAAM,iBAAiB,CAAC;AAGpD,MAAM,UAAU,qBAAqB,CACnC,YAAsB,EACtB,QAAkB;IAElB,IAAI,QAAQ,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,EAAE,CAAC;IACrC,MAAM,UAAU,GAAsB,EAAE,CAAC;IACzC,KAAK,MAAM,IAAI,IAAI,YAAY,EAAE,CAAC;QAChC,KAAK,MAAM,OAAO,IAAI,QAAQ,EAAE,CAAC;YAC/B,IAAI,iBAAiB,CAAC,IAAI,EAAE,CAAC,OAAO,CAAC,CAAC,EAAE,CAAC;gBACvC,UAAU,CAAC,IAAI,CAAC;oBACd,IAAI,EAAE,MAAM;oBACZ,MAAM,EAAE,GAAG,IAAI,YAAY,OAAO,EAAE;oBACpC,QAAQ,EAAE,UAAU;oBACpB,OAAO,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE,OAAO,EAAE;iBACjC,CAAC,CAAC;YACL,CAAC;QACH,CAAC;IACH,CAAC;IACD,OAAO,UAAU,CAAC;AACpB,CAAC"}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import type { Policy } from "../types.js";
|
|
2
|
+
/** Test-only: clear the team membership cache between runs. */
|
|
3
|
+
export declare function _clearTeamMembershipCache(): void;
|
|
4
|
+
export interface ReviewerRequest {
|
|
5
|
+
users: string[];
|
|
6
|
+
teams: string[];
|
|
7
|
+
}
|
|
8
|
+
export declare function buildReviewerRequest(policy: Policy | undefined): ReviewerRequest | null;
|
|
9
|
+
export interface ApprovalVerification {
|
|
10
|
+
satisfied: boolean;
|
|
11
|
+
missingUsers: string[];
|
|
12
|
+
missingTeams: string[];
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* Query a GitHub PR's reviews and compare approving reviewers against the
|
|
16
|
+
* required set. A required user is satisfied if they personally approved.
|
|
17
|
+
* A required team is satisfied if any member of the team approved.
|
|
18
|
+
*/
|
|
19
|
+
export declare function verifyApprovalsReceived(octokit: {
|
|
20
|
+
pulls: {
|
|
21
|
+
listReviews: (args: {
|
|
22
|
+
owner: string;
|
|
23
|
+
repo: string;
|
|
24
|
+
pull_number: number;
|
|
25
|
+
}) => Promise<{
|
|
26
|
+
data: Array<{
|
|
27
|
+
user: {
|
|
28
|
+
login: string;
|
|
29
|
+
} | null;
|
|
30
|
+
state: string;
|
|
31
|
+
}>;
|
|
32
|
+
}>;
|
|
33
|
+
};
|
|
34
|
+
teams: {
|
|
35
|
+
listMembersInOrg: (args: {
|
|
36
|
+
org: string;
|
|
37
|
+
team_slug: string;
|
|
38
|
+
}) => Promise<{
|
|
39
|
+
data: Array<{
|
|
40
|
+
login: string;
|
|
41
|
+
}>;
|
|
42
|
+
}>;
|
|
43
|
+
};
|
|
44
|
+
}, owner: string, repo: string, pull_number: number, required: ReviewerRequest): Promise<ApprovalVerification>;
|
|
45
|
+
//# sourceMappingURL=reviewer-gate.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"reviewer-gate.d.ts","sourceRoot":"","sources":["../../src/policy/reviewer-gate.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AAqB1C,+DAA+D;AAC/D,wBAAgB,yBAAyB,IAAI,IAAI,CAEhD;AAED,MAAM,WAAW,eAAe;IAC9B,KAAK,EAAE,MAAM,EAAE,CAAC;IAChB,KAAK,EAAE,MAAM,EAAE,CAAC;CACjB;AAED,wBAAgB,oBAAoB,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,GAAG,eAAe,GAAG,IAAI,CAKvF;AAED,MAAM,WAAW,oBAAoB;IACnC,SAAS,EAAE,OAAO,CAAC;IACnB,YAAY,EAAE,MAAM,EAAE,CAAC;IACvB,YAAY,EAAE,MAAM,EAAE,CAAC;CACxB;AAED;;;;GAIG;AACH,wBAAsB,uBAAuB,CAC3C,OAAO,EAAE;IACP,KAAK,EAAE;QACL,WAAW,EAAE,CAAC,IAAI,EAAE;YAClB,KAAK,EAAE,MAAM,CAAC;YACd,IAAI,EAAE,MAAM,CAAC;YACb,WAAW,EAAE,MAAM,CAAC;SACrB,KAAK,OAAO,CAAC;YAAE,IAAI,EAAE,KAAK,CAAC;gBAAE,IAAI,EAAE;oBAAE,KAAK,EAAE,MAAM,CAAA;iBAAE,GAAG,IAAI,CAAC;gBAAC,KAAK,EAAE,MAAM,CAAA;aAAE,CAAC,CAAA;SAAE,CAAC,CAAC;KACnF,CAAC;IACF,KAAK,EAAE;QACL,gBAAgB,EAAE,CAAC,IAAI,EAAE;YACvB,GAAG,EAAE,MAAM,CAAC;YACZ,SAAS,EAAE,MAAM,CAAC;SACnB,KAAK,OAAO,CAAC;YAAE,IAAI,EAAE,KAAK,CAAC;gBAAE,KAAK,EAAE,MAAM,CAAA;aAAE,CAAC,CAAA;SAAE,CAAC,CAAC;KACnD,CAAC;CACH,EACD,KAAK,EAAE,MAAM,EACb,IAAI,EAAE,MAAM,EACZ,WAAW,EAAE,MAAM,EACnB,QAAQ,EAAE,eAAe,GACxB,OAAO,CAAC,oBAAoB,CAAC,CA+C/B"}
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* TTL cache for GitHub team membership lookups. High-frequency CI webhooks on
|
|
3
|
+
* a PR with multiple required teams otherwise call `listMembersInOrg` on every
|
|
4
|
+
* check, exhausting GitHub's secondary rate limit.
|
|
5
|
+
*
|
|
6
|
+
* Cache key: `${org}/${team_slug}`. Stale entries are evicted on read.
|
|
7
|
+
* Default TTL: 15 minutes (team rosters change infrequently).
|
|
8
|
+
*
|
|
9
|
+
* This is module-level state — acceptable here because (a) team membership is
|
|
10
|
+
* not tenant-scoped in any way within a single process, and (b) the cache is
|
|
11
|
+
* memory-only so key rotation requires a process restart anyway.
|
|
12
|
+
*/
|
|
13
|
+
const TEAM_CACHE_TTL_MS = 15 * 60 * 1000;
|
|
14
|
+
const teamCache = new Map();
|
|
15
|
+
/** Test-only: clear the team membership cache between runs. */
|
|
16
|
+
export function _clearTeamMembershipCache() {
|
|
17
|
+
teamCache.clear();
|
|
18
|
+
}
|
|
19
|
+
export function buildReviewerRequest(policy) {
|
|
20
|
+
const r = policy?.mandatoryReviewers;
|
|
21
|
+
if (!r)
|
|
22
|
+
return null;
|
|
23
|
+
if (r.users.length === 0 && r.teams.length === 0)
|
|
24
|
+
return null;
|
|
25
|
+
return { users: [...r.users], teams: [...r.teams] };
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Query a GitHub PR's reviews and compare approving reviewers against the
|
|
29
|
+
* required set. A required user is satisfied if they personally approved.
|
|
30
|
+
* A required team is satisfied if any member of the team approved.
|
|
31
|
+
*/
|
|
32
|
+
export async function verifyApprovalsReceived(octokit, owner, repo, pull_number, required) {
|
|
33
|
+
if (required.users.length === 0 && required.teams.length === 0) {
|
|
34
|
+
return { satisfied: true, missingUsers: [], missingTeams: [] };
|
|
35
|
+
}
|
|
36
|
+
const reviews = await octokit.pulls.listReviews({ owner, repo, pull_number });
|
|
37
|
+
// De-dup by user: listReviews returns reviews chronologically (oldest first),
|
|
38
|
+
// so iterating and overwriting gives the latest state per user. A user who
|
|
39
|
+
// APPROVED then CHANGES_REQUESTED must NOT count as approved.
|
|
40
|
+
const latestByUser = new Map();
|
|
41
|
+
for (const r of reviews.data) {
|
|
42
|
+
if (r.user)
|
|
43
|
+
latestByUser.set(r.user.login.toLowerCase(), r.state);
|
|
44
|
+
}
|
|
45
|
+
const approved = new Set(Array.from(latestByUser.entries())
|
|
46
|
+
.filter(([, state]) => state === "APPROVED")
|
|
47
|
+
.map(([login]) => login));
|
|
48
|
+
const missingUsers = required.users.filter((u) => !approved.has(u.toLowerCase()));
|
|
49
|
+
const missingTeams = [];
|
|
50
|
+
const now = Date.now();
|
|
51
|
+
for (const team of required.teams) {
|
|
52
|
+
// Null byte separator: unambiguous even if a future API allows "/" in
|
|
53
|
+
// org or team slugs. GitHub today forbids "/" in both, so this is
|
|
54
|
+
// defensive rather than strictly necessary.
|
|
55
|
+
const cacheKey = `${owner}\x00${team}`;
|
|
56
|
+
let memberLogins;
|
|
57
|
+
const cached = teamCache.get(cacheKey);
|
|
58
|
+
if (cached && cached.expiresAt > now) {
|
|
59
|
+
memberLogins = cached.members;
|
|
60
|
+
}
|
|
61
|
+
else {
|
|
62
|
+
const members = await octokit.teams.listMembersInOrg({ org: owner, team_slug: team });
|
|
63
|
+
memberLogins = members.data.map((m) => m.login.toLowerCase());
|
|
64
|
+
teamCache.set(cacheKey, { members: memberLogins, expiresAt: now + TEAM_CACHE_TTL_MS });
|
|
65
|
+
}
|
|
66
|
+
const memberSet = new Set(memberLogins);
|
|
67
|
+
const anyApproved = Array.from(approved).some((u) => memberSet.has(u));
|
|
68
|
+
if (!anyApproved)
|
|
69
|
+
missingTeams.push(team);
|
|
70
|
+
}
|
|
71
|
+
return {
|
|
72
|
+
satisfied: missingUsers.length === 0 && missingTeams.length === 0,
|
|
73
|
+
missingUsers,
|
|
74
|
+
missingTeams,
|
|
75
|
+
};
|
|
76
|
+
}
|
|
77
|
+
//# sourceMappingURL=reviewer-gate.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"reviewer-gate.js","sourceRoot":"","sources":["../../src/policy/reviewer-gate.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/policy/types.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,eAAe;IAC9B,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,UAAU,CAAC;IACnC,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,UAAU,CAAC;IACrB,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CAClC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/policy/types.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../../src/rbac/errors.ts"],"names":[],"mappings":"AAAA,qBAAa,eAAgB,SAAQ,KAAK;;CAKzC;AAED,qBAAa,cAAe,SAAQ,KAAK;;CAKxC"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
export class SelfDemoteError extends Error {
|
|
2
|
+
constructor() {
|
|
3
|
+
super("An admin cannot demote themselves");
|
|
4
|
+
this.name = "SelfDemoteError";
|
|
5
|
+
}
|
|
6
|
+
}
|
|
7
|
+
export class LastAdminError extends Error {
|
|
8
|
+
constructor() {
|
|
9
|
+
super("Cannot demote the last remaining admin");
|
|
10
|
+
this.name = "LastAdminError";
|
|
11
|
+
}
|
|
12
|
+
}
|
|
13
|
+
//# sourceMappingURL=errors.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"errors.js","sourceRoot":"","sources":["../../src/rbac/errors.ts"],"names":[],"mappings":"AAAA,MAAM,OAAO,eAAgB,SAAQ,KAAK;IACxC;QACE,KAAK,CAAC,mCAAmC,CAAC,CAAC;QAC3C,IAAI,CAAC,IAAI,GAAG,iBAAiB,CAAC;IAChC,CAAC;CACF;AAED,MAAM,OAAO,cAAe,SAAQ,KAAK;IACvC;QACE,KAAK,CAAC,wCAAwC,CAAC,CAAC;QAChD,IAAI,CAAC,IAAI,GAAG,gBAAgB,CAAC;IAC/B,CAAC;CACF"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/rbac/index.ts"],"names":[],"mappings":"AAAA,cAAc,YAAY,CAAC;AAC3B,cAAc,aAAa,CAAC;AAC5B,cAAc,aAAa,CAAC;AAC5B,cAAc,sBAAsB,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/rbac/index.ts"],"names":[],"mappings":"AAAA,cAAc,YAAY,CAAC;AAC3B,cAAc,aAAa,CAAC;AAC5B,cAAc,aAAa,CAAC;AAC5B,cAAc,sBAAsB,CAAC"}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import type { Role } from "./types.js";
|
|
2
|
+
export declare const PERMISSION_MATRIX: {
|
|
3
|
+
readonly "runs.view": readonly ["admin", "operator", "viewer"];
|
|
4
|
+
readonly "runs.retry": readonly ["admin", "operator"];
|
|
5
|
+
readonly "tokens.view": readonly ["admin", "operator", "viewer"];
|
|
6
|
+
readonly "audit.view": readonly ["admin", "operator"];
|
|
7
|
+
readonly "audit.export": readonly ["admin", "operator"];
|
|
8
|
+
readonly "cost.view": readonly ["admin", "operator"];
|
|
9
|
+
readonly "cost.export": readonly ["admin", "operator"];
|
|
10
|
+
readonly "errors.view": readonly ["admin", "operator", "viewer"];
|
|
11
|
+
readonly "coordination.view": readonly ["admin", "operator"];
|
|
12
|
+
readonly "config.view": readonly ["admin"];
|
|
13
|
+
readonly "users.view": readonly ["admin"];
|
|
14
|
+
readonly "users.manage": readonly ["admin"];
|
|
15
|
+
};
|
|
16
|
+
export type PermissionKey = keyof typeof PERMISSION_MATRIX;
|
|
17
|
+
/**
|
|
18
|
+
* Check whether `role` is allowed to perform `action`.
|
|
19
|
+
*
|
|
20
|
+
* Defensive license gate: returns `false` (fail closed, "no permission") with
|
|
21
|
+
* a structured warn when the `rbac` feature is not licensed. The gate is
|
|
22
|
+
* additive to — not a replacement for — the upstream guards in the dashboard
|
|
23
|
+
* middleware and the runs UI, both of which already skip calling `canAccess`
|
|
24
|
+
* in OSS mode. Its purpose is to ensure any future direct caller of the rbac
|
|
25
|
+
* module — a new route, CLI command, third-party integration — cannot
|
|
26
|
+
* silently grant permissions without a license check.
|
|
27
|
+
*
|
|
28
|
+
* Returns `false` rather than throwing because callers (e.g., the canRetry
|
|
29
|
+
* ternary in `dashboard/src/routes/runs.ts`) treat the result as a predicate.
|
|
30
|
+
* Initializers that cannot tolerate a silent denial should mirror the
|
|
31
|
+
* `getDefaultWorkosClient` pattern in `auth/workos-client.ts` (throws
|
|
32
|
+
* `LicenseRequiredError`).
|
|
33
|
+
*/
|
|
34
|
+
export declare function canAccess(role: Role, action: PermissionKey): boolean;
|
|
35
|
+
//# sourceMappingURL=matrix.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"matrix.d.ts","sourceRoot":"","sources":["../../src/rbac/matrix.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,YAAY,CAAC;AAMvC,eAAO,MAAM,iBAAiB;;;;;;;;;;;;;CAasB,CAAC;AAErD,MAAM,MAAM,aAAa,GAAG,MAAM,OAAO,iBAAiB,CAAC;AAE3D;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,SAAS,CAAC,IAAI,EAAE,IAAI,EAAE,MAAM,EAAE,aAAa,GAAG,OAAO,CASpE"}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import { isFeatureLicensed } from "../license.js";
|
|
2
|
+
import { createLogger } from "../logger.js";
|
|
3
|
+
const log = createLogger({ component: "rbac" });
|
|
4
|
+
export const PERMISSION_MATRIX = {
|
|
5
|
+
"runs.view": ["admin", "operator", "viewer"],
|
|
6
|
+
"runs.retry": ["admin", "operator"],
|
|
7
|
+
"tokens.view": ["admin", "operator", "viewer"],
|
|
8
|
+
"audit.view": ["admin", "operator"],
|
|
9
|
+
"audit.export": ["admin", "operator"],
|
|
10
|
+
"cost.view": ["admin", "operator"],
|
|
11
|
+
"cost.export": ["admin", "operator"],
|
|
12
|
+
"errors.view": ["admin", "operator", "viewer"],
|
|
13
|
+
"coordination.view": ["admin", "operator"],
|
|
14
|
+
"config.view": ["admin"],
|
|
15
|
+
"users.view": ["admin"],
|
|
16
|
+
"users.manage": ["admin"],
|
|
17
|
+
};
|
|
18
|
+
/**
|
|
19
|
+
* Check whether `role` is allowed to perform `action`.
|
|
20
|
+
*
|
|
21
|
+
* Defensive license gate: returns `false` (fail closed, "no permission") with
|
|
22
|
+
* a structured warn when the `rbac` feature is not licensed. The gate is
|
|
23
|
+
* additive to — not a replacement for — the upstream guards in the dashboard
|
|
24
|
+
* middleware and the runs UI, both of which already skip calling `canAccess`
|
|
25
|
+
* in OSS mode. Its purpose is to ensure any future direct caller of the rbac
|
|
26
|
+
* module — a new route, CLI command, third-party integration — cannot
|
|
27
|
+
* silently grant permissions without a license check.
|
|
28
|
+
*
|
|
29
|
+
* Returns `false` rather than throwing because callers (e.g., the canRetry
|
|
30
|
+
* ternary in `dashboard/src/routes/runs.ts`) treat the result as a predicate.
|
|
31
|
+
* Initializers that cannot tolerate a silent denial should mirror the
|
|
32
|
+
* `getDefaultWorkosClient` pattern in `auth/workos-client.ts` (throws
|
|
33
|
+
* `LicenseRequiredError`).
|
|
34
|
+
*/
|
|
35
|
+
export function canAccess(role, action) {
|
|
36
|
+
if (!isFeatureLicensed("rbac")) {
|
|
37
|
+
log.warn({ feature: "rbac", action, role }, "canAccess called without an enterprise license — denying (fail closed)");
|
|
38
|
+
return false;
|
|
39
|
+
}
|
|
40
|
+
return PERMISSION_MATRIX[action].includes(role);
|
|
41
|
+
}
|
|
42
|
+
//# sourceMappingURL=matrix.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"matrix.js","sourceRoot":"","sources":["../../src/rbac/matrix.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,iBAAiB,EAAE,MAAM,eAAe,CAAC;AAClD,OAAO,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AAE5C,MAAM,GAAG,GAAG,YAAY,CAAC,EAAE,SAAS,EAAE,MAAM,EAAE,CAAC,CAAC;AAEhD,MAAM,CAAC,MAAM,iBAAiB,GAAG;IAC/B,WAAW,EAAU,CAAC,OAAO,EAAE,UAAU,EAAE,QAAQ,CAAC;IACpD,YAAY,EAAS,CAAC,OAAO,EAAE,UAAU,CAAC;IAC1C,aAAa,EAAQ,CAAC,OAAO,EAAE,UAAU,EAAE,QAAQ,CAAC;IACpD,YAAY,EAAS,CAAC,OAAO,EAAE,UAAU,CAAC;IAC1C,cAAc,EAAO,CAAC,OAAO,EAAE,UAAU,CAAC;IAC1C,WAAW,EAAU,CAAC,OAAO,EAAE,UAAU,CAAC;IAC1C,aAAa,EAAQ,CAAC,OAAO,EAAE,UAAU,CAAC;IAC1C,aAAa,EAAQ,CAAC,OAAO,EAAE,UAAU,EAAE,QAAQ,CAAC;IACpD,mBAAmB,EAAE,CAAC,OAAO,EAAE,UAAU,CAAC;IAC1C,aAAa,EAAQ,CAAC,OAAO,CAAC;IAC9B,YAAY,EAAS,CAAC,OAAO,CAAC;IAC9B,cAAc,EAAO,CAAC,OAAO,CAAC;CACoB,CAAC;AAIrD;;;;;;;;;;;;;;;;GAgBG;AACH,MAAM,UAAU,SAAS,CAAC,IAAU,EAAE,MAAqB;IACzD,IAAI,CAAC,iBAAiB,CAAC,MAAM,CAAC,EAAE,CAAC;QAC/B,GAAG,CAAC,IAAI,CACN,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,EACjC,wEAAwE,CACzE,CAAC;QACF,OAAO,KAAK,CAAC;IACf,CAAC;IACD,OAAQ,iBAAiB,CAAC,MAAM,CAAqB,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC;AACvE,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/rbac/types.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,IAAI,GAAG,OAAO,GAAG,UAAU,GAAG,QAAQ,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/rbac/types.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import type { AnyDb } from "../db/client.js";
|
|
2
|
+
import type { Role } from "./types.js";
|
|
3
|
+
export interface SetUserRoleArgs {
|
|
4
|
+
userId: string;
|
|
5
|
+
newRole: Role;
|
|
6
|
+
actorUserId: string;
|
|
7
|
+
reason?: string;
|
|
8
|
+
}
|
|
9
|
+
export declare function setUserRole(db: AnyDb, args: SetUserRoleArgs): Promise<void>;
|
|
10
|
+
export declare function getUserRole(db: AnyDb, userId: string): Promise<Role | null>;
|
|
11
|
+
/**
|
|
12
|
+
* If the user's email matches `envAdminList` (comma-separated, case-insensitive),
|
|
13
|
+
* promote them to admin. Idempotent — already-admin users are not re-promoted
|
|
14
|
+
* and no audit event is written. Emits a `dashboard.manual_action` event with
|
|
15
|
+
* `action: "bootstrap_admin"` on successful promotion.
|
|
16
|
+
*
|
|
17
|
+
* Returns true if the role was changed.
|
|
18
|
+
*/
|
|
19
|
+
export declare function applyBootstrapAdmins(db: AnyDb, email: string, userId: string, envAdminList: string | undefined): Promise<boolean>;
|
|
20
|
+
export declare function listUsers(db: AnyDb): Promise<Array<{
|
|
21
|
+
id: string;
|
|
22
|
+
email: string;
|
|
23
|
+
name: string | null;
|
|
24
|
+
role: Role;
|
|
25
|
+
lastLoginAt: Date | null;
|
|
26
|
+
}>>;
|
|
27
|
+
//# sourceMappingURL=user-role-store.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"user-role-store.d.ts","sourceRoot":"","sources":["../../src/rbac/user-role-store.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,iBAAiB,CAAC;AAS7C,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,YAAY,CAAC;AAGvC,MAAM,WAAW,eAAe;IAC9B,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,IAAI,CAAC;IACd,WAAW,EAAE,MAAM,CAAC;IACpB,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,wBAAsB,WAAW,CAAC,EAAE,EAAE,KAAK,EAAE,IAAI,EAAE,eAAe,GAAG,OAAO,CAAC,IAAI,CAAC,CA+FjF;AAED,wBAAsB,WAAW,CAAC,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,GAAG,IAAI,CAAC,CAOjF;AAED;;;;;;;GAOG;AACH,wBAAsB,oBAAoB,CACxC,EAAE,EAAE,KAAK,EACT,KAAK,EAAE,MAAM,EACb,MAAM,EAAE,MAAM,EACd,YAAY,EAAE,MAAM,GAAG,SAAS,GAC/B,OAAO,CAAC,OAAO,CAAC,CA+BlB;AAED,wBAAsB,SAAS,CAAC,EAAE,EAAE,KAAK,GAAG,OAAO,CACjD,KAAK,CAAC;IACJ,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IACpB,IAAI,EAAE,IAAI,CAAC;IACX,WAAW,EAAE,IAAI,GAAG,IAAI,CAAC;CAC1B,CAAC,CACH,CAYA"}
|
|
@@ -0,0 +1,148 @@
|
|
|
1
|
+
import { and, eq, ne, count, sql } from "drizzle-orm";
|
|
2
|
+
import { isPostgres } from "../db/client.js";
|
|
3
|
+
import { dashboardUsers } from "../db/schema.js";
|
|
4
|
+
import { logAuditEvent, dashboardGrantRoleEvent, dashboardRevokeRoleEvent, dashboardBootstrapAdminEvent, } from "../audit/index.js";
|
|
5
|
+
import { SelfDemoteError, LastAdminError } from "./errors.js";
|
|
6
|
+
export async function setUserRole(db, args) {
|
|
7
|
+
// The SELECT current / SELECT COUNT / UPDATE sequence MUST share a
|
|
8
|
+
// transaction to close the TOCTOU race on the last-admin guard. Two
|
|
9
|
+
// concurrent demotions must not both see `otherAdmins > 0`.
|
|
10
|
+
//
|
|
11
|
+
// Driver note: drizzle's `db.transaction(async ...)` is NOT supported on
|
|
12
|
+
// better-sqlite3 (it throws "Transaction function cannot return a
|
|
13
|
+
// promise"). For SQLite we issue `BEGIN IMMEDIATE` / `COMMIT` manually,
|
|
14
|
+
// which acquires a RESERVED lock and serializes concurrent writers.
|
|
15
|
+
// For Postgres we use the native drizzle transaction API.
|
|
16
|
+
// `logAuditEvent` is fire-and-forget and runs outside the transaction.
|
|
17
|
+
let oldRole;
|
|
18
|
+
let actorEmail = "unknown";
|
|
19
|
+
let targetEmail;
|
|
20
|
+
const body = async (handle) => {
|
|
21
|
+
const currentRows = await handle
|
|
22
|
+
.select()
|
|
23
|
+
.from(dashboardUsers)
|
|
24
|
+
.where(eq(dashboardUsers.id, args.userId));
|
|
25
|
+
if (currentRows.length === 0)
|
|
26
|
+
throw new Error(`user not found: ${args.userId}`);
|
|
27
|
+
const current = currentRows[0];
|
|
28
|
+
oldRole = current.role;
|
|
29
|
+
targetEmail = current.email;
|
|
30
|
+
// Idempotent no-op
|
|
31
|
+
if (oldRole === args.newRole)
|
|
32
|
+
return;
|
|
33
|
+
// Self-lockout
|
|
34
|
+
if (args.userId === args.actorUserId && args.newRole !== "admin") {
|
|
35
|
+
throw new SelfDemoteError();
|
|
36
|
+
}
|
|
37
|
+
// Last-admin guard: if target is currently admin and we're demoting, count other admins
|
|
38
|
+
if (oldRole === "admin" && args.newRole !== "admin") {
|
|
39
|
+
const [row] = await handle
|
|
40
|
+
.select({ n: count() })
|
|
41
|
+
.from(dashboardUsers)
|
|
42
|
+
.where(and(eq(dashboardUsers.role, "admin"), ne(dashboardUsers.id, args.userId)));
|
|
43
|
+
const otherAdmins = Number(row?.n ?? 0);
|
|
44
|
+
if (otherAdmins === 0)
|
|
45
|
+
throw new LastAdminError();
|
|
46
|
+
}
|
|
47
|
+
await handle
|
|
48
|
+
.update(dashboardUsers)
|
|
49
|
+
.set({ role: args.newRole })
|
|
50
|
+
.where(eq(dashboardUsers.id, args.userId));
|
|
51
|
+
const actorRows = await handle
|
|
52
|
+
.select()
|
|
53
|
+
.from(dashboardUsers)
|
|
54
|
+
.where(eq(dashboardUsers.id, args.actorUserId));
|
|
55
|
+
actorEmail = actorRows[0]?.email ?? "unknown";
|
|
56
|
+
};
|
|
57
|
+
if (isPostgres(db)) {
|
|
58
|
+
await db.transaction(async (tx) => {
|
|
59
|
+
await body(tx);
|
|
60
|
+
});
|
|
61
|
+
}
|
|
62
|
+
else {
|
|
63
|
+
// SQLite path — manual transaction. Use BEGIN IMMEDIATE to grab the
|
|
64
|
+
// RESERVED lock up front, avoiding SQLITE_BUSY under contention.
|
|
65
|
+
await db.run(sql `BEGIN IMMEDIATE`);
|
|
66
|
+
try {
|
|
67
|
+
await body(db);
|
|
68
|
+
await db.run(sql `COMMIT`);
|
|
69
|
+
}
|
|
70
|
+
catch (err) {
|
|
71
|
+
try {
|
|
72
|
+
await db.run(sql `ROLLBACK`);
|
|
73
|
+
}
|
|
74
|
+
catch {
|
|
75
|
+
// ignore rollback errors
|
|
76
|
+
}
|
|
77
|
+
throw err;
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
// Early-exit idempotent no-op: skip audit write.
|
|
81
|
+
if (oldRole === args.newRole)
|
|
82
|
+
return;
|
|
83
|
+
const isRevoke = args.newRole === "viewer";
|
|
84
|
+
const builder = isRevoke ? dashboardRevokeRoleEvent : dashboardGrantRoleEvent;
|
|
85
|
+
await logAuditEvent(db, builder({
|
|
86
|
+
targetUserId: args.userId,
|
|
87
|
+
targetEmail: targetEmail,
|
|
88
|
+
oldRole: oldRole,
|
|
89
|
+
newRole: args.newRole,
|
|
90
|
+
actorUserId: args.actorUserId,
|
|
91
|
+
actorEmail,
|
|
92
|
+
}));
|
|
93
|
+
}
|
|
94
|
+
export async function getUserRole(db, userId) {
|
|
95
|
+
const rows = await db
|
|
96
|
+
.select()
|
|
97
|
+
.from(dashboardUsers)
|
|
98
|
+
.where(eq(dashboardUsers.id, userId));
|
|
99
|
+
if (rows.length === 0)
|
|
100
|
+
return null;
|
|
101
|
+
return rows[0].role;
|
|
102
|
+
}
|
|
103
|
+
/**
|
|
104
|
+
* If the user's email matches `envAdminList` (comma-separated, case-insensitive),
|
|
105
|
+
* promote them to admin. Idempotent — already-admin users are not re-promoted
|
|
106
|
+
* and no audit event is written. Emits a `dashboard.manual_action` event with
|
|
107
|
+
* `action: "bootstrap_admin"` on successful promotion.
|
|
108
|
+
*
|
|
109
|
+
* Returns true if the role was changed.
|
|
110
|
+
*/
|
|
111
|
+
export async function applyBootstrapAdmins(db, email, userId, envAdminList) {
|
|
112
|
+
if (!envAdminList || envAdminList.trim() === "")
|
|
113
|
+
return false;
|
|
114
|
+
const normalizedEmail = email.trim().toLowerCase();
|
|
115
|
+
const adminSet = new Set(envAdminList
|
|
116
|
+
.split(",")
|
|
117
|
+
.map((s) => s.trim().toLowerCase())
|
|
118
|
+
.filter(Boolean));
|
|
119
|
+
if (!adminSet.has(normalizedEmail))
|
|
120
|
+
return false;
|
|
121
|
+
// Already admin? No-op.
|
|
122
|
+
const currentRole = await getUserRole(db, userId);
|
|
123
|
+
if (currentRole === "admin")
|
|
124
|
+
return false;
|
|
125
|
+
// Promote. Bypass setUserRole because the actor is "system", not a user, and
|
|
126
|
+
// the self-demote/last-admin guards don't apply.
|
|
127
|
+
await db
|
|
128
|
+
.update(dashboardUsers)
|
|
129
|
+
.set({ role: "admin" })
|
|
130
|
+
.where(eq(dashboardUsers.id, userId));
|
|
131
|
+
await logAuditEvent(db, dashboardBootstrapAdminEvent({
|
|
132
|
+
targetUserId: userId,
|
|
133
|
+
targetEmail: normalizedEmail,
|
|
134
|
+
}));
|
|
135
|
+
return true;
|
|
136
|
+
}
|
|
137
|
+
export async function listUsers(db) {
|
|
138
|
+
const rows = await db.select().from(dashboardUsers);
|
|
139
|
+
const mapped = rows.map((r) => ({
|
|
140
|
+
id: r.id,
|
|
141
|
+
email: r.email,
|
|
142
|
+
name: r.name ?? null,
|
|
143
|
+
role: r.role,
|
|
144
|
+
lastLoginAt: r.lastLoginAt ?? null,
|
|
145
|
+
}));
|
|
146
|
+
return mapped.sort((a, b) => a.email.localeCompare(b.email));
|
|
147
|
+
}
|
|
148
|
+
//# sourceMappingURL=user-role-store.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"user-role-store.js","sourceRoot":"","sources":["../../src/rbac/user-role-store.ts"],"names":[],"mappings":"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"}
|
package/dist/repo/git.d.ts
CHANGED
|
@@ -146,6 +146,15 @@ export declare function createPRViaCli(options: {
|
|
|
146
146
|
title: string;
|
|
147
147
|
body: string;
|
|
148
148
|
draft?: boolean;
|
|
149
|
+
/** GitHub usernames to request review from. */
|
|
150
|
+
reviewers?: string[];
|
|
151
|
+
/** GitHub team slugs (without owner prefix) to request review from. */
|
|
152
|
+
teamReviewers?: string[];
|
|
153
|
+
/**
|
|
154
|
+
* Repo owner — required when `teamReviewers` is supplied because
|
|
155
|
+
* `gh pr create --reviewer` expects `owner/team-slug` for team reviewers.
|
|
156
|
+
*/
|
|
157
|
+
owner?: string;
|
|
149
158
|
}): Promise<string>;
|
|
150
159
|
/**
|
|
151
160
|
* Merge a PR using the `gh` CLI. Returns true on success.
|
package/dist/repo/git.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"git.d.ts","sourceRoot":"","sources":["../../src/repo/git.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"git.d.ts","sourceRoot":"","sources":["../../src/repo/git.ts"],"names":[],"mappings":"AAqBA;;;;;GAKG;AACH,wBAAgB,OAAO,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,GAAG,EAAE,MAAM,EAAE,SAAS,SAAU,GAAG,OAAO,CAAC,MAAM,CAAC,CAiBzF;AAED;;;;GAIG;AACH,wBAAsB,WAAW,CAC/B,IAAI,EAAE,MAAM,EAAE,EACd,GAAG,EAAE,MAAM,EACX,SAAS,SAAS,GACjB,OAAO,CAAC,MAAM,CAAC,CAMjB;AAED;;;GAGG;AACH,wBAAgB,UAAU,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,GAAG,EAAE,MAAM,EAAE,SAAS,SAAS,GAAG,OAAO,CAAC,MAAM,CAAC,CAY3F;AAED;;GAEG;AACH,wBAAsB,SAAS,CAAC,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CA2BvE;AAED;;GAEG;AACH,wBAAsB,WAAW,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAEhE;AA0CD;;;;;GAKG;AACH,wBAAsB,cAAc,CAClC,OAAO,EAAE,MAAM,EACf,KAAK,EAAE,MAAM,EACb,MAAM,EAAE,MAAM,EACd,OAAO,GAAE,MAA0B,GAClC,OAAO,CAAC,MAAM,CAAC,CAMjB;AAED;;;;;;GAMG;AACH,wBAAsB,wBAAwB,CAC5C,OAAO,EAAE,MAAM,EACf,KAAK,EAAE,MAAM,EACb,MAAM,EAAE,MAAM,EACd,OAAO,GAAE,MAA0B,GAClC,OAAO,CAAC,MAAM,CAAC,CAOjB;AAED;;;GAGG;AACH,wBAAsB,gBAAgB,CAAC,YAAY,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAE5E;AAED;;;;;;;;;GASG;AACH,wBAAsB,iBAAiB,CACrC,YAAY,EAAE,MAAM,EACpB,cAAc,EAAE,MAAM,GACrB,OAAO,CAAC,IAAI,CAAC,CAUf;AAED;;;;;;;;;;GAUG;AACH,wBAAsB,kBAAkB,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CA0DvE;AAED;;GAEG;AACH,wBAAsB,cAAc,CAAC,YAAY,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAoBxE;AAED;;;;GAIG;AACH,wBAAsB,UAAU,CAC9B,YAAY,EAAE,MAAM,EACpB,MAAM,EAAE,MAAM,GACb,OAAO,CAAC,IAAI,CAAC,CAGf;AAED;;;;;;;;GAQG;AACH,wBAAsB,YAAY,CAChC,YAAY,EAAE,MAAM,EACpB,UAAU,EAAE,MAAM,GACjB,OAAO,CAAC;IAAE,OAAO,EAAE,OAAO,CAAC;IAAC,YAAY,EAAE,OAAO,CAAA;CAAE,CAAC,CA2BtD;AAED;;;GAGG;AACH,wBAAsB,WAAW,CAAC,YAAY,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAErE;AAED;;;;;;GAMG;AACH,wBAAsB,eAAe,CACnC,YAAY,EAAE,MAAM,EACpB,MAAM,EAAE,MAAM,GACb,OAAO,CAAC,IAAI,CAAC,CAGf;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,kBAAkB,CAChC,MAAM,EAAE,MAAM,EACd,cAAc,EAAE,OAAO,GACtB,kBAAkB,GAAG,UAAU,CAKjC;AAED;;;;;;;;;;;GAWG;AACH,wBAAsB,iBAAiB,CACrC,YAAY,EAAE,MAAM,EACpB,OAAO,EAAE,MAAM,EACf,cAAc,CAAC,EAAE,MAAM,GACtB,OAAO,CAAC,OAAO,CAAC,CAqBlB;AAED;;;;;GAKG;AACH,wBAAsB,eAAe,CACnC,YAAY,EAAE,MAAM,EACpB,UAAU,EAAE,MAAM,GACjB,OAAO,CAAC,MAAM,EAAE,CAAC,CAsBnB;AAED;;;GAGG;AACH,wBAAsB,cAAc,CAAC,OAAO,EAAE;IAC5C,YAAY,EAAE,MAAM,CAAC;IACrB,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,+CAA+C;IAC/C,SAAS,CAAC,EAAE,MAAM,EAAE,CAAC;IACrB,uEAAuE;IACvE,aAAa,CAAC,EAAE,MAAM,EAAE,CAAC;IACzB;;;OAGG;IACH,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB,GAAG,OAAO,CAAC,MAAM,CAAC,CA0ClB;AAED;;GAEG;AACH,wBAAsB,aAAa,CACjC,YAAY,EAAE,MAAM,EACpB,MAAM,EAAE,MAAM,GACb,OAAO,CAAC,OAAO,CAAC,CAgBlB;AAED;;;;GAIG;AACH,wBAAsB,eAAe,CAAC,YAAY,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,CAWjG;AAED;;;;GAIG;AACH,wBAAsB,gBAAgB,CAAC,YAAY,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAchG;AAED;;;;;GAKG;AACH,wBAAsB,oBAAoB,CACxC,OAAO,EAAE,MAAM,EACf,OAAO,EAAE,MAAM,GACd,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAuBxB;AAED;;GAEG;AACH,wBAAgB,UAAU,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,MAAM,CAEhE;AAED;;;;;;GAMG;AACH,wBAAsB,gBAAgB,CACpC,OAAO,EAAE,MAAM,EACf,QAAQ,GAAE,MAAW,GACpB,OAAO,CAAC,MAAM,EAAE,CAAC,CAoCnB"}
|