diff --git a/docs/architecture.md b/docs/architecture.md
index fbbded5..d78a9ba 100644
--- a/docs/architecture.md
+++ b/docs/architecture.md
@@ -25,8 +25,25 @@ executable `bin/packref` imports that output.
| `manifests` | Detect project manifests and resolve declared dependencies to exact versions. JavaScript is the v1 adapter. |
| `sources` | Normalize, select, and fetch repository or tarball source, including source-specific external adapters. |
| `store` | Address and manage immutable global source snapshots by package identity. |
-| `workspace` | Own the Packref lockfile, user-level state, project paths, integrations, and reference materialization adapters. |
-| `core` | Define package identity, package specs, source types, registry contracts, and shared typed errors. |
+| `workspace` | Own the Packref lockfile, user-level state, integrations, and reference materialization adapters. |
+| `layout` | Define the on-disk paths of project state and user-level state, and the Packref home. |
+| `core` | Define package identity, package specs, repository hosts, source types, registries, and shared typed errors. |
+
+### Layers
+
+Dependencies inside `src/lib` point in a single direction. A folder imports only folders in lower
+layers, and folders in the same layer do not import each other:
+
+1. `core` and `shared`
+2. `layout`
+3. `registries`, `manifests`, `store`, and `workspace`
+4. `sources` (imports `store` to write snapshots)
+5. `references`
+
+`oxlint.config.ts` enforces these layers with one `no-restricted-imports` override for each folder.
+`import/no-relative-parent-imports` stops relative imports from bypassing these overrides, and
+`import/no-cycle` rejects import cycles between files. When you add a folder or a dependency, update
+the overrides.
Commands remain thin so the `references` interface is also the main behavior test seam. Registry and
manifest adapters do not know filesystem layout, while source adapters do not know project manifests
@@ -95,7 +112,8 @@ src/
commands/ CLI command definitions
terminal/ prompts, logs, spinners, titles, and cancellation
lib/
- core/ identities, sources, errors, registry contracts
+ core/ identities, specs, repository hosts, sources, registries, errors
+ layout/ on-disk paths and the Packref home
manifests/ project dependency adapters
references/ command-aligned domain workflows
registries/ package registry adapters
diff --git a/oxlint.config.ts b/oxlint.config.ts
index b8dda9d..11104a1 100644
--- a/oxlint.config.ts
+++ b/oxlint.config.ts
@@ -10,7 +10,215 @@ export default defineConfig({
typeAware: true,
typeCheck: true,
},
+ overrides: [
+ // Each `src/lib` folder imports only the folders in lower layers. See the layers in
+ // `docs/architecture.md`. `references` is the top layer and may import every other folder.
+ {
+ files: ["src/lib/**/*.ts"],
+ rules: {
+ "import/no-relative-parent-imports": "error",
+ },
+ },
+ {
+ files: ["src/lib/core/**/*.ts"],
+ rules: {
+ "no-restricted-imports": [
+ "error",
+ {
+ patterns: [
+ {
+ group: [
+ "#lib/layout/**",
+ "#lib/manifests/**",
+ "#lib/references/**",
+ "#lib/registries/**",
+ "#lib/shared/**",
+ "#lib/sources/**",
+ "#lib/store/**",
+ "#lib/workspace/**",
+ ],
+ message: "core must not import other lib folders.",
+ },
+ ],
+ },
+ ],
+ },
+ },
+ {
+ files: ["src/lib/shared/**/*.ts"],
+ rules: {
+ "no-restricted-imports": [
+ "error",
+ {
+ patterns: [
+ {
+ group: [
+ "#lib/core/**",
+ "#lib/layout/**",
+ "#lib/manifests/**",
+ "#lib/references/**",
+ "#lib/registries/**",
+ "#lib/sources/**",
+ "#lib/store/**",
+ "#lib/workspace/**",
+ ],
+ message: "shared must not import other lib folders.",
+ },
+ ],
+ },
+ ],
+ },
+ },
+ {
+ files: ["src/lib/layout/**/*.ts"],
+ rules: {
+ "no-restricted-imports": [
+ "error",
+ {
+ patterns: [
+ {
+ group: [
+ "#lib/manifests/**",
+ "#lib/references/**",
+ "#lib/registries/**",
+ "#lib/shared/**",
+ "#lib/sources/**",
+ "#lib/store/**",
+ "#lib/workspace/**",
+ ],
+ message: "layout may import only core.",
+ },
+ ],
+ },
+ ],
+ },
+ },
+ {
+ files: ["src/lib/manifests/**/*.ts"],
+ rules: {
+ "no-restricted-imports": [
+ "error",
+ {
+ patterns: [
+ {
+ group: [
+ "#lib/layout/**",
+ "#lib/references/**",
+ "#lib/registries/**",
+ "#lib/shared/**",
+ "#lib/sources/**",
+ "#lib/store/**",
+ "#lib/workspace/**",
+ ],
+ message: "manifests may import only core.",
+ },
+ ],
+ },
+ ],
+ },
+ },
+ {
+ files: ["src/lib/registries/**/*.ts"],
+ rules: {
+ "no-restricted-imports": [
+ "error",
+ {
+ patterns: [
+ {
+ group: [
+ "#lib/layout/**",
+ "#lib/manifests/**",
+ "#lib/references/**",
+ "#lib/shared/**",
+ "#lib/sources/**",
+ "#lib/store/**",
+ "#lib/workspace/**",
+ ],
+ message: "registries may import only core.",
+ },
+ ],
+ },
+ ],
+ },
+ },
+ {
+ files: ["src/lib/store/**/*.ts"],
+ rules: {
+ "no-restricted-imports": [
+ "error",
+ {
+ patterns: [
+ {
+ group: [
+ "#lib/manifests/**",
+ "#lib/references/**",
+ "#lib/registries/**",
+ "#lib/sources/**",
+ "#lib/workspace/**",
+ ],
+ message: "store may import only core, layout, shared.",
+ },
+ ],
+ },
+ ],
+ },
+ },
+ {
+ files: ["src/lib/workspace/**/*.ts"],
+ rules: {
+ "no-restricted-imports": [
+ "error",
+ {
+ patterns: [
+ {
+ group: [
+ "#lib/manifests/**",
+ "#lib/references/**",
+ "#lib/registries/**",
+ "#lib/sources/**",
+ "#lib/store/**",
+ ],
+ message: "workspace may import only core, layout, shared.",
+ },
+ ],
+ },
+ ],
+ },
+ },
+ {
+ files: ["src/lib/sources/**/*.ts"],
+ rules: {
+ "no-restricted-imports": [
+ "error",
+ {
+ patterns: [
+ {
+ group: [
+ "#lib/layout/**",
+ "#lib/manifests/**",
+ "#lib/references/**",
+ "#lib/registries/**",
+ "#lib/workspace/**",
+ ],
+ message: "sources may import only core, shared, store.",
+ },
+ ],
+ },
+ ],
+ },
+ },
+ {
+ // Tests compose layers from several folders to build their fixtures.
+ files: ["src/lib/**/__tests__/**/*.ts"],
+ rules: {
+ "import/no-relative-parent-imports": "off",
+ "no-restricted-imports": "off",
+ },
+ },
+ ],
rules: {
+ // Also report cycles that pass through type-only imports.
+ "import/no-cycle": ["error", { ignoreTypes: false }],
// Effect combinators such as `Option.some(value)`, `Option.flatMap(fn)`, and
// `Effect.map(effect, fn)` are indistinguishable from array iteration methods
// to these array-specific rules.
diff --git a/src/__tests__/add.integration.test.ts b/src/__tests__/add.integration.test.ts
index 49316f5..b219bda 100644
--- a/src/__tests__/add.integration.test.ts
+++ b/src/__tests__/add.integration.test.ts
@@ -7,6 +7,7 @@ import * as Effect from "effect/Effect"
import * as Layer from "effect/Layer"
import { afterEach, describe, expect, it } from "vitest"
import { parsePackageSpec } from "#lib/core/packages.ts"
+import { PackrefHome } from "#lib/layout/home.ts"
import { ProjectDependencyReader } from "#lib/manifests/index.ts"
import { PackageManagerResolver } from "#lib/manifests/javascript.ts"
import { PackageManagerDetector } from "#lib/manifests/package-manager-detector.ts"
@@ -14,7 +15,6 @@ import { addPackageReference } from "#lib/references/add.ts"
import { NpmRegistryClient } from "#lib/registries/npm/client.ts"
import { RepositoryDownloader } from "#lib/sources/repository/fetch.ts"
import { RemoteTagReader } from "#lib/sources/repository/tags.ts"
-import { PackrefHome } from "#lib/workspace/home.ts"
import { Reflinker } from "#lib/workspace/reflinker.ts"
const temporaryPaths: string[] = []
diff --git a/src/commands/add.ts b/src/commands/add.ts
index a4afaf2..8b60b18 100644
--- a/src/commands/add.ts
+++ b/src/commands/add.ts
@@ -5,7 +5,8 @@ import * as Effect from "effect/Effect"
import * as Option from "effect/Option"
import * as Predicate from "effect/Predicate"
import type { ManifestDependency } from "#lib/manifests/manifest.ts"
-import { formatPackageIdentity, parsePackageSpec } from "#lib/core/packages.ts"
+import { formatPackageIdentity } from "#lib/core/identity.ts"
+import { parsePackageSpec } from "#lib/core/packages.ts"
import {
addPackageReference,
findPackageCandidates,
diff --git a/src/commands/list.ts b/src/commands/list.ts
index 1b991bb..33aa407 100644
--- a/src/commands/list.ts
+++ b/src/commands/list.ts
@@ -1,7 +1,7 @@
import * as Command from "effect/cli/Command"
import * as Effect from "effect/Effect"
import color from "picocolors"
-import { formatPackageIdentity } from "#lib/core/packages.ts"
+import { formatPackageIdentity } from "#lib/core/identity.ts"
import { listPackageEntries, readProjectLockfile } from "#lib/workspace/lockfile.ts"
import { requireInitializedProject } from "#lib/workspace/project.ts"
import { Prompter } from "#terminal/prompter.ts"
diff --git a/src/commands/prune.ts b/src/commands/prune.ts
index 84519e3..faaf696 100644
--- a/src/commands/prune.ts
+++ b/src/commands/prune.ts
@@ -1,6 +1,6 @@
import * as Command from "effect/cli/Command"
import * as Effect from "effect/Effect"
-import { formatPackageIdentity } from "#lib/core/packages.ts"
+import { formatPackageIdentity } from "#lib/core/identity.ts"
import { applyPrunePlan, discoverPrunePlan } from "#lib/references/prune.ts"
import { Prompter } from "#terminal/prompter.ts"
import { printTitle } from "#terminal/title.ts"
diff --git a/src/commands/remove.ts b/src/commands/remove.ts
index fb0570a..296444b 100644
--- a/src/commands/remove.ts
+++ b/src/commands/remove.ts
@@ -4,7 +4,8 @@ import * as Command from "effect/cli/Command"
import * as Effect from "effect/Effect"
import * as Option from "effect/Option"
import type { PackageEntry } from "#lib/workspace/lockfile.ts"
-import { formatPackageIdentity, parsePackageSpec } from "#lib/core/packages.ts"
+import { formatPackageIdentity } from "#lib/core/identity.ts"
+import { parsePackageSpec } from "#lib/core/packages.ts"
import {
findPackageReferenceMatches,
listPackageReferences,
diff --git a/src/commands/sync.ts b/src/commands/sync.ts
index e497b90..7b03887 100644
--- a/src/commands/sync.ts
+++ b/src/commands/sync.ts
@@ -1,6 +1,6 @@
import * as Command from "effect/cli/Command"
import * as Effect from "effect/Effect"
-import { formatPackageIdentity } from "#lib/core/packages.ts"
+import { formatPackageIdentity } from "#lib/core/identity.ts"
import {
preparePackageReferenceSync,
syncPackageReferences,
diff --git a/src/lib/core/__tests__/packages.test.ts b/src/lib/core/__tests__/packages.test.ts
index 4e9ff6a..003710c 100644
--- a/src/lib/core/__tests__/packages.test.ts
+++ b/src/lib/core/__tests__/packages.test.ts
@@ -7,12 +7,11 @@ import {
UnsupportedRepositoryHostError,
} from "#lib/core/errors.ts"
import {
- getPackageIdentitySegments,
packageCoordinatesEquivalence,
packageCoordinatesOrder,
- parsePackageSpec,
type PackageIdentity,
-} from "#lib/core/packages.ts"
+} from "#lib/core/identity.ts"
+import { getPackageIdentitySegments, parsePackageSpec } from "#lib/core/packages.ts"
const runEffect = (effect: Effect.Effect) => Effect.runPromise(effect)
diff --git a/src/lib/core/errors.ts b/src/lib/core/errors.ts
index d6fe61e..badea59 100644
--- a/src/lib/core/errors.ts
+++ b/src/lib/core/errors.ts
@@ -1,5 +1,5 @@
import * as Data from "effect/Data"
-import type { PackageIdentity } from "#lib/core/packages.ts"
+import type { PackageIdentity } from "#lib/core/identity.ts"
import { SUPPORTED_REGISTRIES } from "#lib/core/registry.ts"
export class MissingPackageVersion extends Data.TaggedError("MissingPackageVersion")<{
diff --git a/src/lib/core/identity.ts b/src/lib/core/identity.ts
new file mode 100644
index 0000000..b55ce6b
--- /dev/null
+++ b/src/lib/core/identity.ts
@@ -0,0 +1,34 @@
+import * as Equivalence from "effect/Equivalence"
+import * as Order from "effect/Order"
+
+export interface PackageCoordinates {
+ readonly name: string
+ readonly registry: string
+}
+
+export interface PackageIdentity extends PackageCoordinates {
+ readonly version: string
+}
+
+export const packageCoordinatesEquivalence = Equivalence.Struct({
+ name: Equivalence.String,
+ registry: Equivalence.String,
+})
+
+export const packageCoordinatesOrder = Order.combineAll([
+ Order.mapInput(Order.String, (coordinates: PackageCoordinates) => coordinates.registry),
+ Order.mapInput(Order.String, (coordinates: PackageCoordinates) => coordinates.name),
+])
+
+export const packageIdentityEquivalence = Equivalence.combine(
+ packageCoordinatesEquivalence,
+ Equivalence.mapInput(Equivalence.String, (identity: PackageIdentity) => identity.version)
+)
+
+export const packageIdentityOrder = Order.combine(
+ packageCoordinatesOrder,
+ Order.mapInput(Order.String, (identity: PackageIdentity) => identity.version)
+)
+
+export const formatPackageIdentity = (identity: PackageIdentity) =>
+ `${identity.registry}:${identity.name}@${identity.version}`
diff --git a/src/lib/core/packages.ts b/src/lib/core/packages.ts
index 1aa4cb4..a600fe7 100644
--- a/src/lib/core/packages.ts
+++ b/src/lib/core/packages.ts
@@ -1,45 +1,18 @@
import type * as Types from "effect/Types"
import * as Effect from "effect/Effect"
-import * as Equivalence from "effect/Equivalence"
-import * as Order from "effect/Order"
+import type { PackageIdentity } from "#lib/core/identity.ts"
import {
InvalidPackageIdentity,
UnsupportedRegistryError,
UnsupportedRepositoryHostError,
} from "#lib/core/errors.ts"
import { DEFAULT_REGISTRY, checkIsRegistry, type Registry } from "#lib/core/registry.ts"
-
-export interface PackageCoordinates {
- readonly name: string
- readonly registry: string
-}
-
-export interface PackageIdentity extends PackageCoordinates {
- readonly version: string
-}
-
-export const packageCoordinatesEquivalence = Equivalence.Struct({
- name: Equivalence.String,
- registry: Equivalence.String,
-})
-
-export const packageCoordinatesOrder = Order.combineAll([
- Order.mapInput(Order.String, (coordinates: PackageCoordinates) => coordinates.registry),
- Order.mapInput(Order.String, (coordinates: PackageCoordinates) => coordinates.name),
-])
-
-export const packageIdentityEquivalence = Equivalence.combine(
- packageCoordinatesEquivalence,
- Equivalence.mapInput(Equivalence.String, (identity: PackageIdentity) => identity.version)
-)
-
-export const packageIdentityOrder = Order.combine(
- packageCoordinatesOrder,
- Order.mapInput(Order.String, (identity: PackageIdentity) => identity.version)
-)
-
-export const formatPackageIdentity = (identity: PackageIdentity) =>
- `${identity.registry}:${identity.name}@${identity.version}`
+import {
+ HOST_REPOSITORY_PROVIDERS,
+ checkIsRepositoryProvider,
+ REPOSITORY_PROVIDER_HOSTS,
+ type RepositoryProvider,
+} from "#lib/core/repository.ts"
export interface RegistryPackageSpec {
readonly _tag: "registry"
@@ -48,14 +21,6 @@ export interface RegistryPackageSpec {
readonly specifier?: string
}
-export const SUPPORTED_REPOSITORY_PROVIDERS = [
- "bitbucket",
- "github",
- "gitlab",
- "sourcehut",
-] as const
-export type RepositoryProvider = (typeof SUPPORTED_REPOSITORY_PROVIDERS)[number]
-
export interface RepositoryPackageSpec {
readonly _tag: "repository"
readonly name: string
@@ -108,20 +73,6 @@ const validatePathSegment = Effect.fn("validatePathSegment")(function* (
}
})
-export const REPOSITORY_PROVIDER_HOSTS = {
- bitbucket: "bitbucket.org",
- github: "github.com",
- gitlab: "gitlab.com",
- sourcehut: "git.sr.ht",
-} satisfies Record
-
-const HOST_REPOSITORY_PROVIDERS = new Map(
- SUPPORTED_REPOSITORY_PROVIDERS.map((provider) => [REPOSITORY_PROVIDER_HOSTS[provider], provider])
-)
-
-const checkIsRepositoryProvider = (value: string): value is RepositoryProvider =>
- SUPPORTED_REPOSITORY_PROVIDERS.some((provider) => provider === value)
-
const splitRepositoryRef = (value: string) => {
const schemeIndex = value.indexOf("://")
const scpPathIndex = schemeIndex === -1 ? value.indexOf(":") : -1
diff --git a/src/lib/core/repository.ts b/src/lib/core/repository.ts
new file mode 100644
index 0000000..d852b82
--- /dev/null
+++ b/src/lib/core/repository.ts
@@ -0,0 +1,21 @@
+export const SUPPORTED_REPOSITORY_PROVIDERS = [
+ "bitbucket",
+ "github",
+ "gitlab",
+ "sourcehut",
+] as const
+export type RepositoryProvider = (typeof SUPPORTED_REPOSITORY_PROVIDERS)[number]
+
+export const REPOSITORY_PROVIDER_HOSTS = {
+ bitbucket: "bitbucket.org",
+ github: "github.com",
+ gitlab: "gitlab.com",
+ sourcehut: "git.sr.ht",
+} satisfies Record
+
+export const HOST_REPOSITORY_PROVIDERS = new Map(
+ SUPPORTED_REPOSITORY_PROVIDERS.map((provider) => [REPOSITORY_PROVIDER_HOSTS[provider], provider])
+)
+
+export const checkIsRepositoryProvider = (value: string): value is RepositoryProvider =>
+ SUPPORTED_REPOSITORY_PROVIDERS.some((provider) => provider === value)
diff --git a/src/lib/workspace/home.ts b/src/lib/layout/home.ts
similarity index 100%
rename from src/lib/workspace/home.ts
rename to src/lib/layout/home.ts
diff --git a/src/lib/workspace/paths.ts b/src/lib/layout/paths.ts
similarity index 61%
rename from src/lib/workspace/paths.ts
rename to src/lib/layout/paths.ts
index 8d39671..9c64e90 100644
--- a/src/lib/workspace/paths.ts
+++ b/src/lib/layout/paths.ts
@@ -1,4 +1,7 @@
-import type * as Path from "effect/Path"
+import * as Effect from "effect/Effect"
+import * as Path from "effect/Path"
+import type { PackageIdentity } from "#lib/core/identity.ts"
+import { getPackageIdentitySegments } from "#lib/core/packages.ts"
export const PACKREF_DIRECTORY_NAME = ".packref"
export const LOCKFILE_NAME = "packref-lock.json"
@@ -16,3 +19,13 @@ export const getGlobalDirectoryPath = (path: Path.Path, home: string) =>
export const getGlobalConfigPath = (path: Path.Path, home: string) =>
path.join(getGlobalDirectoryPath(path, home), GLOBAL_CONFIG_NAME)
+
+export const getPackageIdentityPath = Effect.fn("getPackageIdentityPath")(function* (
+ root: string,
+ identity: PackageIdentity
+) {
+ const path = yield* Path.Path
+ const segments = yield* getPackageIdentitySegments(identity)
+
+ return path.join(root, ...segments)
+})
diff --git a/src/lib/references/__tests__/add.test.ts b/src/lib/references/__tests__/add.test.ts
index 5a073ed..92e1b7d 100644
--- a/src/lib/references/__tests__/add.test.ts
+++ b/src/lib/references/__tests__/add.test.ts
@@ -15,6 +15,7 @@ import type { NpmPackageMetadata } from "#lib/registries/npm/metadata.ts"
import type { PackageEntry } from "#lib/workspace/lockfile.ts"
import { NetworkError, ReflinkError, SnapshotFetchError } from "#lib/core/errors.ts"
import { parsePackageSpec } from "#lib/core/packages.ts"
+import { PackrefHome } from "#lib/layout/home.ts"
import { ProjectDependencyReader } from "#lib/manifests/index.ts"
import { PackageManagerResolver } from "#lib/manifests/javascript.ts"
import {
@@ -26,7 +27,6 @@ import {
import { NpmRegistryClient } from "#lib/registries/npm/client.ts"
import { RepositoryDownloader } from "#lib/sources/repository/fetch.ts"
import { RemoteTagReader } from "#lib/sources/repository/tags.ts"
-import { PackrefHome } from "#lib/workspace/home.ts"
import { Reflinker } from "#lib/workspace/reflinker.ts"
const temporaryPaths: string[] = []
diff --git a/src/lib/references/__tests__/install.test.ts b/src/lib/references/__tests__/install.test.ts
index 7ef071b..03f1c99 100644
--- a/src/lib/references/__tests__/install.test.ts
+++ b/src/lib/references/__tests__/install.test.ts
@@ -17,10 +17,10 @@ import {
StoreSourceMismatchError,
TarballFetchError,
} from "#lib/core/errors.ts"
+import { PackrefHome } from "#lib/layout/home.ts"
import { installPackageReferences } from "#lib/references/install.ts"
import { RepositoryDownloader } from "#lib/sources/repository/fetch.ts"
import { RemoteTagReader } from "#lib/sources/repository/tags.ts"
-import { PackrefHome } from "#lib/workspace/home.ts"
import { Reflinker } from "#lib/workspace/reflinker.ts"
type TestRepositorySource = Types.Mutable
diff --git a/src/lib/references/__tests__/prune.test.ts b/src/lib/references/__tests__/prune.test.ts
index 61df61e..2cf6e56 100644
--- a/src/lib/references/__tests__/prune.test.ts
+++ b/src/lib/references/__tests__/prune.test.ts
@@ -7,11 +7,11 @@ import * as NodeServices from "@effect/platform-node/NodeServices"
import * as Effect from "effect/Effect"
import * as Layer from "effect/Layer"
import { afterEach, describe, expect, it } from "vitest"
-import type { PackageIdentity } from "#lib/core/packages.ts"
+import type { PackageIdentity } from "#lib/core/identity.ts"
import { initializeProject, repositoryEntry } from "#commands/__tests__/helpers.ts"
+import { PackrefHome } from "#lib/layout/home.ts"
import { applyPrunePlan, discoverPrunePlan } from "#lib/references/prune.ts"
import { getStoreEntryPath } from "#lib/store/index.ts"
-import { PackrefHome } from "#lib/workspace/home.ts"
const temporaryPaths: string[] = []
diff --git a/src/lib/references/__tests__/sync.test.ts b/src/lib/references/__tests__/sync.test.ts
index 74d19ba..cbca28c 100644
--- a/src/lib/references/__tests__/sync.test.ts
+++ b/src/lib/references/__tests__/sync.test.ts
@@ -15,13 +15,13 @@ import {
TarballFetchError,
UnsupportedManifestError,
} from "#lib/core/errors.ts"
+import { PackrefHome } from "#lib/layout/home.ts"
import { ProjectDependencyReader } from "#lib/manifests/index.ts"
import { PackageManagerResolver } from "#lib/manifests/javascript.ts"
import { preparePackageReferenceSync, syncPackageReferences } from "#lib/references/sync.ts"
import { NpmRegistryClient } from "#lib/registries/npm/client.ts"
import { RepositoryDownloader } from "#lib/sources/repository/fetch.ts"
import { RemoteTagReader } from "#lib/sources/repository/tags.ts"
-import { PackrefHome } from "#lib/workspace/home.ts"
import { Reflinker } from "#lib/workspace/reflinker.ts"
const temporaryPaths: string[] = []
diff --git a/src/lib/references/add.ts b/src/lib/references/add.ts
index 761f131..bbe2faa 100644
--- a/src/lib/references/add.ts
+++ b/src/lib/references/add.ts
@@ -5,6 +5,7 @@ import * as Option from "effect/Option"
import * as Order from "effect/Order"
import * as Path from "effect/Path"
import * as Predicate from "effect/Predicate"
+import type { ParsedPackageSpec, RepositoryPackageSpec } from "#lib/core/packages.ts"
import type { RepositorySource } from "#lib/core/source.ts"
import type { ManifestDependency } from "#lib/manifests/manifest.ts"
import type { ResolvedPackageReference } from "#lib/registries/registry.ts"
@@ -16,11 +17,9 @@ import {
} from "#lib/core/errors.ts"
import {
packageCoordinatesEquivalence,
- packageIdentityEquivalence,
type PackageIdentity,
- type ParsedPackageSpec,
- type RepositoryPackageSpec,
-} from "#lib/core/packages.ts"
+ packageIdentityEquivalence,
+} from "#lib/core/identity.ts"
import { ProjectDependencyReader } from "#lib/manifests/index.ts"
import { resolvePackageReference } from "#lib/registries/index.ts"
import { fetchRepositorySnapshot } from "#lib/sources/repository/fetch.ts"
diff --git a/src/lib/references/clean.ts b/src/lib/references/clean.ts
index 0163cc2..0413ff9 100644
--- a/src/lib/references/clean.ts
+++ b/src/lib/references/clean.ts
@@ -2,8 +2,8 @@ import * as Effect from "effect/Effect"
import * as FileSystem from "effect/FileSystem"
import * as Path from "effect/Path"
import { PACKAGE_DIRECTORY_NAME } from "#lib/core/packages.ts"
+import { getDirectoryPath, getProjectLockfilePath } from "#lib/layout/paths.ts"
import { emptyLockfile, readProjectLockfile, writeLockfileAtPath } from "#lib/workspace/lockfile.ts"
-import { getDirectoryPath, getProjectLockfilePath } from "#lib/workspace/paths.ts"
import { requireInitializedProject } from "#lib/workspace/project.ts"
export interface ProjectCleanPlan {
diff --git a/src/lib/references/install.ts b/src/lib/references/install.ts
index 6db27d8..a50ed7c 100644
--- a/src/lib/references/install.ts
+++ b/src/lib/references/install.ts
@@ -6,7 +6,7 @@ import {
StoreSourceMismatchError,
UnsupportedRepositoryHostError,
} from "#lib/core/errors.ts"
-import { SUPPORTED_REPOSITORY_PROVIDERS } from "#lib/core/packages.ts"
+import { checkIsRepositoryProvider } from "#lib/core/repository.ts"
import { packageSourceEquivalence } from "#lib/core/source.ts"
import { fetchRepositorySnapshot } from "#lib/sources/repository/fetch.ts"
import {
@@ -69,9 +69,7 @@ const fetchLockedStoreEntry = Effect.fn("fetchLockedStoreEntry")(function* (entr
return yield* ensureMatchingSource(entry, materialized)
}
- const isDirectRepository = SUPPORTED_REPOSITORY_PROVIDERS.some(
- (provider) => provider === entry.registry
- )
+ const isDirectRepository = checkIsRepositoryProvider(entry.registry)
const resolvedRepository = isDirectRepository
? yield* Effect.gen(function* () {
const source = yield* normalizeRepositorySource(entry.source)
diff --git a/src/lib/references/prune.ts b/src/lib/references/prune.ts
index 0eac9d3..b7eb060 100644
--- a/src/lib/references/prune.ts
+++ b/src/lib/references/prune.ts
@@ -3,7 +3,7 @@ import * as FileSystem from "effect/FileSystem"
import * as Filter from "effect/Filter"
import * as Order from "effect/Order"
import { ProjectFilesystemError } from "#lib/core/errors.ts"
-import { packageIdentityOrder, type PackageIdentity } from "#lib/core/packages.ts"
+import { type PackageIdentity, packageIdentityOrder } from "#lib/core/identity.ts"
import { listStoreEntries, removeStoreEntry, type StoreEntry } from "#lib/store/index.ts"
import { initializeGlobalConfig, unregisterProjects } from "#lib/workspace/config.ts"
import { readProjectLockfile } from "#lib/workspace/lockfile.ts"
diff --git a/src/lib/references/remove.ts b/src/lib/references/remove.ts
index dd66da8..87ed490 100644
--- a/src/lib/references/remove.ts
+++ b/src/lib/references/remove.ts
@@ -2,7 +2,6 @@ import type * as Types from "effect/Types"
import * as Array from "effect/Array"
import * as Effect from "effect/Effect"
import * as FileSystem from "effect/FileSystem"
-import * as Path from "effect/Path"
import * as Result from "effect/Result"
import type { ParsedPackageSpec } from "#lib/core/packages.ts"
import {
@@ -10,7 +9,6 @@ import {
PackageReferenceFilesystemError,
RemovePackageReferencesError,
} from "#lib/core/errors.ts"
-import { getStorePackagePath } from "#lib/store/paths.ts"
import {
findPackageEntries,
listPackageEntries,
@@ -18,8 +16,7 @@ import {
removePackageEntries,
type PackageEntry,
} from "#lib/workspace/lockfile.ts"
-import { getDirectoryPath } from "#lib/workspace/paths.ts"
-import { requireInitializedProject } from "#lib/workspace/project.ts"
+import { getProjectReferencePath, requireInitializedProject } from "#lib/workspace/project.ts"
const REMOVE_CONCURRENCY = 8
@@ -79,13 +76,11 @@ export const removePackageReferences = Effect.fn("removePackageReferences")(func
entries: readonly PackageEntry[]
) {
const fs = yield* FileSystem.FileSystem
- const path = yield* Path.Path
- const projectDirectoryPath = getDirectoryPath(path, projectPath)
const attempts = yield* Effect.forEach(
entries,
(entry) =>
Effect.gen(function* () {
- const referencePath = yield* getStorePackagePath(projectDirectoryPath, entry)
+ const referencePath = yield* getProjectReferencePath(projectPath, entry)
const referenceExists = yield* fs.exists(referencePath).pipe(
Effect.mapError(
(cause) =>
diff --git a/src/lib/references/sync.ts b/src/lib/references/sync.ts
index e24b667..c65c6e5 100644
--- a/src/lib/references/sync.ts
+++ b/src/lib/references/sync.ts
@@ -2,16 +2,15 @@ import * as Array from "effect/Array"
import * as Effect from "effect/Effect"
import * as FileSystem from "effect/FileSystem"
import * as Option from "effect/Option"
-import * as Path from "effect/Path"
import * as Result from "effect/Result"
import type { ManifestDependency } from "#lib/manifests/manifest.ts"
import { PackageReferenceFilesystemError, UnsupportedManifestError } from "#lib/core/errors.ts"
import {
+ type PackageCoordinates,
packageCoordinatesEquivalence,
packageCoordinatesOrder,
packageIdentityEquivalence,
- type PackageCoordinates,
-} from "#lib/core/packages.ts"
+} from "#lib/core/identity.ts"
import { ProjectDependencyReader } from "#lib/manifests/index.ts"
import {
materializePackageCandidateReference,
@@ -19,15 +18,13 @@ import {
type ResolvedPackageCandidateReference,
} from "#lib/references/add.ts"
import { removePackageReferences } from "#lib/references/remove.ts"
-import { getStorePackagePath } from "#lib/store/paths.ts"
import { registerProject } from "#lib/workspace/config.ts"
import {
listPackageEntries,
readProjectLockfile,
type PackageEntry,
} from "#lib/workspace/lockfile.ts"
-import { getDirectoryPath } from "#lib/workspace/paths.ts"
-import { requireInitializedProject } from "#lib/workspace/project.ts"
+import { getProjectReferencePath, requireInitializedProject } from "#lib/workspace/project.ts"
export interface SyncPackageReferencesOptions {
readonly projectPath?: string
@@ -80,9 +77,7 @@ const packageReferenceExists = Effect.fn("sync.packageReferenceExists")(function
entry: PackageEntry
) {
const fs = yield* FileSystem.FileSystem
- const path = yield* Path.Path
- const projectDirectoryPath = getDirectoryPath(path, projectPath)
- const referencePath = yield* getStorePackagePath(projectDirectoryPath, entry)
+ const referencePath = yield* getProjectReferencePath(projectPath, entry)
return yield* fs.exists(referencePath).pipe(
Effect.mapError(
diff --git a/src/lib/registries/registry.ts b/src/lib/registries/registry.ts
index 399e3c4..b7a3d76 100644
--- a/src/lib/registries/registry.ts
+++ b/src/lib/registries/registry.ts
@@ -1,5 +1,6 @@
import type * as Effect from "effect/Effect"
-import type { PackageIdentity, RegistryPackageSpec } from "#lib/core/packages.ts"
+import type { PackageIdentity } from "#lib/core/identity.ts"
+import type { RegistryPackageSpec } from "#lib/core/packages.ts"
import type { Registry } from "#lib/core/registry.ts"
import type { RepositorySourceCandidate } from "#lib/core/source.ts"
diff --git a/src/lib/sources/repository/__tests__/fetch.test.ts b/src/lib/sources/repository/__tests__/fetch.test.ts
index 52a6e32..f526740 100644
--- a/src/lib/sources/repository/__tests__/fetch.test.ts
+++ b/src/lib/sources/repository/__tests__/fetch.test.ts
@@ -8,8 +8,8 @@ import * as Effect from "effect/Effect"
import * as Layer from "effect/Layer"
import { afterEach, describe, expect, it } from "vitest"
import { SnapshotFetchError } from "#lib/core/errors.ts"
+import { PackrefHome } from "#lib/layout/home.ts"
import { fetchRepositorySnapshot, RepositoryDownloader } from "#lib/sources/repository/fetch.ts"
-import { PackrefHome } from "#lib/workspace/home.ts"
const temporaryPaths: string[] = []
diff --git a/src/lib/sources/repository/__tests__/tags.test.ts b/src/lib/sources/repository/__tests__/tags.test.ts
index ef36c6b..c68d5e5 100644
--- a/src/lib/sources/repository/__tests__/tags.test.ts
+++ b/src/lib/sources/repository/__tests__/tags.test.ts
@@ -8,7 +8,8 @@ import * as Layer from "effect/Layer"
import * as Option from "effect/Option"
import * as PlatformError from "effect/PlatformError"
import { afterEach, describe, expect, it } from "vitest"
-import type { PackageIdentity, RepositoryPackageSpec } from "#lib/core/packages.ts"
+import type { PackageIdentity } from "#lib/core/identity.ts"
+import type { RepositoryPackageSpec } from "#lib/core/packages.ts"
import type { NormalizedRepositorySource } from "#lib/core/source.ts"
import {
GitExecutableNotFoundError,
diff --git a/src/lib/sources/repository/fetch.ts b/src/lib/sources/repository/fetch.ts
index b8e1808..cda5d12 100644
--- a/src/lib/sources/repository/fetch.ts
+++ b/src/lib/sources/repository/fetch.ts
@@ -3,7 +3,7 @@ import * as Context from "effect/Context"
import * as Effect from "effect/Effect"
import * as Layer from "effect/Layer"
import { downloadTemplate } from "giget"
-import type { PackageIdentity } from "#lib/core/packages.ts"
+import type { PackageIdentity } from "#lib/core/identity.ts"
import type { RepositorySource, ResolvedRepositoryRef } from "#lib/core/source.ts"
import { SnapshotFetchError } from "#lib/core/errors.ts"
import { materializeStoreEntry } from "#lib/store/index.ts"
diff --git a/src/lib/sources/repository/normalize.ts b/src/lib/sources/repository/normalize.ts
index c790675..1b6e768 100644
--- a/src/lib/sources/repository/normalize.ts
+++ b/src/lib/sources/repository/normalize.ts
@@ -2,6 +2,8 @@ import type * as Types from "effect/Types"
import * as Effect from "effect/Effect"
import * as Match from "effect/Match"
import * as Option from "effect/Option"
+import type { PackageIdentity } from "#lib/core/identity.ts"
+import type { RepositoryPackageSpec } from "#lib/core/packages.ts"
import type {
NormalizedRepositorySource,
RepositorySourceCandidate,
@@ -13,29 +15,22 @@ import {
UnsupportedRepositoryHostError,
} from "#lib/core/errors.ts"
import {
+ checkIsRepositoryProvider,
+ HOST_REPOSITORY_PROVIDERS,
REPOSITORY_PROVIDER_HOSTS,
SUPPORTED_REPOSITORY_PROVIDERS,
- type PackageIdentity,
- type RepositoryPackageSpec,
type RepositoryProvider,
-} from "#lib/core/packages.ts"
+} from "#lib/core/repository.ts"
import { matchRepositoryTag, RemoteTagReader } from "#lib/sources/repository/tags.ts"
const COMMIT_SHA_PATTERN = /^[0-9a-f]{40}$/iu
-const HOST_PROVIDERS = new Map(
- SUPPORTED_REPOSITORY_PROVIDERS.map((provider) => [REPOSITORY_PROVIDER_HOSTS[provider], provider])
-)
-
const DEFAULT_SHORTHAND_PROVIDER = "github" satisfies RepositoryProvider
const SHORTHAND_PATTERN = new RegExp(
`^(?${SUPPORTED_REPOSITORY_PROVIDERS.join("|")}):(?.+)$`,
"u"
)
-const checkIsKnownProvider = (value: string): value is RepositoryProvider =>
- SUPPORTED_REPOSITORY_PROVIDERS.some((provider) => provider === value)
-
const cleanRepositoryPath = (repositoryPath: string) =>
repositoryPath
.replace(/\/+$/u, "")
@@ -56,7 +51,7 @@ const makeNormalizedSource = (
return Effect.fail(invalidRepositoryUrl(candidate, "repository path must not be empty"))
}
- const provider = HOST_PROVIDERS.get(host)
+ const provider = HOST_REPOSITORY_PROVIDERS.get(host)
const fetchRepositoryPath =
provider === "sourcehut" ? repositoryPath.replace(/^~/u, "") : repositoryPath
@@ -130,7 +125,11 @@ export const normalizeRepositorySource = Effect.fn("normalizeRepositorySource")(
const provider = Option.getOrUndefined(shorthandGroups)?.provider
const shorthandPath = Option.getOrUndefined(shorthandGroups)?.repositoryPath
- if (provider !== undefined && shorthandPath !== undefined && checkIsKnownProvider(provider)) {
+ if (
+ provider !== undefined
+ && shorthandPath !== undefined
+ && checkIsRepositoryProvider(provider)
+ ) {
return normalizeFromShorthandUrl(candidate, provider, shorthandPath)
}
diff --git a/src/lib/sources/repository/tags.ts b/src/lib/sources/repository/tags.ts
index 57d0baa..4fa632b 100644
--- a/src/lib/sources/repository/tags.ts
+++ b/src/lib/sources/repository/tags.ts
@@ -12,7 +12,7 @@ import { ChildProcessSpawner } from "effect/process/ChildProcessSpawner"
import * as Result from "effect/Result"
import * as Schedule from "effect/Schedule"
import * as Stream from "effect/Stream"
-import type { PackageIdentity } from "#lib/core/packages.ts"
+import type { PackageIdentity } from "#lib/core/identity.ts"
import type { NormalizedRepositorySource } from "#lib/core/source.ts"
import { GitExecutableNotFoundError, NetworkError } from "#lib/core/errors.ts"
diff --git a/src/lib/sources/tarball/__tests__/fetch.test.ts b/src/lib/sources/tarball/__tests__/fetch.test.ts
index 3a313f8..d7e2ad2 100644
--- a/src/lib/sources/tarball/__tests__/fetch.test.ts
+++ b/src/lib/sources/tarball/__tests__/fetch.test.ts
@@ -11,8 +11,8 @@ import * as Layer from "effect/Layer"
import { createTarGzip } from "nanotar"
import { afterEach, describe, expect, it } from "vitest"
import { TarballFetchError } from "#lib/core/errors.ts"
+import { PackrefHome } from "#lib/layout/home.ts"
import { fetchTarballSnapshot } from "#lib/sources/tarball/fetch.ts"
-import { PackrefHome } from "#lib/workspace/home.ts"
const temporaryPaths: string[] = []
diff --git a/src/lib/sources/tarball/fetch.ts b/src/lib/sources/tarball/fetch.ts
index 8c6ab50..f9d6668 100644
--- a/src/lib/sources/tarball/fetch.ts
+++ b/src/lib/sources/tarball/fetch.ts
@@ -4,7 +4,7 @@ import * as HttpClient from "effect/http/HttpClient"
import * as HttpClientResponse from "effect/http/HttpClientResponse"
import * as Path from "effect/Path"
import { parseTarGzip, type ParsedTarFileItem } from "nanotar"
-import type { PackageIdentity } from "#lib/core/packages.ts"
+import type { PackageIdentity } from "#lib/core/identity.ts"
import type { TarballSource } from "#lib/core/source.ts"
import { TarballFetchError } from "#lib/core/errors.ts"
import { checkIsPathWithin } from "#lib/shared/path.ts"
diff --git a/src/lib/store/__tests__/store.test.ts b/src/lib/store/__tests__/store.test.ts
index eced956..2d58a17 100644
--- a/src/lib/store/__tests__/store.test.ts
+++ b/src/lib/store/__tests__/store.test.ts
@@ -7,13 +7,13 @@ import * as NodeServices from "@effect/platform-node/NodeServices"
import * as Effect from "effect/Effect"
import * as Layer from "effect/Layer"
import { afterEach, describe, expect, it } from "vitest"
+import { PackrefHome } from "#lib/layout/home.ts"
import {
getStoreEntryPath,
hasStoreEntry,
listStoreEntries,
removeStoreEntry,
} from "#lib/store/index.ts"
-import { PackrefHome } from "#lib/workspace/home.ts"
const temporaryPaths: string[] = []
diff --git a/src/lib/store/index.ts b/src/lib/store/index.ts
index 581ee49..cdf4297 100644
--- a/src/lib/store/index.ts
+++ b/src/lib/store/index.ts
@@ -8,19 +8,16 @@ import * as Schema from "effect/Schema"
import * as Semaphore from "effect/Semaphore"
import type { PackageSource } from "#lib/core/source.ts"
import { GlobalStoreFilesystemError, StoreCorruptedError } from "#lib/core/errors.ts"
-import {
- packageIdentityOrder,
- PACKAGE_DIRECTORY_NAME,
- SUPPORTED_REPOSITORY_PROVIDERS,
- type PackageIdentity,
-} from "#lib/core/packages.ts"
+import { type PackageIdentity, packageIdentityOrder } from "#lib/core/identity.ts"
+import { PACKAGE_DIRECTORY_NAME } from "#lib/core/packages.ts"
+import { checkIsRepositoryProvider } from "#lib/core/repository.ts"
import { PackageSourceSchema } from "#lib/core/source.ts"
+import { PackrefHome } from "#lib/layout/home.ts"
import { formatJson } from "#lib/shared/json.ts"
import {
getGlobalStorePath,
getStoreEntryPaths as getPathsForStoreEntry,
} from "#lib/store/paths.ts"
-import { PackrefHome } from "#lib/workspace/home.ts"
export interface StoreEntry {
readonly identity: PackageIdentity
@@ -121,8 +118,7 @@ export const listStoreEntries = Effect.fn("listStoreEntries")(function* () {
const packageSegmentPath = path.join(registryPath, packageSegment)
const hasNestedPackageName =
- packageSegment.startsWith("@")
- || SUPPORTED_REPOSITORY_PROVIDERS.some((provider) => provider === registry)
+ packageSegment.startsWith("@") || checkIsRepositoryProvider(registry)
if (hasNestedPackageName) {
const scopedPackages = yield* listDirectoryOrEmpty(packageSegmentPath, semaphore)
diff --git a/src/lib/store/paths.ts b/src/lib/store/paths.ts
index 111b215..ee01043 100644
--- a/src/lib/store/paths.ts
+++ b/src/lib/store/paths.ts
@@ -1,7 +1,8 @@
import * as Effect from "effect/Effect"
import * as Path from "effect/Path"
-import { getPackageIdentitySegments, type PackageIdentity } from "#lib/core/packages.ts"
-import { getGlobalDirectoryPath } from "#lib/workspace/paths.ts"
+import type { PackageIdentity } from "#lib/core/identity.ts"
+import { getPackageIdentitySegments } from "#lib/core/packages.ts"
+import { getGlobalDirectoryPath } from "#lib/layout/paths.ts"
export const STORE_DIRECTORY_NAME = "store"
export const STORE_METADATA_DIRECTORY_NAME = ".metadata"
@@ -9,16 +10,6 @@ export const STORE_METADATA_DIRECTORY_NAME = ".metadata"
export const getGlobalStorePath = (path: Path.Path, home: string) =>
path.join(getGlobalDirectoryPath(path, home), STORE_DIRECTORY_NAME)
-export const getStorePackagePath = Effect.fn("getStorePackagePath")(function* (
- storeRoot: string,
- identity: PackageIdentity
-) {
- const path = yield* Path.Path
- const segments = yield* getPackageIdentitySegments(identity)
-
- return path.join(storeRoot, ...segments)
-})
-
export const getStoreEntryPaths = Effect.fn("getStoreEntryPaths")(function* (
storeRoot: string,
identity: PackageIdentity
diff --git a/src/lib/workspace/config.ts b/src/lib/workspace/config.ts
index 7603830..2454d79 100644
--- a/src/lib/workspace/config.ts
+++ b/src/lib/workspace/config.ts
@@ -4,9 +4,9 @@ import * as Filter from "effect/Filter"
import * as Path from "effect/Path"
import * as Schema from "effect/Schema"
import { ConfigParseError } from "#lib/core/errors.ts"
+import { PackrefHome } from "#lib/layout/home.ts"
+import { getGlobalConfigPath, getGlobalDirectoryPath } from "#lib/layout/paths.ts"
import { formatJson } from "#lib/shared/json.ts"
-import { PackrefHome } from "#lib/workspace/home.ts"
-import { getGlobalConfigPath, getGlobalDirectoryPath } from "#lib/workspace/paths.ts"
export const GlobalConfigSchema = Schema.Struct({
projects: Schema.Array(Schema.String),
diff --git a/src/lib/workspace/lockfile.ts b/src/lib/workspace/lockfile.ts
index 68a4a0e..8cb44d4 100644
--- a/src/lib/workspace/lockfile.ts
+++ b/src/lib/workspace/lockfile.ts
@@ -4,16 +4,16 @@ import * as FileSystem from "effect/FileSystem"
import * as Filter from "effect/Filter"
import * as Path from "effect/Path"
import * as Schema from "effect/Schema"
+import type { ParsedPackageSpec } from "#lib/core/packages.ts"
import { LockfileParseError } from "#lib/core/errors.ts"
import {
+ type PackageIdentity,
packageIdentityEquivalence,
packageIdentityOrder,
- type PackageIdentity,
- type ParsedPackageSpec,
-} from "#lib/core/packages.ts"
+} from "#lib/core/identity.ts"
import { PackageSourceSchema } from "#lib/core/source.ts"
+import { getProjectLockfilePath } from "#lib/layout/paths.ts"
import { formatJson } from "#lib/shared/json.ts"
-import { getProjectLockfilePath } from "#lib/workspace/paths.ts"
export const PackageEntrySchema = Schema.Struct({
name: Schema.String,
diff --git a/src/lib/workspace/project.ts b/src/lib/workspace/project.ts
index a3df2a7..643d9b5 100644
--- a/src/lib/workspace/project.ts
+++ b/src/lib/workspace/project.ts
@@ -1,12 +1,11 @@
import * as Effect from "effect/Effect"
import * as FileSystem from "effect/FileSystem"
import * as Path from "effect/Path"
-import type { PackageIdentity } from "#lib/core/packages.ts"
+import type { PackageIdentity } from "#lib/core/identity.ts"
import type { PackageSource } from "#lib/core/source.ts"
import { NotInitializedError, ReflinkError } from "#lib/core/errors.ts"
+import { getDirectoryPath, getPackageIdentityPath } from "#lib/layout/paths.ts"
import { checkIsPathWithin } from "#lib/shared/path.ts"
-import { getStorePackagePath } from "#lib/store/paths.ts"
-import { getDirectoryPath } from "#lib/workspace/paths.ts"
import { Reflinker } from "#lib/workspace/reflinker.ts"
export const ensureDirectory = Effect.fn("ensureDirectory")(function* (projectPath: string) {
@@ -43,7 +42,7 @@ export const getProjectReferencePath = Effect.fn("getProjectReferencePath")(func
) {
const path = yield* Path.Path
- return yield* getStorePackagePath(getDirectoryPath(path, projectPath), identity)
+ return yield* getPackageIdentityPath(getDirectoryPath(path, projectPath), identity)
})
export const hasProjectReference = Effect.fn("hasProjectReference")(function* (
@@ -66,7 +65,7 @@ export const createProjectReference = Effect.fn("createProjectReference")(functi
const path = yield* Path.Path
const reflinker = yield* Reflinker
const projectDirectoryPath = getDirectoryPath(path, projectPath)
- const targetPath = yield* getStorePackagePath(projectDirectoryPath, identity)
+ const targetPath = yield* getPackageIdentityPath(projectDirectoryPath, identity)
const referenceSourcePath =
source.type === "repository" && source.directory !== undefined
? path.resolve(storePath, source.directory)