Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions components/modules/component-package-name/index.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
export { componentIdToPackageName } from './component-id-to-package-name';
export { getNodeModulesPathOfComponent } from './component-node-modules-path';
export { resolveComponentIdFromPackageName, isLikelyPackageName } from './package-name-to-component-id';
export type { PackageManifestFetcher } from './package-name-to-component-id';
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@ import type { ComponentIdObj } from '@teambit/component-id';
import { ComponentID } from '@teambit/component-id';
import { BitError } from '@teambit/bit-error';

export type PackageManifestFetcher = { fetchFullPackageManifest: (packageName: string) => Promise<any> };

/**
* Utility function to check if a string looks like a package name vs component ID
* @param id - The string to check
Expand All @@ -23,7 +25,7 @@ export function isLikelyPackageName(id: string): boolean {
*/
export async function resolveComponentIdFromPackageName(
packageName: string,
dependencyResolver: { fetchFullPackageManifest: (name: string) => Promise<any> }
dependencyResolver: PackageManifestFetcher
): Promise<ComponentID> {
if (!packageName.startsWith('@')) {
throw new BitError(
Expand Down
51 changes: 51 additions & 0 deletions scopes/component/component/aspect-definition.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
import type { Component } from './component';

export type AspectDefinitionProps = {
id?: string;
component?: Component;
aspectPath: string;
runtimePath: string | null;
aspectFilePath: string | null;
local?: boolean;
};

export class AspectDefinition {
constructor(
/**
* path to the root directory of the aspect module.
*/
readonly aspectPath: string,

/**
* path to the aspect file (.aspect).
*/
readonly aspectFilePath: string | null,

/**
* path to the runtime entry
*/
readonly runtimePath: string | null,
/**
* aspect component
*/
readonly component?: Component,
/**
* id of the component (used instead of component in the case of core aspect)
*/
readonly id?: string,
/**
* aspect defined using 'file://' protocol
*/
readonly local?: boolean
) {}

get getId() {
if (this.component) return this.component.id.toString();
if (this.id) return this.id;
return null;
}

static from({ component, aspectPath, aspectFilePath, runtimePath, id, local }: AspectDefinitionProps) {
return new AspectDefinition(aspectPath, aspectFilePath, runtimePath, component, id, local);
}
}
33 changes: 33 additions & 0 deletions scopes/component/component/component-dependencies.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
/**
* a dependency of a component, as the dependency-resolver resolves it (its `Dependency`).
* defined here so the component aspect doesn't depend on the dependency-resolver aspect.
*/
export type ComponentDependencyEntry = {
id: string;
version: string;
type: string;
lifecycle: string;
source?: string;
hidden?: boolean;
optional?: boolean;
getPackageName?: () => string;
};

export type ComponentDependenciesManifest = {
dependencies: Record<string, string>;
optionalDependencies: Record<string, string>;
devDependencies: Record<string, string>;
peerDependencies: Record<string, string>;
Comment thread
davidfirst marked this conversation as resolved.
peerDependenciesMeta?: Record<string, { optional: true }>;
};

/**
* the dependencies of a component, as the dependency-resolver resolves them (its `DependencyList`).
* defined here so the component aspect doesn't depend on the dependency-resolver aspect.
*/
export interface ComponentDependencyList {
readonly dependencies: ComponentDependencyEntry[];
forEach(predicate: (dep: ComponentDependencyEntry, index?: number) => void): void;
map(predicate: (dep: ComponentDependencyEntry, index?: number) => any): any[];
toDependenciesManifest(): ComponentDependenciesManifest;
}
6 changes: 3 additions & 3 deletions scopes/component/component/component-factory.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@ import type { BitId } from '@teambit/legacy-bit-id';
import type { ComponentID } from '@teambit/component-id';
import type { ConsumerComponent } from '@teambit/legacy.consumer-component';
import type { ComponentLog } from '@teambit/objects';
import type { AspectDefinition } from '@teambit/aspect-loader';
import type { DependencyList } from '@teambit/dependency-resolver';
import type { AspectDefinition } from './aspect-definition';
import type { ComponentDependencyList } from './component-dependencies';
import type { Component, InvalidComponent } from './component';
import type { State } from './state';
import type { Snap } from './snap';
Expand Down Expand Up @@ -145,7 +145,7 @@ export interface ComponentFactory {

getLogs(id: ComponentID, shortHash?: boolean, startsFrom?: string): Promise<ComponentLog[]>;

getDependencies(component: Component): DependencyList;
getDependencies(component: Component): ComponentDependencyList;

componentPackageName(component: Component): string;

Expand Down
16 changes: 14 additions & 2 deletions scopes/component/component/component.main.runtime.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,8 @@ import type { ComponentID } from '@teambit/component-id';
import { flatten, orderBy } from 'lodash';
import type { LoggerMain } from '@teambit/logger';
import { LoggerAspect } from '@teambit/logger';
import type { DependencyResolverMain } from '@teambit/dependency-resolver';
import type { ExtensionDataList } from '@teambit/legacy.extension-data';
import type { PackageManifestFetcher } from '@teambit/pkg.modules.component-package-name';
import type { ComponentFactory } from './component-factory';
import { ComponentAspect } from './component.aspect';
import { componentSchema } from './component.graphql';
Expand All @@ -38,7 +38,7 @@ export type ComponentHostSlot = SlotRegistry<ComponentFactory>;
export type ShowFragmentSlot = SlotRegistry<ShowFragment[]>;

export class ComponentMain {
dependencyResolver: DependencyResolverMain;
private packageManifestFetcher?: PackageManifestFetcher;
constructor(
/**
* slot for component hosts to register.
Expand Down Expand Up @@ -149,6 +149,18 @@ export class ComponentMain {
return !!this.hostSlot.get(name);
}

/**
* lets the commands of this aspect fetch package manifests, e.g. `bit show <package-name>`.
*/
registerPackageManifestFetcher(packageManifestFetcher: PackageManifestFetcher) {
Comment thread
davidfirst marked this conversation as resolved.
this.packageManifestFetcher = packageManifestFetcher;
}

getPackageManifestFetcher(): PackageManifestFetcher {
if (!this.packageManifestFetcher) throw new Error('no package-manifest fetcher was registered');
return this.packageManifestFetcher;
}

/**
* register a show fragment to display further information in the `bit show` command.
*/
Expand Down
7 changes: 5 additions & 2 deletions scopes/component/component/component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,9 @@ import type { ComponentID } from '@teambit/component-id';
import { BitError } from '@teambit/bit-error';
import type { BuildStatus } from '@teambit/legacy.constants';
import type { ComponentLog } from '@teambit/objects';
import type { DependencyList } from '@teambit/dependency-resolver';
import { slice } from 'lodash';
import type { ComponentFactory } from './component-factory';
import type { ComponentDependencyList } from './component-dependencies';
import type ComponentFS from './component-fs';
// import { NothingToSnap } from './exceptions';
import type { Config as ComponentConfig } from './config';
Expand Down Expand Up @@ -150,7 +150,10 @@ export class Component implements IComponent {
return filteredLogs;
}

getDependencies(): DependencyList {
/**
* @deprecated use `DependencyResolverMain.getDependencies(component)`, which returns the full `DependencyList`.
*/
getDependencies(): ComponentDependencyList {
Comment thread
qodo-free-for-open-source-projects[bot] marked this conversation as resolved.
return this.factory.getDependencies(this);
}

Expand Down
1 change: 1 addition & 0 deletions scopes/component/component/esm.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ export const Component = cjsModule.Component;
export const ComponentID = cjsModule.ComponentID;
export const ComponentAspect = cjsModule.ComponentAspect;
export const AspectEntry = cjsModule.AspectEntry;
export const AspectDefinition = cjsModule.AspectDefinition;
export const Snap = cjsModule.Snap;
export const Tag = cjsModule.Tag;
export const State = cjsModule.State;
Expand Down
3 changes: 3 additions & 0 deletions scopes/component/component/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ export type { Hash } from './hash';
export { TagMap } from './tag-map';
export { ComponentMap } from './component-map';
export type { ComponentMain } from './component.main.runtime';
export type { ComponentDependencyList } from './component-dependencies';
export type { ComponentUI } from './component.ui.runtime';
export type { Section } from './section';
export { ComponentContext, ComponentDescriptorContext, useComponentDescriptor } from './ui/context/component-context';
Expand All @@ -57,3 +58,5 @@ export { useComponent, useIdFromLocation, useComponentLogs, ComponentLogsResult,
// export { AspectEntry } from './aspect-entry';
export { ComponentAspect };
export default ComponentAspect;
export { AspectDefinition } from './aspect-definition';
Comment thread
davidfirst marked this conversation as resolved.
export type { AspectDefinitionProps } from './aspect-definition';
2 changes: 1 addition & 1 deletion scopes/component/component/show/show.cmd.ts
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ to see the legacy bit show, please use "--legacy" flag`);
private async resolveIdWithoutWorkspace(id: string): Promise<string> {
if (isLikelyPackageName(id)) {
try {
const compId = await resolveComponentIdFromPackageName(id, this.component.dependencyResolver);
const compId = await resolveComponentIdFromPackageName(id, this.component.getPackageManifestFetcher());
return compId.toString();
} catch (error) {
const errorMessage = error instanceof Error ? error.message : String(error);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import type { SemverVersion } from '@teambit/envs';
import type { DependencySource } from '../policy/variant-policy/variant-policy';

export type WorkspaceDependencyLifecycleType = 'runtime' | 'peer';
Expand All @@ -16,10 +17,7 @@ export interface SerializedDependency {
packageName?: string;
}

/**
* Allowed values are valid semver values and the "-" sign.
*/
export type SemverVersion = string;
export type { SemverVersion };
export type PackageName = string;

export type DependencyManifest = {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1991,7 +1991,7 @@ as an alternative, you can use "+" to keep the same version installed in the wor
new DevDependenciesFragment(dependencyResolver),
new PeerDependenciesFragment(dependencyResolver),
]);
componentAspect.dependencyResolver = dependencyResolver;
componentAspect.registerPackageManifestFetcher(dependencyResolver);
// TODO: solve this generics issue and remove the ts-ignore
// @ts-ignore
dependencyResolver.registerDependencyFactories([new ComponentDependencyFactory(componentAspect)]);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,54 +6,23 @@ import type {
} from '../variant-policy';
import { createVariantPolicyEntry, VariantPolicy } from '../variant-policy';
import type { DependencyLifecycleType } from '../../dependencies';
import type {
EnvJsoncPolicyEntry,
EnvJsoncPolicyPeerEntry,
VersionKeyName,
EnvJsoncPolicyConfigKey,
EnvPolicyConfigObject,
} from '@teambit/envs';

export type EnvJsoncPolicyEntry = {
name: string;
version: string;
/**
* hide the dependency from the component's package.json / dependencies list
*/
hidden?: boolean;
/**
* force add to component dependencies even if it's not used by the component.
*/
force?: boolean;
optional?: boolean;
};

export type EnvJsoncPolicyPeerEntry = EnvJsoncPolicyEntry & {
supportedRange: string;
/**
* When true, this peer dependency will be resolved as a single version at the workspace root,
* even if different envs specify different versions. Useful for @types packages and workspace-level
* tools (eslint, prettier) that must resolve from the workspace root.
* When false (default), conflicts are resolved per-component via env roots.
*/
workspaceSingleton?: boolean;
/**
* When true, generates a pnpm override for this peer using its version,
* forcing all transitive dependencies to use the same version.
* Useful to prevent old versions from being pulled by published packages.
*/
override?: boolean;
};

export type VersionKeyName = 'version' | 'supportedRange';

export type EnvJsoncPolicyConfigKey = 'peers' | 'dev' | 'runtime';

export type EnvPolicyEnvJsoncConfigObject = {
peers?: EnvJsoncPolicyPeerEntry[];
dev?: EnvJsoncPolicyEntry[];
runtime?: EnvJsoncPolicyEntry[];
};

/**
* Config that is used before the new env.jsonc format was introduced.
*/
export type EnvPolicyLegacyConfigObject = Pick<EnvPolicyEnvJsoncConfigObject, 'peers'> & VariantPolicyConfigObject;

export type EnvPolicyConfigObject = EnvPolicyEnvJsoncConfigObject | EnvPolicyLegacyConfigObject;
export type {
EnvJsoncPolicyEntry,
EnvJsoncPolicyPeerEntry,
VersionKeyName,
EnvJsoncPolicyConfigKey,
EnvPolicyEnvJsoncConfigObject,
EnvPolicyLegacyConfigObject,
EnvPolicyConfigObject,
} from '@teambit/envs';

export class EnvPolicy extends VariantPolicy {
constructor(
Expand Down
17 changes: 3 additions & 14 deletions scopes/dependencies/dependency-resolver/policy/policy.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,11 @@
import type { DependencyLifecycleType } from '../dependencies';
import type { SemverVersion } from '@teambit/envs';

export type { SemverVersion, PolicyConfigKeys, PolicyConfigKeysNames } from '@teambit/envs';

// TODO: add DetailedDependencyPolicy once support the force prop
// export type DependencyPolicy = SemverVersionRule | DetailedDependencyPolicy;

/**
* Allowed values are valid semver values
*/
export type SemverVersion = string;

export type GitUrlVersion = string;

export type FileSystemPath = string;
Expand All @@ -23,15 +21,6 @@ export type PolicySemver = SemverVersion | RemoveDepSign;
*/
export type PolicyVersion = PolicySemver | GitUrlVersion | FileSystemPath;

// TODO: think if it might need to be in another place and just reference there
export type PolicyConfigKeys = {
dependencies: 'dependencies';
devDependencies: 'devDependencies';
peerDependencies: 'peerDependencies';
};

export type PolicyConfigKeysNames = keyof PolicyConfigKeys;

export interface Policy<T> {
toConfigObject(): T;
}
Expand Down
Loading
Loading