@teambit/objects 0.0.0-420215afca7cec9ac6474c9228f933bbe7f69a08 → 0.0.0-4263b1ed64ef563e8ee21f07834766d925c08898

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.
@@ -738,8 +738,8 @@ export default class Component extends BitObject {
738
738
  else
739
739
  throw new Error(`unable to add a new version for "${this.id()}" on main.
740
740
  this version started from an older version (${previouslyUsedVersion}), and not from the head (${head}).
741
- if this is done intentionally, please re-run with --detach-head (or --override-head if available).
742
- otherwise, please run "bit checkout head" to be up to date, then snap/tag your changes.`);
741
+ please run "bit checkout head" to be up to date, then snap/tag your changes.
742
+ if this is done intentionally, you can use --detach-head (or --override-head if available), but make sure you understand the implications as this is an experimental feature that may not be fully stable.`);
743
743
  } else {
744
744
  this.setHead(version.hash());
745
745
  this.detachedHeads.clearCurrent();
@@ -1205,6 +1205,27 @@ consider using --ignore-missing-artifacts flag if you're sure the artifacts are
1205
1205
  await this.setDivergeData(repo, undefined, undefined, workspaceId);
1206
1206
  const divergeData = this.getDivergeData();
1207
1207
  const localHashes = divergeData.snapsOnSourceOnly;
1208
+
1209
+ // When there's a detached head, divergeData only includes the detached head lineage.
1210
+ // We also need to include unexported versions from the main head lineage.
1211
+ const hasDetachedHead = this.detachedHeads && this.detachedHeads.getAllHeads().length > 0;
1212
+ if (hasDetachedHead && this.head) {
1213
+ // Calculate divergence from the main head as well
1214
+ const mainHeadDivergeData = await getDivergeData({
1215
+ repo,
1216
+ modelComponent: this,
1217
+ targetHead: (this.laneId ? this.calculatedRemoteHeadWhenOnLane : this.remoteHead) || null,
1218
+ sourceHead: this.head,
1219
+ throws: false,
1220
+ });
1221
+ // Add main head local versions that aren't already in localHashes
1222
+ for (const hash of mainHeadDivergeData.snapsOnSourceOnly) {
1223
+ if (!localHashes.find((h) => h.isEqual(hash))) {
1224
+ localHashes.push(hash);
1225
+ }
1226
+ }
1227
+ }
1228
+
1208
1229
  if (!localHashes.length) return [];
1209
1230
  return localHashes.reverse(); // reverse to get the older first
1210
1231
  }
@@ -67,21 +67,13 @@ describe('Version', () => {
67
67
  it('dependencies should be an array', () => {
68
68
  expect(dependencies).to.be.an('array').and.have.lengthOf(1);
69
69
  });
70
- it('dependencies should have properties id and relativePaths only', () => {
70
+ it('dependencies should have id property only (relativePaths removed)', () => {
71
71
  expect(dependencies[0]).to.haveOwnProperty('id');
72
- expect(dependencies[0]).to.haveOwnProperty('relativePaths');
72
+ expect(dependencies[0]).to.not.haveOwnProperty('relativePaths');
73
73
  expect(dependencies[0]).to.not.haveOwnProperty('nonExistProperty');
74
- expect(Object.keys(dependencies[0])).to.have.lengthOf(2);
75
- });
76
- it('relativePaths should be an array', () => {
77
- expect(dependencies[0].relativePaths).to.be.an('array').and.have.lengthOf(1);
78
- });
79
- it('relativePaths should have properties sourceRelativePath and destinationRelativePath only', () => {
80
- expect(dependencies[0].relativePaths[0]).to.haveOwnProperty('sourceRelativePath');
81
- expect(dependencies[0].relativePaths[0]).to.haveOwnProperty('destinationRelativePath');
82
- expect(dependencies[0].relativePaths[0]).to.not.haveOwnProperty('nonExistProperty');
83
- expect(Object.keys(dependencies[0].relativePaths[0])).to.have.lengthOf(2);
74
+ expect(Object.keys(dependencies[0])).to.have.lengthOf(1);
84
75
  });
76
+ // relativePaths tests removed - no longer included in Version.id() hash for Harmony components
85
77
  });
86
78
  });
87
79
  describe('hash()', () => {
package/models/version.ts CHANGED
@@ -231,19 +231,11 @@ export default class Version extends BitObject {
231
231
  id() {
232
232
  const obj = this.toObject();
233
233
 
234
- // @todo: remove the entire dependencies.relativePaths from the ID (it's going to be a breaking change)
235
234
  const getDependencies = (deps: Dependencies) => {
236
235
  const clonedDependencies = deps.cloneAsString();
237
- // @ts-ignore AUTO-ADDED-AFTER-MIGRATION-PLEASE-FIX!
238
- return clonedDependencies.map((dependency: Dependency) => {
236
+ return clonedDependencies.map((dependency) => {
239
237
  return {
240
238
  id: dependency.id,
241
- relativePaths: dependency.relativePaths.map((relativePath) => {
242
- return {
243
- sourceRelativePath: relativePath.sourceRelativePath,
244
- destinationRelativePath: relativePath.destinationRelativePath,
245
- };
246
- }),
247
239
  };
248
240
  });
249
241
  };
@@ -2,6 +2,7 @@ import tarStream from 'tar-stream';
2
2
  import { pMapPool } from '@teambit/toolbox.promise.map-pool';
3
3
  import { compact } from 'lodash';
4
4
  import { Readable, PassThrough, pipeline } from 'stream';
5
+ import crypto from 'crypto';
5
6
  import BitObject from './object';
6
7
  import { BitObjectList } from './bit-object-list';
7
8
  import Ref from './ref';
@@ -52,6 +53,19 @@ export class ObjectList {
52
53
  return this.objects.length;
53
54
  }
54
55
 
56
+ /**
57
+ * Generates a SHA1 hash from all object buffers.
58
+ * Used to identify duplicate export requests during retries.
59
+ * Performance wise, it's not too bad. ~98ms for 150 components on CircleCI.
60
+ */
61
+ getSha1Hash(): string {
62
+ const hash = crypto.createHash('sha1');
63
+ for (const obj of this.objects) {
64
+ hash.update(new Uint8Array(obj.buffer));
65
+ }
66
+ return hash.digest('hex');
67
+ }
68
+
55
69
  static mergeMultipleInstances(objectLists: ObjectList[]): ObjectList {
56
70
  const objectList = new ObjectList();
57
71
  objectLists.forEach((objList) => objectList.mergeObjectList(objList));
package/objects/object.ts CHANGED
@@ -141,6 +141,7 @@ path: ${err.path}`);
141
141
  * prefer using `this.parseObject()`, unless it must be sync.
142
142
  */
143
143
  static parseSync(fileContents: Buffer): BitObject {
144
+ // @ts-ignore todo: fix after merging #9359
144
145
  const buffer = inflateSync(fileContents);
145
146
  return parse(buffer);
146
147
  }
@@ -22,12 +22,11 @@ import type { ObjectItem } from './object-list';
22
22
  import { ObjectList } from './object-list';
23
23
  import BitRawObject from './raw-object';
24
24
  import Ref from './ref';
25
- import type { ContentTransformer } from './repository-hooks';
26
- import { onPersist, onRead } from './repository-hooks';
27
25
  import type { InMemoryCache } from '@teambit/harmony.modules.in-memory-cache';
28
26
  import { getMaxSizeForObjects, createInMemoryCache } from '@teambit/harmony.modules.in-memory-cache';
29
27
  import { ScopeMeta, Lane, ModelComponent } from '../models';
30
28
 
29
+ type ContentTransformer = (content: Buffer) => Buffer;
31
30
  const OBJECTS_BACKUP_DIR = `${OBJECTS_DIR}.bak`;
32
31
  const TRASH_DIR = 'trash';
33
32
 
@@ -46,8 +45,8 @@ export default class Repository {
46
45
  constructor(scopePath: string, scopeJson: ScopeJson) {
47
46
  this.scopePath = scopePath;
48
47
  this.scopeJson = scopeJson;
49
- this.onRead = onRead(scopePath, scopeJson);
50
- this.onPersist = onPersist(scopePath, scopeJson);
48
+ this.onRead = (content: Buffer) => Repository.onPostObjectRead?.(content) || content;
49
+ this.onPersist = (content: Buffer) => Repository.onPreObjectPersist?.(content) || content;
51
50
  this.cache = createInMemoryCache({ maxSize: getMaxSizeForObjects() });
52
51
  }
53
52
 
@@ -90,6 +89,20 @@ export default class Repository {
90
89
 
91
90
  static onPostObjectsPersist: () => Promise<void>;
92
91
 
92
+ /**
93
+ * Hook for transforming content before objects are persisted to the filesystem.
94
+ * Note: This function cannot be async because it's used by the synchronous `loadSync` method
95
+ * which needs to maintain sync behavior for compatibility with existing code.
96
+ */
97
+ static onPreObjectPersist: (content: Buffer) => Buffer;
98
+
99
+ /**
100
+ * Hook for transforming content after objects are read from the filesystem.
101
+ * Note: This function cannot be async because it's used by the synchronous `loadSync` method
102
+ * which needs to maintain sync behavior for compatibility with existing code.
103
+ */
104
+ static onPostObjectRead: (content: Buffer) => Buffer;
105
+
93
106
  async reLoadScopeIndex() {
94
107
  this.scopeIndex = await this.loadOptionallyCreateScopeIndex();
95
108
  }
package/package.json CHANGED
@@ -1,63 +1,62 @@
1
1
  {
2
2
  "name": "@teambit/objects",
3
- "version": "0.0.0-420215afca7cec9ac6474c9228f933bbe7f69a08",
3
+ "version": "0.0.0-4263b1ed64ef563e8ee21f07834766d925c08898",
4
4
  "homepage": "https://bit.cloud/teambit/scope/objects",
5
5
  "main": "dist/index.js",
6
6
  "componentId": {
7
7
  "scope": "teambit.scope",
8
8
  "name": "objects",
9
- "version": "420215afca7cec9ac6474c9228f933bbe7f69a08"
9
+ "version": "4263b1ed64ef563e8ee21f07834766d925c08898"
10
10
  },
11
11
  "dependencies": {
12
- "@pnpm/dependency-path": "1001.1.0",
13
- "@pnpm/lockfile.types": "^1002.0.0",
12
+ "@pnpm/dependency-path": "1001.1.6",
13
+ "@pnpm/lockfile.types": "^1002.0.5",
14
14
  "semver": "7.7.1",
15
15
  "lodash": "4.17.21",
16
16
  "uuid": "8.3.2",
17
17
  "async-mutex": "0.3.1",
18
18
  "p-map-series": "2.1.0",
19
19
  "tar-stream": "2.2.0",
20
- "is-relative-path": "2.0.0",
21
20
  "fs-extra": "10.0.0",
22
21
  "uid-number": "0.0.6",
23
22
  "@teambit/harmony": "0.4.7",
23
+ "@teambit/cli": "0.0.1289",
24
24
  "@teambit/component-id": "1.2.4",
25
- "@teambit/legacy.utils": "0.0.23",
25
+ "@teambit/legacy.utils": "0.0.29",
26
+ "@teambit/harmony.modules.get-basic-log": "0.0.90",
26
27
  "@teambit/bit-error": "0.0.404",
27
28
  "@teambit/component-version": "1.0.4",
29
+ "@teambit/component.snap-distance": "0.0.90",
30
+ "@teambit/config-store": "0.0.169",
28
31
  "@teambit/lane-id": "0.0.312",
29
- "@teambit/legacy.cli.error": "0.0.24",
30
- "@teambit/legacy.constants": "0.0.14",
31
- "@teambit/legacy.logger": "0.0.24",
32
- "@teambit/toolbox.crypto.sha1": "0.0.7",
32
+ "@teambit/legacy.cli.error": "0.0.31",
33
+ "@teambit/legacy.constants": "0.0.20",
34
+ "@teambit/legacy.logger": "0.0.31",
35
+ "@teambit/legacy.scope": "0.0.89",
36
+ "@teambit/toolbox.crypto.sha1": "0.0.11",
37
+ "@teambit/component.sources": "0.0.141",
33
38
  "@teambit/legacy-bit-id": "1.1.3",
34
- "@teambit/legacy-component-log": "0.0.408",
35
- "@teambit/pkg.modules.semver-helper": "0.0.13",
39
+ "@teambit/legacy-component-log": "0.0.413",
40
+ "@teambit/legacy.consumer-component": "0.0.90",
41
+ "@teambit/legacy.consumer-config": "0.0.89",
42
+ "@teambit/legacy.extension-data": "0.0.91",
43
+ "@teambit/pkg.modules.semver-helper": "0.0.18",
36
44
  "@teambit/toolbox.array.duplications-finder": "0.0.3",
37
45
  "@teambit/graph.cleargraph": "0.0.11",
38
- "@teambit/bit.get-bit-version": "0.0.6",
39
- "@teambit/harmony.modules.concurrency": "0.0.15",
40
- "@teambit/toolbox.promise.map-pool": "0.0.6",
41
- "@teambit/harmony.modules.in-memory-cache": "0.0.17",
42
- "@teambit/toolbox.fs.remove-empty-dir": "0.0.5",
43
- "@teambit/cli": "0.0.0-caae57424b1508fa747a3dee4ebf0d3dea58d299",
44
- "@teambit/harmony.modules.get-basic-log": "0.0.0-31bee6d769fdb68b53e1061b305f2951b4896901",
45
- "@teambit/component.snap-distance": "0.0.0-e5ce840a4cc1c37d0d9ab05cdda957ca35ba1cfb",
46
- "@teambit/config-store": "0.0.0-507e0921c023fe811a89847dbdd405ca091badd8",
47
- "@teambit/legacy.scope": "0.0.0-3a16a8d0dfee5d75f435468844a824d3a2dcb99d",
48
- "@teambit/component.sources": "0.0.0-02419ba08b235e0f4bdb459c1894e03ed2381c5d",
49
- "@teambit/legacy.consumer-component": "0.0.0-4b1b0616a15195d07d8854f1ef490dd1ee9fdd82",
50
- "@teambit/legacy.consumer-config": "0.0.0-fdda55d0da29351c3477bd6616c7aac1cdb136a2",
51
- "@teambit/legacy.extension-data": "0.0.0-4eef6e6509d2baf2a66d7148aeaf1a7622cb2069",
52
- "@teambit/semantics.doc-parser": "0.0.0-f913c490db1567a221bfbfc240f90c062bb09e05",
53
- "@teambit/graph": "0.0.0-623bd10c15acd489c98faf81f5bef77c67ce7536"
46
+ "@teambit/bit.get-bit-version": "0.0.11",
47
+ "@teambit/semantics.doc-parser": "0.0.97",
48
+ "@teambit/harmony.modules.concurrency": "0.0.21",
49
+ "@teambit/toolbox.promise.map-pool": "0.0.10",
50
+ "@teambit/harmony.modules.in-memory-cache": "0.0.24",
51
+ "@teambit/toolbox.fs.remove-empty-dir": "0.0.9",
52
+ "@teambit/graph": "0.0.0-273fd9923d353a095e323ebd2f986f2e8ba6652f"
54
53
  },
55
54
  "devDependencies": {
56
55
  "@types/semver": "7.5.8",
57
56
  "@types/lodash": "4.14.165",
58
57
  "@types/uuid": "8.3.4",
59
58
  "@types/fs-extra": "9.0.7",
60
- "@teambit/harmony.envs.core-aspect-env": "0.0.75"
59
+ "@teambit/harmony.envs.core-aspect-env": "0.0.80"
61
60
  },
62
61
  "peerDependencies": {
63
62
  "chai": "5.2.1",
@@ -1,4 +0,0 @@
1
- import type { ScopeJson } from '@teambit/legacy.scope';
2
- export type ContentTransformer = (content: Buffer) => Buffer;
3
- export declare function onPersist(scopePath: string, scopeJson: ScopeJson): ContentTransformer;
4
- export declare function onRead(scopePath: string, scopeJson: ScopeJson): ContentTransformer;
@@ -1,56 +0,0 @@
1
- "use strict";
2
-
3
- Object.defineProperty(exports, "__esModule", {
4
- value: true
5
- });
6
- exports.onPersist = onPersist;
7
- exports.onRead = onRead;
8
- function _isRelativePath() {
9
- const data = _interopRequireDefault(require("is-relative-path"));
10
- _isRelativePath = function () {
11
- return data;
12
- };
13
- return data;
14
- }
15
- function _path() {
16
- const data = _interopRequireDefault(require("path"));
17
- _path = function () {
18
- return data;
19
- };
20
- return data;
21
- }
22
- function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
23
- function loadHooks(scopePath, scopeJson) {
24
- const hooksPath = scopeJson.hooksPath;
25
- if (hooksPath) {
26
- const hooksFinalPath = (0, _isRelativePath().default)(hooksPath) ? _path().default.join(scopePath, hooksPath) : hooksPath;
27
- // eslint-disable-next-line global-require, import/no-dynamic-require
28
- const hooks = require(hooksFinalPath);
29
- return hooks;
30
- }
31
- return undefined;
32
- }
33
- function onPersist(scopePath, scopeJson) {
34
- const defaultFunc = content => content;
35
- const hooks = loadHooks(scopePath, scopeJson);
36
- if (hooks) {
37
- const onReadFunction = hooks.onPersist;
38
- if (onReadFunction) {
39
- return onReadFunction;
40
- }
41
- }
42
- return defaultFunc;
43
- }
44
- function onRead(scopePath, scopeJson) {
45
- const defaultFunc = content => content;
46
- const hooks = loadHooks(scopePath, scopeJson);
47
- if (hooks) {
48
- const onReadFunction = hooks.onRead;
49
- if (onReadFunction) {
50
- return onReadFunction;
51
- }
52
- }
53
- return defaultFunc;
54
- }
55
-
56
- //# sourceMappingURL=repository-hooks.js.map
@@ -1 +0,0 @@
1
- {"version":3,"names":["_isRelativePath","data","_interopRequireDefault","require","_path","e","__esModule","default","loadHooks","scopePath","scopeJson","hooksPath","hooksFinalPath","isRelative","path","join","hooks","undefined","onPersist","defaultFunc","content","onReadFunction","onRead"],"sources":["repository-hooks.ts"],"sourcesContent":["import isRelative from 'is-relative-path';\nimport path from 'path';\n\nimport type { ScopeJson } from '@teambit/legacy.scope';\n\nexport type ContentTransformer = (content: Buffer) => Buffer;\n\nfunction loadHooks(scopePath: string, scopeJson: ScopeJson): any | undefined {\n const hooksPath = scopeJson.hooksPath;\n if (hooksPath) {\n const hooksFinalPath = isRelative(hooksPath) ? path.join(scopePath, hooksPath) : hooksPath;\n // eslint-disable-next-line global-require, import/no-dynamic-require\n const hooks = require(hooksFinalPath);\n return hooks;\n }\n return undefined;\n}\n\nexport function onPersist(scopePath: string, scopeJson: ScopeJson): ContentTransformer {\n const defaultFunc = (content) => content;\n const hooks = loadHooks(scopePath, scopeJson);\n if (hooks) {\n const onReadFunction = hooks.onPersist;\n if (onReadFunction) {\n return onReadFunction;\n }\n }\n return defaultFunc;\n}\n\nexport function onRead(scopePath: string, scopeJson: ScopeJson): ContentTransformer {\n const defaultFunc = (content) => content;\n\n const hooks = loadHooks(scopePath, scopeJson);\n if (hooks) {\n const onReadFunction = hooks.onRead;\n if (onReadFunction) {\n return onReadFunction;\n }\n }\n return defaultFunc;\n}\n"],"mappings":";;;;;;;AAAA,SAAAA,gBAAA;EAAA,MAAAC,IAAA,GAAAC,sBAAA,CAAAC,OAAA;EAAAH,eAAA,YAAAA,CAAA;IAAA,OAAAC,IAAA;EAAA;EAAA,OAAAA,IAAA;AAAA;AACA,SAAAG,MAAA;EAAA,MAAAH,IAAA,GAAAC,sBAAA,CAAAC,OAAA;EAAAC,KAAA,YAAAA,CAAA;IAAA,OAAAH,IAAA;EAAA;EAAA,OAAAA,IAAA;AAAA;AAAwB,SAAAC,uBAAAG,CAAA,WAAAA,CAAA,IAAAA,CAAA,CAAAC,UAAA,GAAAD,CAAA,KAAAE,OAAA,EAAAF,CAAA;AAMxB,SAASG,SAASA,CAACC,SAAiB,EAAEC,SAAoB,EAAmB;EAC3E,MAAMC,SAAS,GAAGD,SAAS,CAACC,SAAS;EACrC,IAAIA,SAAS,EAAE;IACb,MAAMC,cAAc,GAAG,IAAAC,yBAAU,EAACF,SAAS,CAAC,GAAGG,eAAI,CAACC,IAAI,CAACN,SAAS,EAAEE,SAAS,CAAC,GAAGA,SAAS;IAC1F;IACA,MAAMK,KAAK,GAAGb,OAAO,CAACS,cAAc,CAAC;IACrC,OAAOI,KAAK;EACd;EACA,OAAOC,SAAS;AAClB;AAEO,SAASC,SAASA,CAACT,SAAiB,EAAEC,SAAoB,EAAsB;EACrF,MAAMS,WAAW,GAAIC,OAAO,IAAKA,OAAO;EACxC,MAAMJ,KAAK,GAAGR,SAAS,CAACC,SAAS,EAAEC,SAAS,CAAC;EAC7C,IAAIM,KAAK,EAAE;IACT,MAAMK,cAAc,GAAGL,KAAK,CAACE,SAAS;IACtC,IAAIG,cAAc,EAAE;MAClB,OAAOA,cAAc;IACvB;EACF;EACA,OAAOF,WAAW;AACpB;AAEO,SAASG,MAAMA,CAACb,SAAiB,EAAEC,SAAoB,EAAsB;EAClF,MAAMS,WAAW,GAAIC,OAAO,IAAKA,OAAO;EAExC,MAAMJ,KAAK,GAAGR,SAAS,CAACC,SAAS,EAAEC,SAAS,CAAC;EAC7C,IAAIM,KAAK,EAAE;IACT,MAAMK,cAAc,GAAGL,KAAK,CAACM,MAAM;IACnC,IAAID,cAAc,EAAE;MAClB,OAAOA,cAAc;IACvB;EACF;EACA,OAAOF,WAAW;AACpB","ignoreList":[]}
@@ -1,42 +0,0 @@
1
- import isRelative from 'is-relative-path';
2
- import path from 'path';
3
-
4
- import type { ScopeJson } from '@teambit/legacy.scope';
5
-
6
- export type ContentTransformer = (content: Buffer) => Buffer;
7
-
8
- function loadHooks(scopePath: string, scopeJson: ScopeJson): any | undefined {
9
- const hooksPath = scopeJson.hooksPath;
10
- if (hooksPath) {
11
- const hooksFinalPath = isRelative(hooksPath) ? path.join(scopePath, hooksPath) : hooksPath;
12
- // eslint-disable-next-line global-require, import/no-dynamic-require
13
- const hooks = require(hooksFinalPath);
14
- return hooks;
15
- }
16
- return undefined;
17
- }
18
-
19
- export function onPersist(scopePath: string, scopeJson: ScopeJson): ContentTransformer {
20
- const defaultFunc = (content) => content;
21
- const hooks = loadHooks(scopePath, scopeJson);
22
- if (hooks) {
23
- const onReadFunction = hooks.onPersist;
24
- if (onReadFunction) {
25
- return onReadFunction;
26
- }
27
- }
28
- return defaultFunc;
29
- }
30
-
31
- export function onRead(scopePath: string, scopeJson: ScopeJson): ContentTransformer {
32
- const defaultFunc = (content) => content;
33
-
34
- const hooks = loadHooks(scopePath, scopeJson);
35
- if (hooks) {
36
- const onReadFunction = hooks.onRead;
37
- if (onReadFunction) {
38
- return onReadFunction;
39
- }
40
- }
41
- return defaultFunc;
42
- }