Skip to content

Commit

Permalink
feat(core): add specifier type for * & latest
Browse files Browse the repository at this point in the history
Closes #174
  • Loading branch information
JamieMason committed Dec 29, 2023
1 parent ddd179f commit 23f8bde
Show file tree
Hide file tree
Showing 4 changed files with 37 additions and 6 deletions.
4 changes: 2 additions & 2 deletions src/specifier/index.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -165,8 +165,8 @@ describe('supported version formats', () => {
version: '~1.0.0',
},
{
name: 'range',
expected: 'Range',
name: 'latest',
expected: 'Latest',
version: '*',
},
{
Expand Down
10 changes: 7 additions & 3 deletions src/specifier/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import { DeleteSpecifier } from './delete';
import { ExactSpecifier } from './exact';
import { FileSpecifier } from './file';
import { HostedGitSpecifier } from './hosted-git';
import { LatestSpecifier } from './latest';
import { parseSpecifier } from './lib/parse-specifier';
import { RangeSpecifier } from './range';
import { TagSpecifier } from './tag';
Expand All @@ -15,25 +16,27 @@ import { WorkspaceProtocolSpecifier } from './workspace-protocol';
export namespace Specifier {
export const Alias = AliasSpecifier;
export const Delete = DeleteSpecifier;
export const Exact = ExactSpecifier;
export const File = FileSpecifier;
export const HostedGit = HostedGitSpecifier;
export const Latest = LatestSpecifier;
export const Range = RangeSpecifier;
export const Tag = TagSpecifier;
export const Unsupported = UnsupportedSpecifier;
export const Url = UrlSpecifier;
export const Version = ExactSpecifier;
export const WorkspaceProtocol = WorkspaceProtocolSpecifier;

export type Any =
| AliasSpecifier
| DeleteSpecifier
| ExactSpecifier
| FileSpecifier
| HostedGitSpecifier
| LatestSpecifier
| RangeSpecifier
| TagSpecifier
| UnsupportedSpecifier
| UrlSpecifier
| ExactSpecifier
| WorkspaceProtocolSpecifier;

export function create(instance: Instance, raw: string | Delete): Specifier.Any {
Expand All @@ -44,7 +47,8 @@ export namespace Specifier {
const parsed = parseSpecifier(instance.name, raw, instance.packageJsonFile);
const type = parsed.type;
const data = { instance, raw };
if (type === 'version') return new Specifier.Version(data);
if (raw === '*') return new Specifier.Latest(data);
if (type === 'version') return new Specifier.Exact(data);
if (type === 'range') return new Specifier.Range(data);
if (type === 'workspaceProtocol') return new Specifier.WorkspaceProtocol(data);
if (type === 'alias') return new Specifier.Alias(data);
Expand Down
28 changes: 28 additions & 0 deletions src/specifier/latest.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import { Effect, pipe } from 'effect';
import { Specifier } from '.';
import { BaseSpecifier } from './base';
import { NonSemverError } from './lib/non-semver-error';
import type { SpecificRegistryResult } from './lib/specific-registry-result';

type T = SpecificRegistryResult<'range'>;

/**
* @example "*"
*/
export class LatestSpecifier extends BaseSpecifier<T> {
_tag = 'Latest' as const;

/** Return the semver version including the range */
getSemver(): Effect.Effect<never, NonSemverError, string> {
return pipe(
this.parse(),
Effect.mapError(() => new NonSemverError({ specifier: this })),
Effect.map((parsed) => parsed.fetchSpec),
);
}

/** Get a new `Specifier` from the given semver version applied to this one */
setSemver(version: string): Effect.Effect<never, never, Specifier.Any> {
return Effect.succeed(Specifier.create(this.instance, version));
}
}
1 change: 0 additions & 1 deletion src/specifier/range.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ import type { SpecificRegistryResult } from './lib/specific-registry-result';
type T = SpecificRegistryResult<'range'>;

/**
* @example "*"
* @example "^1.2.3"
*/
export class RangeSpecifier extends BaseSpecifier<T> {
Expand Down

0 comments on commit 23f8bde

Please sign in to comment.