@teambit/component-writer 1.0.1174 → 1.0.1175

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -20,6 +20,13 @@ export type ComponentWriterProps = {
20
20
  existingComponentMap?: ComponentMap;
21
21
  skipUpdatingBitMap?: boolean;
22
22
  };
23
+ /**
24
+ * a version of the workspace-root component can carry files that a component nested inside it owns
25
+ * today - it was snapped before that component was extracted out of the root. they belong to the
26
+ * nested component now (see getNestedRootDirs), so writing them back would replace its source with
27
+ * an older copy of it.
28
+ */
29
+ export declare function isOwnedByNestedComponent(relativePath: PathLinuxRelative, nestedRootDirs: PathLinuxRelative[]): boolean;
23
30
  export default class ComponentWriter {
24
31
  component: Component;
25
32
  writeToPath: PathLinuxRelative;
@@ -4,6 +4,7 @@ Object.defineProperty(exports, "__esModule", {
4
4
  value: true
5
5
  });
6
6
  exports.default = void 0;
7
+ exports.isOwnedByNestedComponent = isOwnedByNestedComponent;
7
8
  function _legacy() {
8
9
  const data = require("@teambit/legacy.utils");
9
10
  _legacy = function () {
@@ -11,6 +12,13 @@ function _legacy() {
11
12
  };
12
13
  return data;
13
14
  }
15
+ function _legacy2() {
16
+ const data = require("@teambit/legacy.bit-map");
17
+ _legacy2 = function () {
18
+ return data;
19
+ };
20
+ return data;
21
+ }
14
22
  function _component() {
15
23
  const data = require("@teambit/component.sources");
16
24
  _component = function () {
@@ -42,6 +50,20 @@ function _bitError() {
42
50
  function _defineProperty(e, r, t) { return (r = _toPropertyKey(r)) in e ? Object.defineProperty(e, r, { value: t, enumerable: !0, configurable: !0, writable: !0 }) : e[r] = t, e; }
43
51
  function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == typeof i ? i : i + ""; }
44
52
  function _toPrimitive(t, r) { if ("object" != typeof t || !t) return t; var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r || "default"); if ("object" != typeof i) return i; throw new TypeError("@@toPrimitive must return a primitive value."); } return ("string" === r ? String : Number)(t); }
53
+ /**
54
+ * a version of the workspace-root component can carry files that a component nested inside it owns
55
+ * today - it was snapped before that component was extracted out of the root. they belong to the
56
+ * nested component now (see getNestedRootDirs), so writing them back would replace its source with
57
+ * an older copy of it.
58
+ */
59
+ function isOwnedByNestedComponent(relativePath, nestedRootDirs) {
60
+ return nestedRootDirs.some(
61
+ // the nested root-dir itself, not only what is under it: the root can carry a plain file exactly
62
+ // where the component's directory now is - it was one before the component was extracted there.
63
+ // a file and a directory cannot share a path, and writing the stale file over it fails the whole
64
+ // checkout with EISDIR. the directory is the nested component's, so the root gives up the path.
65
+ nestedRootDir => relativePath === nestedRootDir || relativePath.startsWith(`${nestedRootDir}/`));
66
+ }
45
67
  class ComponentWriter {
46
68
  constructor({
47
69
  component,
@@ -115,8 +137,15 @@ class ComponentWriter {
115
137
  if (this.deleteBitDirContent) {
116
138
  this.component.dataToPersist.removePath(new (_component().RemovePath)(this.writeToPath));
117
139
  }
118
- this.component.files.forEach(file => file.override = this.override);
119
- this.component.files.map(file => this.component.dataToPersist.addFile(file));
140
+ const nestedRootDirs = this.bitMap.getNestedRootDirs(this.writeToPath);
141
+ this.component.files.forEach(file => {
142
+ const relativePath = (0, _legacy().pathNormalizeToLinux)(file.relative);
143
+ // the live map is never written from a versioned copy, see isWorkspaceMapFile
144
+ if ((0, _legacy2().isWorkspaceMapFile)(relativePath)) return;
145
+ if (isOwnedByNestedComponent(relativePath, nestedRootDirs)) return;
146
+ file.override = this.override;
147
+ this.component.dataToPersist.addFile(file);
148
+ });
120
149
  if (this.component.license && this.component.license.contents) {
121
150
  this.component.license.updatePaths({
122
151
  newBase: this.writeToPath
@@ -132,9 +161,6 @@ class ComponentWriter {
132
161
  }
133
162
  }
134
163
  async addComponentToBitMap(rootDir) {
135
- if (rootDir === '.') {
136
- throw new Error('addComponentToBitMap: rootDir cannot be "."');
137
- }
138
164
  const filesForBitMap = this.component.files.map(file => {
139
165
  return {
140
166
  name: file.basename,
@@ -1 +1 @@
1
- {"version":3,"names":["_legacy","data","require","_component","_componentVersion","_objects","_bitError","_defineProperty","e","r","t","_toPropertyKey","Object","defineProperty","value","enumerable","configurable","writable","i","_toPrimitive","Symbol","toPrimitive","call","TypeError","String","Number","ComponentWriter","constructor","component","writeToPath","writeConfig","writePackageJson","override","isolated","workspace","scope","consumer","bitMap","ignoreBitDependencies","deleteBitDirContent","existingComponentMap","skipUpdatingBitMap","populateComponentsFilesToWrite","Error","files","length","BitError","id","toString","throwForImportingLegacyIntoHarmony","dataToPersist","DataToPersist","componentMap","addComponentToBitMap","_updateComponentRootPathAccordingToBitMap","rootDir","populateFilesToWriteToComponentDir","isLegacy","removePath","RemovePath","forEach","file","map","addFile","license","contents","updatePaths","newBase","vinylFile","getComponentConfigVinylFile","filesForBitMap","name","basename","relativePath","pathNormalizeToLinux","relative","test","bitId","replaceSnapWithTagIfNeeded","compId","resolveIdWithDefaultScope","defaultScope","hasScope","undefined","componentDefaultScopeFromComponentDirAndName","fullName","addComponent","componentId","mainFile","version","isHash","compFromModel","getModelComponentIfExist","tag","getTagOfRefIfExists","Ref","from","changeVersion","getRootDir","writtenPath","_updateFilesBasePaths","exports","default"],"sources":["component-writer.ts"],"sourcesContent":["import type { ComponentID, ComponentIdList } from '@teambit/component-id';\nimport type { Scope } from '@teambit/legacy.scope';\nimport type { PathLinuxRelative } from '@teambit/legacy.utils';\nimport { pathNormalizeToLinux } from '@teambit/legacy.utils';\nimport type { BitMap, ComponentMap } from '@teambit/legacy.bit-map';\nimport type { ConsumerComponent as Component } from '@teambit/legacy.consumer-component';\nimport { DataToPersist, RemovePath } from '@teambit/component.sources';\nimport type { Consumer } from '@teambit/legacy.consumer';\nimport { isHash } from '@teambit/component-version';\nimport { Ref } from '@teambit/objects';\nimport type { Workspace } from '@teambit/workspace';\nimport { BitError } from '@teambit/bit-error';\n\nexport type ComponentWriterProps = {\n component: Component;\n writeToPath: PathLinuxRelative;\n writeConfig?: boolean;\n writePackageJson?: boolean;\n override?: boolean;\n isolated?: boolean;\n workspace: Workspace;\n scope?: Scope | undefined;\n bitMap: BitMap;\n ignoreBitDependencies?: boolean | ComponentIdList;\n deleteBitDirContent?: boolean;\n existingComponentMap?: ComponentMap;\n skipUpdatingBitMap?: boolean;\n};\n\nexport default class ComponentWriter {\n component: Component;\n writeToPath: PathLinuxRelative;\n writeConfig?: boolean;\n writePackageJson?: boolean;\n override: boolean; // default to true\n isolated?: boolean;\n consumer: Consumer | undefined; // when using capsule, the consumer is not defined\n workspace: Workspace;\n scope?: Scope | undefined;\n bitMap: BitMap;\n ignoreBitDependencies: boolean | ComponentIdList;\n deleteBitDirContent: boolean | undefined;\n existingComponentMap: ComponentMap | undefined;\n skipUpdatingBitMap?: boolean;\n\n constructor({\n component,\n writeToPath,\n writeConfig = false,\n writePackageJson = true,\n override = true,\n isolated = false,\n workspace,\n scope = workspace.consumer?.scope,\n bitMap,\n ignoreBitDependencies = true,\n deleteBitDirContent,\n existingComponentMap,\n skipUpdatingBitMap,\n }: ComponentWriterProps) {\n this.component = component;\n this.writeToPath = writeToPath;\n this.writeConfig = writeConfig;\n this.writePackageJson = writePackageJson;\n this.override = override;\n this.isolated = isolated;\n this.workspace = workspace;\n this.consumer = workspace.consumer;\n this.scope = scope;\n this.bitMap = bitMap;\n this.ignoreBitDependencies = ignoreBitDependencies;\n this.deleteBitDirContent = deleteBitDirContent;\n this.existingComponentMap = existingComponentMap;\n this.skipUpdatingBitMap = skipUpdatingBitMap;\n }\n\n async populateComponentsFilesToWrite(): Promise<Component> {\n if (this.isolated) throw new Error('for isolation, please use this.populateComponentsFilesToWriteForCapsule()');\n if (!this.component.files || !this.component.files.length) {\n throw new BitError(`Component ${this.component.id.toString()} is invalid as it has no files`);\n }\n this.throwForImportingLegacyIntoHarmony();\n this.component.dataToPersist = new DataToPersist();\n this.component.componentMap = this.existingComponentMap || (await this.addComponentToBitMap(this.writeToPath));\n this.deleteBitDirContent = false;\n this._updateComponentRootPathAccordingToBitMap();\n if (!this.skipUpdatingBitMap) {\n this.component.componentMap = await this.addComponentToBitMap(this.component.componentMap.rootDir);\n }\n this.writePackageJson = false;\n await this.populateFilesToWriteToComponentDir();\n return this.component;\n }\n\n private throwForImportingLegacyIntoHarmony() {\n if (this.component.isLegacy && this.consumer) {\n throw new Error(\n `unable to write component \"${this.component.id.toString()}\", it is a legacy component and this workspace is Harmony`\n );\n }\n }\n\n async populateFilesToWriteToComponentDir() {\n if (this.deleteBitDirContent) {\n this.component.dataToPersist.removePath(new RemovePath(this.writeToPath));\n }\n this.component.files.forEach((file) => (file.override = this.override));\n this.component.files.map((file) => this.component.dataToPersist.addFile(file));\n\n if (this.component.license && this.component.license.contents) {\n this.component.license.updatePaths({ newBase: this.writeToPath });\n this.component.license.override = this.override;\n this.component.dataToPersist.addFile(this.component.license);\n }\n if (this.writeConfig) {\n const vinylFile = await this.workspace.getComponentConfigVinylFile(this.component.id, { override: true }, true);\n this.component.dataToPersist.addFile(vinylFile);\n }\n }\n\n async addComponentToBitMap(rootDir: string): Promise<ComponentMap> {\n if (rootDir === '.') {\n throw new Error('addComponentToBitMap: rootDir cannot be \".\"');\n }\n const filesForBitMap = this.component.files.map((file) => {\n return { name: file.basename, relativePath: pathNormalizeToLinux(file.relative), test: file.test };\n });\n\n const bitId = await this.replaceSnapWithTagIfNeeded();\n const compId = this.workspace.resolveIdWithDefaultScope(bitId);\n const defaultScope = compId.hasScope()\n ? undefined\n : await this.workspace.componentDefaultScopeFromComponentDirAndName(rootDir, bitId.fullName);\n\n return this.bitMap.addComponent({\n componentId: compId,\n files: filesForBitMap,\n defaultScope,\n mainFile: pathNormalizeToLinux(this.component.mainFile),\n rootDir,\n });\n }\n\n private async replaceSnapWithTagIfNeeded(): Promise<ComponentID> {\n const version = this.component.id.version;\n if (!version || !isHash(version)) {\n return this.component.id;\n }\n const compFromModel = await this.scope?.getModelComponentIfExist(this.component.id);\n const tag = compFromModel?.getTagOfRefIfExists(Ref.from(version));\n if (tag) return this.component.id.changeVersion(tag);\n return this.component.id;\n }\n\n _updateComponentRootPathAccordingToBitMap() {\n // @ts-ignore this.component.componentMap is set\n this.writeToPath = this.component.componentMap.getRootDir();\n this.component.writtenPath = this.writeToPath;\n this._updateFilesBasePaths();\n }\n\n private _updateFilesBasePaths() {\n const newBase = this.writeToPath || '.';\n this.component.files.forEach((file) => file.updatePaths({ newBase }));\n }\n}\n"],"mappings":"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","ignoreList":[]}
1
+ {"version":3,"names":["_legacy","data","require","_legacy2","_component","_componentVersion","_objects","_bitError","_defineProperty","e","r","t","_toPropertyKey","Object","defineProperty","value","enumerable","configurable","writable","i","_toPrimitive","Symbol","toPrimitive","call","TypeError","String","Number","isOwnedByNestedComponent","relativePath","nestedRootDirs","some","nestedRootDir","startsWith","ComponentWriter","constructor","component","writeToPath","writeConfig","writePackageJson","override","isolated","workspace","scope","consumer","bitMap","ignoreBitDependencies","deleteBitDirContent","existingComponentMap","skipUpdatingBitMap","populateComponentsFilesToWrite","Error","files","length","BitError","id","toString","throwForImportingLegacyIntoHarmony","dataToPersist","DataToPersist","componentMap","addComponentToBitMap","_updateComponentRootPathAccordingToBitMap","rootDir","populateFilesToWriteToComponentDir","isLegacy","removePath","RemovePath","getNestedRootDirs","forEach","file","pathNormalizeToLinux","relative","isWorkspaceMapFile","addFile","license","contents","updatePaths","newBase","vinylFile","getComponentConfigVinylFile","filesForBitMap","map","name","basename","test","bitId","replaceSnapWithTagIfNeeded","compId","resolveIdWithDefaultScope","defaultScope","hasScope","undefined","componentDefaultScopeFromComponentDirAndName","fullName","addComponent","componentId","mainFile","version","isHash","compFromModel","getModelComponentIfExist","tag","getTagOfRefIfExists","Ref","from","changeVersion","getRootDir","writtenPath","_updateFilesBasePaths","exports","default"],"sources":["component-writer.ts"],"sourcesContent":["import type { ComponentID, ComponentIdList } from '@teambit/component-id';\nimport type { Scope } from '@teambit/legacy.scope';\nimport type { PathLinuxRelative } from '@teambit/legacy.utils';\nimport { pathNormalizeToLinux } from '@teambit/legacy.utils';\nimport type { BitMap, ComponentMap } from '@teambit/legacy.bit-map';\nimport { isWorkspaceMapFile } from '@teambit/legacy.bit-map';\nimport type { ConsumerComponent as Component } from '@teambit/legacy.consumer-component';\nimport { DataToPersist, RemovePath } from '@teambit/component.sources';\nimport type { Consumer } from '@teambit/legacy.consumer';\nimport { isHash } from '@teambit/component-version';\nimport { Ref } from '@teambit/objects';\nimport type { Workspace } from '@teambit/workspace';\nimport { BitError } from '@teambit/bit-error';\n\nexport type ComponentWriterProps = {\n component: Component;\n writeToPath: PathLinuxRelative;\n writeConfig?: boolean;\n writePackageJson?: boolean;\n override?: boolean;\n isolated?: boolean;\n workspace: Workspace;\n scope?: Scope | undefined;\n bitMap: BitMap;\n ignoreBitDependencies?: boolean | ComponentIdList;\n deleteBitDirContent?: boolean;\n existingComponentMap?: ComponentMap;\n skipUpdatingBitMap?: boolean;\n};\n\n/**\n * a version of the workspace-root component can carry files that a component nested inside it owns\n * today - it was snapped before that component was extracted out of the root. they belong to the\n * nested component now (see getNestedRootDirs), so writing them back would replace its source with\n * an older copy of it.\n */\nexport function isOwnedByNestedComponent(\n relativePath: PathLinuxRelative,\n nestedRootDirs: PathLinuxRelative[]\n): boolean {\n return nestedRootDirs.some(\n // the nested root-dir itself, not only what is under it: the root can carry a plain file exactly\n // where the component's directory now is - it was one before the component was extracted there.\n // a file and a directory cannot share a path, and writing the stale file over it fails the whole\n // checkout with EISDIR. the directory is the nested component's, so the root gives up the path.\n (nestedRootDir) => relativePath === nestedRootDir || relativePath.startsWith(`${nestedRootDir}/`)\n );\n}\n\nexport default class ComponentWriter {\n component: Component;\n writeToPath: PathLinuxRelative;\n writeConfig?: boolean;\n writePackageJson?: boolean;\n override: boolean; // default to true\n isolated?: boolean;\n consumer: Consumer | undefined; // when using capsule, the consumer is not defined\n workspace: Workspace;\n scope?: Scope | undefined;\n bitMap: BitMap;\n ignoreBitDependencies: boolean | ComponentIdList;\n deleteBitDirContent: boolean | undefined;\n existingComponentMap: ComponentMap | undefined;\n skipUpdatingBitMap?: boolean;\n\n constructor({\n component,\n writeToPath,\n writeConfig = false,\n writePackageJson = true,\n override = true,\n isolated = false,\n workspace,\n scope = workspace.consumer?.scope,\n bitMap,\n ignoreBitDependencies = true,\n deleteBitDirContent,\n existingComponentMap,\n skipUpdatingBitMap,\n }: ComponentWriterProps) {\n this.component = component;\n this.writeToPath = writeToPath;\n this.writeConfig = writeConfig;\n this.writePackageJson = writePackageJson;\n this.override = override;\n this.isolated = isolated;\n this.workspace = workspace;\n this.consumer = workspace.consumer;\n this.scope = scope;\n this.bitMap = bitMap;\n this.ignoreBitDependencies = ignoreBitDependencies;\n this.deleteBitDirContent = deleteBitDirContent;\n this.existingComponentMap = existingComponentMap;\n this.skipUpdatingBitMap = skipUpdatingBitMap;\n }\n\n async populateComponentsFilesToWrite(): Promise<Component> {\n if (this.isolated) throw new Error('for isolation, please use this.populateComponentsFilesToWriteForCapsule()');\n if (!this.component.files || !this.component.files.length) {\n throw new BitError(`Component ${this.component.id.toString()} is invalid as it has no files`);\n }\n this.throwForImportingLegacyIntoHarmony();\n this.component.dataToPersist = new DataToPersist();\n this.component.componentMap = this.existingComponentMap || (await this.addComponentToBitMap(this.writeToPath));\n this.deleteBitDirContent = false;\n this._updateComponentRootPathAccordingToBitMap();\n if (!this.skipUpdatingBitMap) {\n this.component.componentMap = await this.addComponentToBitMap(this.component.componentMap.rootDir);\n }\n this.writePackageJson = false;\n await this.populateFilesToWriteToComponentDir();\n return this.component;\n }\n\n private throwForImportingLegacyIntoHarmony() {\n if (this.component.isLegacy && this.consumer) {\n throw new Error(\n `unable to write component \"${this.component.id.toString()}\", it is a legacy component and this workspace is Harmony`\n );\n }\n }\n\n async populateFilesToWriteToComponentDir() {\n if (this.deleteBitDirContent) {\n this.component.dataToPersist.removePath(new RemovePath(this.writeToPath));\n }\n const nestedRootDirs = this.bitMap.getNestedRootDirs(this.writeToPath);\n this.component.files.forEach((file) => {\n const relativePath = pathNormalizeToLinux(file.relative);\n // the live map is never written from a versioned copy, see isWorkspaceMapFile\n if (isWorkspaceMapFile(relativePath)) return;\n if (isOwnedByNestedComponent(relativePath, nestedRootDirs)) return;\n file.override = this.override;\n this.component.dataToPersist.addFile(file);\n });\n\n if (this.component.license && this.component.license.contents) {\n this.component.license.updatePaths({ newBase: this.writeToPath });\n this.component.license.override = this.override;\n this.component.dataToPersist.addFile(this.component.license);\n }\n if (this.writeConfig) {\n const vinylFile = await this.workspace.getComponentConfigVinylFile(this.component.id, { override: true }, true);\n this.component.dataToPersist.addFile(vinylFile);\n }\n }\n\n async addComponentToBitMap(rootDir: string): Promise<ComponentMap> {\n const filesForBitMap = this.component.files.map((file) => {\n return { name: file.basename, relativePath: pathNormalizeToLinux(file.relative), test: file.test };\n });\n\n const bitId = await this.replaceSnapWithTagIfNeeded();\n const compId = this.workspace.resolveIdWithDefaultScope(bitId);\n const defaultScope = compId.hasScope()\n ? undefined\n : await this.workspace.componentDefaultScopeFromComponentDirAndName(rootDir, bitId.fullName);\n\n return this.bitMap.addComponent({\n componentId: compId,\n files: filesForBitMap,\n defaultScope,\n mainFile: pathNormalizeToLinux(this.component.mainFile),\n rootDir,\n });\n }\n\n private async replaceSnapWithTagIfNeeded(): Promise<ComponentID> {\n const version = this.component.id.version;\n if (!version || !isHash(version)) {\n return this.component.id;\n }\n const compFromModel = await this.scope?.getModelComponentIfExist(this.component.id);\n const tag = compFromModel?.getTagOfRefIfExists(Ref.from(version));\n if (tag) return this.component.id.changeVersion(tag);\n return this.component.id;\n }\n\n _updateComponentRootPathAccordingToBitMap() {\n // @ts-ignore this.component.componentMap is set\n this.writeToPath = this.component.componentMap.getRootDir();\n this.component.writtenPath = this.writeToPath;\n this._updateFilesBasePaths();\n }\n\n private _updateFilesBasePaths() {\n const newBase = this.writeToPath || '.';\n this.component.files.forEach((file) => file.updatePaths({ newBase }));\n }\n}\n"],"mappings":"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","ignoreList":[]}
@@ -10,6 +10,12 @@ import type { Consumer } from '@teambit/legacy.consumer';
10
10
  export interface ManyComponentsWriterParams {
11
11
  components: ConsumerComponent[];
12
12
  writeToPath?: string;
13
+ /**
14
+ * a directory per component, keyed by the id without its version, for writing a set of components
15
+ * that each go to its own place - as "--path" does for a whole batch. a component the map does not
16
+ * name falls back to writeToPath, and then to the default directory.
17
+ */
18
+ writeToPathPerId?: Record<string, string>;
13
19
  throwForExistingDir?: boolean;
14
20
  writeToEmptyDir?: boolean;
15
21
  writeConfig?: boolean;
@@ -68,12 +74,55 @@ export declare class ComponentWriterMain {
68
74
  */
69
75
  private fixDirsIfNested;
70
76
  private getWriteParamsOfOneComponent;
77
+ /**
78
+ * where this component was asked to go, if anywhere: its own entry in writeToPathPerId, else the
79
+ * writeToPath of the whole batch.
80
+ */
81
+ private getWriteToPath;
71
82
  private moveComponentsIfNeeded;
72
83
  /**
73
84
  * true when the directory-conflict check can be skipped: either nothing is written to the filesystem, or the
74
85
  * target directory already belongs to this exact component (so overriding it in place is safe).
75
86
  */
76
87
  private shouldSkipDirConflictCheck;
88
+ /**
89
+ * a workspace-root component's files land in the workspace tree itself, where a path may be a
90
+ * symbolic link the user made - a directory on the way, or the destination itself. a write through
91
+ * it would land the file wherever the link points, so every existing path on the way to an incoming
92
+ * file has to be real. this is about where the write goes, not what it replaces, so --override does
93
+ * not waive it (it waives the conflict check, which is the other place the destination is looked at).
94
+ */
95
+ /**
96
+ * the incoming files a write would actually land at the workspace root. a component nested in the
97
+ * root owns its own directory, and populateFilesToWriteToComponentDir leaves those files alone - so
98
+ * the checks below must not reject an import over a path it would never touch. an older version of
99
+ * the root, snapped before that component was extracted out of it, still carries them.
100
+ */
101
+ private filesThatWouldLand;
102
+ private throwForSymlinksInTheWay;
103
+ /**
104
+ * only a workspace-root component may be written to ".". any other component written there would own
105
+ * every unclaimed file in the workspace from the next scan on, and drop out of install and link. a
106
+ * workspace-root component is told by the marker its versions carry (see WorkspaceRootData) - a
107
+ * .bitmap among its files is not enough, a component snapped before maps were excluded from
108
+ * component scans may carry one.
109
+ */
110
+ private throwForNonWorkspaceRootComponent;
111
+ /**
112
+ * the workspace root is never empty - it holds .bit, .bitmap and workspace.jsonc - so "not empty"
113
+ * says nothing about a conflict there. the target is only reachable for a workspace-root component.
114
+ * restoring a git-free workspace from its scope starts from `bit init`, and the root files are meant
115
+ * to land on top of the ones it generated. every other existing file at the root is the user's own,
116
+ * whether or not the workspace tracks components yet, so overwriting it takes --override like any
117
+ * other occupied directory. a file identical to its incoming copy is not overwritten in any sense
118
+ * that matters, and this is what lets the files `bit init` generates (agent instructions, mcp config)
119
+ * meet their own versioned copies. workspace.jsonc is the exception: the freshly initialized one is
120
+ * meant to be replaced by the versioned one - and only while the map is still empty, which is what
121
+ * `bit init` leaves behind. once the workspace tracks a component the file is the user's own like
122
+ * any other, whichever component that is: the exemption is about what `bit init` just wrote, not
123
+ * about who owns the root.
124
+ */
125
+ private throwForOccupiedWorkspaceRoot;
77
126
  private throwErrorWhenDirectoryNotEmpty;
78
127
  /**
79
128
  * final `writeToPath` resolution for the `--write-to-empty-dir` import flag, mainly for non-interactive clients
@@ -90,12 +90,26 @@ function _legacy() {
90
90
  return data;
91
91
  }
92
92
  function _legacy2() {
93
- const data = require("@teambit/legacy.constants");
93
+ const data = require("@teambit/legacy.bit-map");
94
94
  _legacy2 = function () {
95
95
  return data;
96
96
  };
97
97
  return data;
98
98
  }
99
+ function _workspaceRoot() {
100
+ const data = require("@teambit/workspace-root");
101
+ _workspaceRoot = function () {
102
+ return data;
103
+ };
104
+ return data;
105
+ }
106
+ function _legacy3() {
107
+ const data = require("@teambit/legacy.constants");
108
+ _legacy3 = function () {
109
+ return data;
110
+ };
111
+ return data;
112
+ }
99
113
  function _component() {
100
114
  const data = require("@teambit/component.sources");
101
115
  _component = function () {
@@ -111,7 +125,7 @@ function _configMerger() {
111
125
  return data;
112
126
  }
113
127
  function _componentWriter() {
114
- const data = _interopRequireDefault(require("./component-writer"));
128
+ const data = _interopRequireWildcard(require("./component-writer"));
115
129
  _componentWriter = function () {
116
130
  return data;
117
131
  };
@@ -239,7 +253,7 @@ class ComponentWriterMain {
239
253
  // rely on .bitmap to determine whether a dependency exists and what's its origin
240
254
  await Promise.all(componentWriterInstances.map(async componentWriter => {
241
255
  componentWriter.existingComponentMap = componentWriter.existingComponentMap || (await componentWriter.addComponentToBitMap(componentWriter.writeToPath));
242
- const componentConfigPath = path().join(this.workspace.path, componentWriter.existingComponentMap.rootDir, _legacy2().COMPONENT_CONFIG_FILE_NAME);
256
+ const componentConfigPath = path().join(this.workspace.path, componentWriter.existingComponentMap.rootDir, _legacy3().COMPONENT_CONFIG_FILE_NAME);
243
257
  const componentConfigExist = await _fsExtra().default.pathExists(componentConfigPath);
244
258
  componentWriter.writeConfig = componentWriter.writeConfig || componentConfigExist;
245
259
  }));
@@ -323,15 +337,26 @@ class ComponentWriterMain {
323
337
  });
324
338
  }
325
339
  getWriteParamsOfOneComponent(component, opts) {
326
- const componentRootDir = opts.writeToPath ? (0, _legacy().pathNormalizeToLinux)(this.consumer.getPathRelativeToConsumer(path().resolve(opts.writeToPath))) : this.consumer.composeRelativeComponentPath(component.id);
340
+ // "--path ." resolves to an empty relative path. normalize it to "." so it is a real rootDir
341
+ // rather than a falsy one that later turns into an undefined path segment.
342
+ const writeToPath = this.getWriteToPath(component, opts);
343
+ const componentRootDir = writeToPath ? (0, _legacy().pathNormalizeToLinux)(this.consumer.getPathRelativeToConsumer(path().resolve(writeToPath))) || _legacy2().WORKSPACE_ROOT_DIR : this.consumer.composeRelativeComponentPath(component.id);
327
344
  // components can't be saved with multiple versions, so we can ignore the version to find the component in bit.map
328
345
  const existingComponentMap = this.consumer?.bitMap.getComponentIfExist(component.id, {
329
346
  ignoreVersion: true
330
347
  });
348
+ // a component already tracked at the root is written there whatever path was derived above, e.g. by
349
+ // a checkout or a re-import, so the guards of the root run for it as well
350
+ if (componentRootDir === _legacy2().WORKSPACE_ROOT_DIR || existingComponentMap?.rootDir === _legacy2().WORKSPACE_ROOT_DIR) {
351
+ this.throwForNonWorkspaceRootComponent(component);
352
+ // the symlink rule is about where a write lands, and --track-only writes nothing (skipWritingToFs)
353
+ if (!opts.skipWritingToFs) this.throwForSymlinksInTheWay(component, opts.writeConfig);
354
+ }
331
355
  // with --write-to-empty-dir, dir-conflict resolution is deferred to relocateOccupiedDirs() so it runs after the
332
356
  // fixDirs* passes (which may still adjust writeToPath); otherwise fail here when the target dir is occupied.
333
- if (this.consumer && !opts.writeToEmptyDir) {
334
- this.throwErrorWhenDirectoryNotEmpty(componentRootDir, existingComponentMap, opts);
357
+ // the workspace root is never relocated (see relocateOccupiedDirs), so its own check runs either way.
358
+ if (this.consumer && (!opts.writeToEmptyDir || componentRootDir === _legacy2().WORKSPACE_ROOT_DIR)) {
359
+ this.throwErrorWhenDirectoryNotEmpty(component, componentRootDir, existingComponentMap, opts);
335
360
  }
336
361
  return {
337
362
  workspace: this.workspace,
@@ -343,9 +368,18 @@ class ComponentWriterMain {
343
368
  existingComponentMap: existingComponentMap ?? undefined
344
369
  };
345
370
  }
371
+ /**
372
+ * where this component was asked to go, if anywhere: its own entry in writeToPathPerId, else the
373
+ * writeToPath of the whole batch.
374
+ */
375
+ getWriteToPath(component, opts) {
376
+ return opts.writeToPathPerId?.[component.id.toStringWithoutVersion()] || opts.writeToPath;
377
+ }
346
378
  moveComponentsIfNeeded(opts) {
347
- if (opts.writeToPath && this.consumer) {
379
+ if (this.consumer) {
348
380
  opts.components.forEach(component => {
381
+ const writeToPath = this.getWriteToPath(component, opts);
382
+ if (!writeToPath) return;
349
383
  const componentMap = component.componentMap;
350
384
  if (!componentMap.rootDir) {
351
385
  throw new (_bitError().BitError)(`unable to use "--path" flag.
@@ -356,8 +390,14 @@ to move all component files to a different directory, run bit remove and then bi
356
390
  // @ts-ignore relativeWrittenPath is set at this point
357
391
  const absoluteWrittenPath = this.consumer.toAbsolutePath(relativeWrittenPath);
358
392
  // @ts-ignore this.writeToPath is set at this point
359
- const absoluteWriteToPath = path().resolve(opts.writeToPath); // don't use consumer.toAbsolutePath, it might be an inner dir
393
+ const absoluteWriteToPath = path().resolve(writeToPath); // don't use consumer.toAbsolutePath, it might be an inner dir
360
394
  if (relativeWrittenPath && absoluteWrittenPath !== absoluteWriteToPath) {
395
+ // a component tracked at the workspace root is the workspace. moving it schedules the removal
396
+ // of the directory it leaves, which there is the workspace tree (see moveExistingComponent)
397
+ if (componentMap.rootDir === _legacy2().WORKSPACE_ROOT_DIR) {
398
+ throw new (_bitError().BitError)(`unable to write "${component.id.toString()}" to "${writeToPath}", it is tracked at the workspace root, which is the workspace itself.
399
+ run "bit remove ${component.id.toStringWithoutVersion()}" first if the workspace should stop tracking its root`);
400
+ }
361
401
  this.mover.moveExistingComponent(component, absoluteWrittenPath, absoluteWriteToPath);
362
402
  }
363
403
  });
@@ -367,17 +407,114 @@ to move all component files to a different directory, run bit remove and then bi
367
407
  * true when the directory-conflict check can be skipped: either nothing is written to the filesystem, or the
368
408
  * target directory already belongs to this exact component (so overriding it in place is safe).
369
409
  */
370
- shouldSkipDirConflictCheck(componentDirRelative, componentMap, opts) {
410
+ shouldSkipDirConflictCheck(component, componentDirRelative, componentMap, opts) {
371
411
  if (opts.skipWritingToFs) return true;
372
412
  if (!componentMap) return false;
373
413
  // no writeToPath: it goes to the default directory. an existing componentMap means the component is not new.
374
- if (!opts.writeToPath) return true;
414
+ if (!this.getWriteToPath(component, opts)) return true;
375
415
  // writeToPath specified and that directory is already used for that component. compare against the
376
416
  // normalized componentDirRelative (not the raw opts.writeToPath, which may be absolute/OS-specific).
377
417
  return componentMap.rootDir === componentDirRelative;
378
418
  }
379
- throwErrorWhenDirectoryNotEmpty(componentDirRelative, componentMap, opts) {
380
- if (this.shouldSkipDirConflictCheck(componentDirRelative, componentMap, opts)) return;
419
+
420
+ /**
421
+ * a workspace-root component's files land in the workspace tree itself, where a path may be a
422
+ * symbolic link the user made - a directory on the way, or the destination itself. a write through
423
+ * it would land the file wherever the link points, so every existing path on the way to an incoming
424
+ * file has to be real. this is about where the write goes, not what it replaces, so --override does
425
+ * not waive it (it waives the conflict check, which is the other place the destination is looked at).
426
+ */
427
+ /**
428
+ * the incoming files a write would actually land at the workspace root. a component nested in the
429
+ * root owns its own directory, and populateFilesToWriteToComponentDir leaves those files alone - so
430
+ * the checks below must not reject an import over a path it would never touch. an older version of
431
+ * the root, snapped before that component was extracted out of it, still carries them.
432
+ */
433
+ filesThatWouldLand(component) {
434
+ const nestedRootDirs = this.consumer.bitMap.getNestedRootDirs(_legacy2().WORKSPACE_ROOT_DIR);
435
+ return component.files.filter(file => {
436
+ const relativePath = (0, _legacy().pathNormalizeToLinux)(file.relative);
437
+ // the live map is never written from a versioned copy either, so a workspace whose own .bitmap
438
+ // is a symbolic link must not fail an import over a file that would not be touched
439
+ if ((0, _legacy2().isWorkspaceMapFile)(relativePath)) return false;
440
+ return !(0, _componentWriter().isOwnedByNestedComponent)(relativePath, nestedRootDirs);
441
+ });
442
+ }
443
+ throwForSymlinksInTheWay(component, writeConfig) {
444
+ const pathsInTheWay = new Set();
445
+ const landing = this.filesThatWouldLand(component).map(file => (0, _legacy().pathNormalizeToLinux)(file.relative));
446
+ // the config file is generated rather than versioned, so it is not among the component's files -
447
+ // it still lands at the root, and this rule is about where a write goes. the flag the caller
448
+ // passed does not settle whether it lands: the writer turns config writing on by itself when a
449
+ // config file is already at the rootDir (see populateComponentsFilesToWrite), which a symlink
450
+ // pointing at an existing file reads as. it is looked up the same way, so a broken one - which
451
+ // the writer would not write through either - does not fail the write for nothing.
452
+ if (writeConfig || _fsExtra().default.existsSync(this.consumer.toAbsolutePath(_legacy3().COMPONENT_CONFIG_FILE_NAME))) {
453
+ landing.push(_legacy3().COMPONENT_CONFIG_FILE_NAME);
454
+ }
455
+ landing.forEach(relativePath => {
456
+ const segments = relativePath.split('/');
457
+ segments.forEach((_, index) => pathsInTheWay.add(segments.slice(0, index + 1).join('/')));
458
+ });
459
+ pathsInTheWay.forEach(pathInTheWay => {
460
+ const stat = lstatIfExists(this.consumer.toAbsolutePath(pathInTheWay));
461
+ if (!stat?.isSymbolicLink()) return;
462
+ throw new (_bitError().BitError)(`unable to write "${component.id.toString()}" to the workspace root, "${pathInTheWay}" is a symbolic link and the files would be written through it`);
463
+ });
464
+ }
465
+
466
+ /**
467
+ * only a workspace-root component may be written to ".". any other component written there would own
468
+ * every unclaimed file in the workspace from the next scan on, and drop out of install and link. a
469
+ * workspace-root component is told by the marker its versions carry (see WorkspaceRootData) - a
470
+ * .bitmap among its files is not enough, a component snapped before maps were excluded from
471
+ * component scans may carry one.
472
+ */
473
+ throwForNonWorkspaceRootComponent(component) {
474
+ if ((0, _workspaceRoot().isWorkspaceRootComponent)(component.extensions)) return;
475
+ throw new (_bitError().BitError)(`unable to import "${component.id.toString()}" to the workspace root, it is not a workspace-root component. use --path to write it to a directory`);
476
+ }
477
+
478
+ /**
479
+ * the workspace root is never empty - it holds .bit, .bitmap and workspace.jsonc - so "not empty"
480
+ * says nothing about a conflict there. the target is only reachable for a workspace-root component.
481
+ * restoring a git-free workspace from its scope starts from `bit init`, and the root files are meant
482
+ * to land on top of the ones it generated. every other existing file at the root is the user's own,
483
+ * whether or not the workspace tracks components yet, so overwriting it takes --override like any
484
+ * other occupied directory. a file identical to its incoming copy is not overwritten in any sense
485
+ * that matters, and this is what lets the files `bit init` generates (agent instructions, mcp config)
486
+ * meet their own versioned copies. workspace.jsonc is the exception: the freshly initialized one is
487
+ * meant to be replaced by the versioned one - and only while the map is still empty, which is what
488
+ * `bit init` leaves behind. once the workspace tracks a component the file is the user's own like
489
+ * any other, whichever component that is: the exemption is about what `bit init` just wrote, not
490
+ * about who owns the root.
491
+ */
492
+ throwForOccupiedWorkspaceRoot(component, opts) {
493
+ if (!opts.throwForExistingDir) return;
494
+ const isFreshWorkspace = !this.consumer.bitMap.components.length;
495
+ const generatedByInit = isFreshWorkspace ? [_legacy3().WORKSPACE_JSONC] : [];
496
+ const filesToOverwrite = this.filesThatWouldLand(component).filter(file => {
497
+ const relativePath = (0, _legacy().pathNormalizeToLinux)(file.relative);
498
+ if (generatedByInit.includes(relativePath)) return false;
499
+ const absolutePath = this.consumer.toAbsolutePath(relativePath);
500
+ // lstat rather than exists: a symlink in the way, dangling or not, is a conflict and not a path
501
+ // to write through, and so is a directory. only a regular file is compared with the incoming copy.
502
+ const stat = lstatIfExists(absolutePath);
503
+ if (!stat) return false;
504
+ if (!stat.isFile()) return true;
505
+ // compared byte for byte through latin1, which maps each byte to one character. Buffer.equals is
506
+ // avoided because its signature differs between @types/node majors, and an aspect build type-checks
507
+ // this file with whichever version its capsule resolves.
508
+ return _fsExtra().default.readFileSync(absolutePath, 'latin1') !== file.contents.toString('latin1');
509
+ }).map(file => (0, _legacy().pathNormalizeToLinux)(file.relative));
510
+ if (!filesToOverwrite.length) return;
511
+ const shown = filesToOverwrite.slice(0, 10).join(', ');
512
+ const rest = filesToOverwrite.length > 10 ? ` and ${filesToOverwrite.length - 10} more` : '';
513
+ throw new (_bitError().BitError)(`unable to import "${component.id.toString()}" to the workspace root, it would overwrite ${shown}${rest}.
514
+ use --override to overwrite them`);
515
+ }
516
+ throwErrorWhenDirectoryNotEmpty(component, componentDirRelative, componentMap, opts) {
517
+ if (this.shouldSkipDirConflictCheck(component, componentDirRelative, componentMap, opts)) return;
381
518
  const componentDir = this.consumer.toAbsolutePath(componentDirRelative);
382
519
  if (!_fsExtra().default.pathExistsSync(componentDir)) return;
383
520
  if (!componentMap) {
@@ -390,6 +527,10 @@ either use --path to specify a different directory or modify "defaultDirectory"
390
527
  if (!(0, _legacy().isDir)(componentDir)) {
391
528
  throw new (_bitError().BitError)(`unable to import to ${componentDir} because it's a file`);
392
529
  }
530
+ if (componentDirRelative === _legacy2().WORKSPACE_ROOT_DIR) {
531
+ this.throwForOccupiedWorkspaceRoot(component, opts);
532
+ return;
533
+ }
393
534
  if (!(0, _legacy().isDirEmptySync)(componentDir) && opts.throwForExistingDir) {
394
535
  throw new (_bitError().BitError)(`unable to import to ${componentDir}, the directory is not empty. use --override flag to delete the directory and then import`);
395
536
  }
@@ -411,7 +552,10 @@ either use --path to specify a different directory or modify "defaultDirectory"
411
552
  componentWriterInstances.forEach(componentWriter => {
412
553
  const currentDir = componentWriter.writeToPath;
413
554
  const componentMap = componentWriter.existingComponentMap;
414
- if (this.shouldSkipDirConflictCheck(currentDir, componentMap, opts)) return;
555
+ // the workspace root is a target only for a workspace-root component, and "._1" is not the
556
+ // workspace root. its conflicts are handled by throwForOccupiedWorkspaceRoot.
557
+ if (currentDir === _legacy2().WORKSPACE_ROOT_DIR) return;
558
+ if (this.shouldSkipDirConflictCheck(componentWriter.component, currentDir, componentMap, opts)) return;
415
559
  const unavailableReason = this.getDirUnavailableReason(currentDir, componentMap);
416
560
  if (!unavailableReason) return;
417
561
  let num = 1;
@@ -465,5 +609,13 @@ function incrementPathRecursively(p, allPaths) {
465
609
  }
466
610
  return newPath;
467
611
  }
612
+ function lstatIfExists(absolutePath) {
613
+ try {
614
+ return _fsExtra().default.lstatSync(absolutePath);
615
+ } catch (err) {
616
+ if (err.code === 'ENOENT') return undefined;
617
+ throw err;
618
+ }
619
+ }
468
620
 
469
621
  //# sourceMappingURL=component-writer.main.runtime.js.map