JamieMason/syncpack

View on GitHub
src/specifier/hosted-git.ts

Summary

Maintainability
A
0 mins
Test Coverage
C
72%
import { Effect, pipe } from 'effect';
import type { HostedGitResult } from 'npm-package-arg';
import { isSemver } from '../guards/is-semver.js';
import { BaseSpecifier } from './base.js';
import { Specifier } from './index.js';
import { NonSemverError } from './lib/non-semver-error.js';

/** @example "git+https://github.com/user/foo" */
export class HostedGitSpecifier extends BaseSpecifier<HostedGitResult> {
  _tag = 'HostedGit';

  /** The public name referenced in config */
  name = 'hosted-git' as const;

  /** Return the git tag if it is valid semver */
  getSemver(): Effect.Effect<string, NonSemverError> {
    return pipe(
      this.parse(),
      Effect.mapError(() => new NonSemverError({ specifier: this })),
      Effect.map((parsed) => parsed.gitCommittish || ''),
      Effect.flatMap((gitCommittish) =>
        isSemver(gitCommittish) ? Effect.succeed(gitCommittish) : NonSemverError.asEffect(this),
      ),
    );
  }

  /** Get a new `Specifier` from the given semver version applied to this one */
  setSemver(version: string): Effect.Effect<Specifier.Any, NonSemverError> {
    return pipe(
      this.parse(),
      Effect.mapError(() => new NonSemverError({ specifier: this })),
      Effect.map((parsed) => ({
        gitCommittish: parsed.gitCommittish || '',
        rawSpec: parsed.rawSpec || '',
      })),
      Effect.map(({ gitCommittish, rawSpec }) => rawSpec.replace(gitCommittish, version)),
      Effect.map((raw) => Specifier.create(this.instance, raw)),
    );
  }
}