65 lines · 2.1 KB
import type { PermissionsSpec } from "./spec";

export const TOKEN_SCOPES = [
  "contents",
  "actions",
  "issues",
  "pull-requests",
  "deployments",
  "statuses",
  "id-token",
] as const;

export type TokenScope = (typeof TOKEN_SCOPES)[number];
export type AccessLevel = "read" | "write";
export type TokenPermissions = Partial<Record<TokenScope, AccessLevel>>;

const DEFAULT_PERMISSIONS: TokenPermissions = {
  contents: "read",
  actions: "read",
  issues: "read",
  "pull-requests": "read",
  deployments: "read",
  statuses: "read",
};

function isScope(value: string): value is TokenScope {
  return (TOKEN_SCOPES as readonly string[]).includes(value);
}

function expand(spec: PermissionsSpec): TokenPermissions {
  if (spec === "read-all" || spec === "write-all") {
    const level: AccessLevel = spec === "read-all" ? "read" : "write";
    return Object.fromEntries(TOKEN_SCOPES.filter((scope) => scope !== "id-token").map((scope) => [scope, level]));
  }
  const out: TokenPermissions = {};
  for (const [scope, level] of Object.entries(spec)) {
    if (isScope(scope) && level !== "none") out[scope] = level;
  }
  return out;
}