All files / src/entities instance-version.ts

100% Statements 28/28
100% Branches 16/16
100% Functions 4/4
100% Lines 24/24

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 5525x   25x 25x               25x 33x 33x       25x 49x 49x     21x                   25x   66x 66x   59x   7x 6x 6x 5x 4x 4x 3x       25x 6x 4x      
import { ConnectionManager } from '../services/ConnectionManager';
import type { GitLabTier } from '../services/GitLabVersionDetector';
import { getGitLabApiUrlFromContext } from '../oauth/token-context';
import { parseVersion } from '../utils/version';
 
/**
 * Whether the GitLab instance serving the current request is at least `minVersion`.
 * Used where a version gate cannot live in tool requirements, e.g. a parameter
 * whose availability differs per action. The version is detected at startup, so
 * this is an in-memory read; an unknown version fails open.
 */
export function instanceAtLeast(minVersion: string): boolean {
  const version = currentInstance()?.version ?? 'unknown';
  return version === 'unknown' || parseVersion(version) >= parseVersion(minVersion);
}
 
/** Detected version/tier of the instance serving the current request, if known. */
export function currentInstance(): { version: string; tier: GitLabTier } | undefined {
  try {
    return ConnectionManager.getInstance().getInstanceInfo(getGitLabApiUrlFromContext());
  } catch {
    // Connection not initialised: nothing is known yet.
    return undefined;
  }
}
 
/**
 * Whether the GraphQL schema of the instance serving the current request has the
 * type, field and argument. Lets a handler pick its native query or a fallback
 * from what the instance actually exposes (version, edition and feature flags
 * alike). True when the schema is not known yet (fail-open to the native path).
 */
export function graphqlSupports(typeName: string, fieldName?: string, argName?: string): boolean {
  let index;
  try {
    index = ConnectionManager.getInstance().getSchemaInfo(getGitLabApiUrlFromContext()).fieldIndex;
  } catch {
    return true;
  }
  if (!index) return true;
  const fields = index.get(typeName);
  if (!fields) return false;
  if (!fieldName) return true;
  const field = fields.get(fieldName);
  if (!field) return false;
  return !argName || field.args.has(argName);
}
 
/** Throw a clear error when the instance is older than `minVersion` for `feature`. */
export function assertInstanceAtLeast(minVersion: string, feature: string): void {
  if (!instanceAtLeast(minVersion)) {
    throw new Error(`${feature} requires GitLab ${minVersion}+`);
  }
}