import * as semver from 'semver'; import { LaneId } from '@teambit/lane-id'; import { ComponentID } from '@teambit/component-id'; import type { LegacyComponentLog } from '@teambit/legacy-component-log'; import { BitId } from '@teambit/legacy-bit-id'; import { ConsumerComponent } from '@teambit/legacy.consumer-component'; import type { SnapsDistance } from '@teambit/component.snap-distance'; import { ComponentObjects, ComponentVersion } from '@teambit/legacy.scope'; import type { Repository } from '../objects'; import { BitObject, Ref } from '../objects'; import type Lane from './lane'; import type Version from './version'; import type { VersionParents } from './version-history'; import VersionHistory from './version-history'; import type { ObjectItem } from '../objects/object-list'; import type { Scope } from '@teambit/legacy.scope'; import { DetachedHeads } from './detach-heads'; type State = { versions?: { [version: string]: { local?: boolean; }; }; }; export type AddVersionOpts = { addToUpdateDependentsInLane?: boolean; /** * kind of rebase. * if true, set the head as the parent of the new version. * by default, the parent is the currently used version in .bitmap. * (this prop takes affect only when the component is checked out to an older version) */ setHeadAsParent?: boolean; detachHead?: boolean; overrideHead?: boolean; }; type Versions = { [version: string]: Ref; }; export type ScopeListItem = { url: string; name: string; date: string; }; export type ComponentLog = LegacyComponentLog; export type ComponentProps = { scope: string; name: string; versions?: Versions; orphanedVersions?: Versions; lang: string; deprecated: boolean; bindingPrefix: string; state?: State; scopesList?: ScopeListItem[]; head?: Ref; schema?: string | undefined; detachedHeads?: DetachedHeads; }; export declare const VERSION_ZERO = "0.0.0"; /** * we can't rename the class as ModelComponent because old components are already saved in the model * with 'Component' in their headers. see object-registrar.types() */ export default class Component extends BitObject { scope: string; name: string; versions: Versions; orphanedVersions: Versions; lang: string; /** * @deprecated moved to the Version object inside teambit/deprecation aspect */ deprecated: boolean; bindingPrefix: string; /** * @deprecated since 0.12.6 (long long ago :) probably can be removed) */ local: boolean | null | undefined; state: State; scopesList: ScopeListItem[]; head?: Ref; remoteHead?: Ref | null; /** * doesn't get saved in the scope, used to easier access the local snap head data * when checked out to a lane, this prop is either Ref or null. otherwise (when on main), this prop is undefined. */ laneHeadLocal?: Ref | null; /** * doesn't get saved in the scope, used to easier access the remote snap head data * when checked out to a lane, this prop is either Ref or null. otherwise (when on main), this prop is undefined. */ laneHeadRemote?: Ref | null; /** * when checked out to a lane, calculate what should be the head on the remote. * if the laneHeadRemote is null, for example, when the lane is new, then used the the lane it was forked from. * it no head is found on the lane/forked, then use the component.head. */ calculatedRemoteHeadWhenOnLane?: Ref | null; laneId?: LaneId; laneDataIsPopulated: boolean; schema: string | undefined; detachedHeads: DetachedHeads; private divergeData?; private _populateVersionHistoryMutex?; constructor(props: ComponentProps); private get populateVersionHistoryMutex(); get versionArray(): Ref[]; setVersion(tag: string, ref: Ref): void; setOrphanedVersion(tag: string, ref: Ref): void; getRef(version: string): Ref | null; getHeadStr(): string | null; getHead(): Ref | undefined; /** * returns the head hash. regardless of whether current lane is the default or not. * if on a lane, it returns the head of the component on the lane. */ getHeadRegardlessOfLane(): Ref | undefined; getHeadAsTagIfExist(): string | undefined; hasHead(): boolean; setHead(head: Ref | undefined): void; listVersions(sort?: 'ASC' | 'DESC'): string[]; listVersionsIncludeOrphaned(sort?: 'ASC' | 'DESC'): string[]; hasVersion(version: string, repo: Repository, includeOrphaned?: boolean): Promise; hasTag(version: string): boolean; get versionsIncludeOrphaned(): Versions; hasTagIncludeOrphaned(version: string): boolean; /** * whether the head is a snap (not a tag) */ isHeadSnap(): boolean | undefined; /** * add a new remote if it is not there already */ addScopeListItem(scopeListItem: ScopeListItem): void; /** * on main - it checks local-head (or .bitmap version if given) vs remote-head. * on lane - it checks local-head on lane vs remote-head on lane. * however, to get an accurate `divergeData.snapsOnSourceOnly`, the above is not enough. * for example, comp-a@snap-x from lane-a is merged into lane-b. we don't want this snap-x to be "local", because * then, bit-status will show it as "staged" and bit-reset will remove it unexpectedly. * if we only check by the local-head and remote-head on lane, it'll be local because the remote-head of lane-b is empty. * to address this, we search all remote-refs files for this bit-id and during the local history traversal, if a hash * is found there, it'll stop the traversal and not mark it as remote. * in this example, during the merge, lane-a was fetched, and the remote-ref of this lane has snap-x as the head. */ setDivergeData(repo: Repository, throws?: boolean, fromCache?: boolean, workspaceId?: ComponentID): Promise; isOnLane(): boolean; /** * this is used (among others) by `bit status` to check whether snaps are local (staged), for `bit reset` to remove them * and for `bit export` to push them. for "merge pending" status, use `this.getDivergeDataForMergePending()`. */ getDivergeData(): SnapsDistance; /** * don't use modelComponent.getDivergeData() because in some scenarios when on a lane, it compares the head * on the lane against the head on the main, which could show the component as diverged incorrectly. */ getDivergeDataForMergePending(repo: Repository): Promise; populateLocalAndRemoteHeads(repo: Repository, lane?: Lane): Promise; setLaneHeadLocal(lane?: Lane): void; /** * returns only the versions that exist in both components (regardless whether the hash are the same) * e.g. this.component = [0.0.1, 0.0.2, 0.0.3], other component = [0.0.3, 0.0.4]. it returns only [0.0.3]. * also, in case it is coming from 'bit import', the version must be locally changed. * otherwise, it doesn't matter whether the hashes are different. */ _getComparableVersionsObjects(otherComponent: Component, // in case of merging, the otherComponent is the existing component, and "this" is the incoming component local: boolean): { thisComponentVersions: Versions; otherComponentVersions: Versions; }; compatibleWith(component: Component, local: boolean): boolean; diffWith(component: Component, local: boolean): string[]; isEmpty(): boolean; /** * on main return main head, on lane, return lane head. * if the head is also a tag, return the tag, otherwise, return the hash. */ getHeadRegardlessOfLaneAsTagOrHash(returnVersionZeroForNoHead?: boolean): string; /** * get the recent head. if locally is ahead, return the local head. otherwise, return the remote head. * * a user can be checked out to a lane, in which case, `this.laneHeadLocal` and `this.laneHeadRemote` * may be populated. * `this.head` may not be populated, e.g. when a component was created on * this lane and never got snapped on main. * it's impossible that `this.head.isEqual(this.laneHeadLocal)`, because when snapping it's either * on main, which goes to this.head OR on a lane, which goes to this.laneHeadLocal. */ headIncludeRemote(repo: Repository): Promise; getRefOfAncestor(repo: Repository, generationsToGoBack: number): Promise; latestVersion(): string; latestVersionIfExist(): string | undefined; isLatestGreaterThan(version: string | null | undefined): boolean; /** * Return the lateset version which actuall exists in the scope * (exists means the object itself exists) * This relevant for cases when the component version array has few versions * but we don't have all the refs in the object * * @returns {number} * @memberof Component */ latestExisting(repository: Repository): string; /** * get component log and sort by the timestamp in ascending order (from the earliest to the latest) */ collectLogs(scope: Scope, shortHash?: boolean, startFrom?: Ref): Promise; collectVersions(repo: Repository): Promise; getTagOfRefIfExists(ref: Ref, allTags?: Versions): string | undefined; getTag(version: string): string | undefined; switchHashesWithTagsIfExist(refs: Ref[]): string[]; /** * if exactVersion is defined, add exact version instead of using the semver mechanism */ getVersionToAdd(releaseType?: semver.ReleaseType, exactVersion?: string | null, incrementBy?: number, preReleaseId?: string): string; isEqual(component: Component, considerOrphanedVersions?: boolean): boolean; addVersion(version: Version, versionToAdd: string, lane?: Lane, previouslyUsedVersion?: string, { addToUpdateDependentsInLane, setHeadAsParent, detachHead, overrideHead }?: AddVersionOpts): string; version(releaseType?: semver.ReleaseType, incrementBy?: number, preReleaseId?: string): string; id(): string; /** * @deprecated use toComponentId() instead */ toBitId(): BitId; toComponentId(): ComponentID; /** * @deprecated use toComponentIdWithLatestVersion() instead */ toBitIdWithLatestVersion(): BitId; toComponentIdWithLatestVersion(): ComponentID; toComponentIdWithHead(): ComponentID; toBitIdWithLatestVersionAllowNull(): ComponentID; toObject(): { name: string; scope: string; versions: {}; lang: string; deprecated: boolean; bindingPrefix: string; remotes: ScopeListItem[]; schema: string | undefined; detachedHeads: { heads?: string[]; deleted?: string[]; current?: string; } | undefined; }; loadVersion(versionStr: string, repository: Repository, throws?: boolean): Promise; loadVersionSync(version: string, repository: Repository, throws?: boolean): Version; collectVersionsObjects(repo: Repository, versions: string[], throwForMissingLocalArtifacts?: boolean, workspaceId?: ComponentID): Promise; collectObjects(repo: Repository): Promise; /** * to delete a version from a component, don't call this method directly. Instead, use sources.removeVersion() */ removeVersion(version: string): Ref; toComponentVersion(versionStr?: string): ComponentVersion; /** * if no "specificVersion" is given, it returns according to the head */ isDeprecated(repo: Repository, specificVersion?: string): Promise; isRemoved(repo: Repository, specificVersion?: string): Promise; isLaneReadmeOf(repo: Repository): Promise; /** * convert a ModelComponent of a specific version to ConsumerComponent * @see sources.consumerComponentToVersion() for the opposite action. */ toConsumerComponent(versionStr: string, scopeName: string, repository: Repository): Promise; private addDepsInfoFromDepsResolver; refs(): Ref[]; validateBeforePersisting(componentStr: string): void; toBuffer(pretty: boolean): Buffer; /** * Clear data that is relevant only for the local scope and should not be moved to the remote scope */ clearStateData(): void; markVersionAsLocal(version: string): void; /** * local versions that are not exported on the main lane. * @see `this.getLocalTagsOrHashes()`, to get local snaps on the current lane */ getLocalVersions(): string[]; hasLocalTag(tag: string): boolean; getLocalTagsOrHashes(repo: Repository, workspaceId?: ComponentID): Promise; getLocalHashes(repo: Repository, workspaceId?: ComponentID): Promise; /** * for most cases, use `isLocallyChanged`, which takes into account lanes. * this is for cases when we only care about the versions exist in the `state` prop. */ isLocallyChangedRegardlessOfLanes(): boolean; /** * whether the component was locally changed, either by adding a new snap/tag or by merging * components from different lanes. */ isLocallyChanged(repo: Repository, lane?: Lane | null, workspaceId?: ComponentID): Promise; getVersionHistory(repo: Repository): Promise; getAndPopulateVersionHistory(repo: Repository, head: Ref): Promise; /** * careful! the `versions` passed here can belong to other components, not necessarily to this one. * that's why it checks whether the version-hash exists in the VersionHistory, and if it's not, * it won't update it. */ updateRebasedVersionHistory(repo: Repository, versions: Version[]): Promise; updateVersionHistory(repo: Repository, versions: Version[]): Promise; populateVersionHistoryIfMissingGracefully(repo: Repository, versionHistory: VersionHistory, head: Ref, /** * during traversal, if a hash is found in the VersionHistory it probably means that it has all history until this * point, so we can stop there for better performance. In some rare cases (e.g. the export was interrupted), we * need the ability of full traversal to repair the VersionHistory. */ exitWhenFind?: boolean): Promise<{ err?: Error; added?: VersionParents[]; }>; static parse(contents: string): Component; static from(props: ComponentProps): Component; static fromBitId(bitId: ComponentID): Component; get isLegacy(): boolean; validate(): void; } export {};