screw-up 1.31.0 → 1.32.0

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.
Files changed (34) hide show
  1. package/dist/index.cjs +503 -132
  2. package/dist/index.cjs.map +1 -1
  3. package/dist/index.mjs +4 -4
  4. package/dist/main.cjs +519 -148
  5. package/dist/main.cjs.map +1 -1
  6. package/dist/main.mjs +6 -6
  7. package/dist/{metadata-file-BWd04LhD.js → metadata-file-D79yMa_A.js} +500 -128
  8. package/dist/metadata-file-D79yMa_A.js.map +1 -0
  9. package/dist/{packageMetadata-ip0rBTwa.cjs → packageMetadata-6po5LHyH.cjs} +5 -5
  10. package/dist/{packageMetadata-ip0rBTwa.cjs.map → packageMetadata-6po5LHyH.cjs.map} +1 -1
  11. package/dist/{packageMetadata-BDGBM3Fx.cjs → packageMetadata-Cwh4Fqmw.cjs} +3 -3
  12. package/dist/{packageMetadata-BsMXJpMH.js → packageMetadata-Sm2NpI2b.js} +6 -6
  13. package/dist/{packageMetadata-BsMXJpMH.js.map → packageMetadata-Sm2NpI2b.js.map} +1 -1
  14. package/dist/src/analyzer.d.ts +2 -2
  15. package/dist/src/analyzer.d.ts.map +1 -1
  16. package/dist/src/cli-internal.d.ts +2 -2
  17. package/dist/src/cli.d.ts +2 -2
  18. package/dist/src/declaration-import-fix.d.ts +2 -2
  19. package/dist/src/default-import-fix.d.ts +2 -2
  20. package/dist/src/fast-tags.d.ts +2 -2
  21. package/dist/src/fast-tags.d.ts.map +1 -1
  22. package/dist/src/generated/packageMetadata.d.ts +4 -4
  23. package/dist/src/git-operations.d.ts +2 -2
  24. package/dist/src/git-ref-utils.d.ts +16 -2
  25. package/dist/src/git-ref-utils.d.ts.map +1 -1
  26. package/dist/src/index.d.ts +2 -2
  27. package/dist/src/internal.d.ts +2 -2
  28. package/dist/src/main.d.ts +2 -2
  29. package/dist/src/metadata-file.d.ts +2 -2
  30. package/dist/src/text-edits.d.ts +2 -2
  31. package/dist/src/types.d.ts +2 -2
  32. package/dist/src/vite-plugin.d.ts +2 -2
  33. package/package.json +7 -7
  34. package/dist/metadata-file-BWd04LhD.js.map +0 -1
@@ -1,18 +1,20 @@
1
1
  /*!
2
2
  * name: screw-up
3
- * version: 1.31.0
3
+ * version: 1.32.0
4
4
  * description: Simply package metadata inserter on Vite plugin
5
5
  * author: Kouji Matsui (@kekyo@mi.kekyo.net)
6
6
  * license: MIT
7
7
  * repository.url: https://github.com/kekyo/screw-up.git
8
- * git.commit.hash: ebb41ebf06ebe1bec39a3770c70a62cb95b4b7d6
8
+ * git.commit.hash: 8a0078c34fa41bdb0cbf2d23837ac5e3217cbf53
9
9
  */
10
- import fs, { mkdir, readFile, readdir, stat, writeFile } from "fs/promises";
10
+ import fs, { mkdir, open, readFile, readdir, stat, writeFile } from "fs/promises";
11
11
  import { existsSync } from "fs";
12
12
  import { basename, dirname, isAbsolute, join } from "path";
13
13
  import { glob } from "glob";
14
14
  import * as git from "isomorphic-git";
15
15
  import __screwUpDefaultImportModule0 from "isomorphic-git";
16
+ import { createHash } from "crypto";
17
+ import { inflateSync } from "zlib";
16
18
  //#region \0rolldown/runtime.js
17
19
  var __create = Object.create;
18
20
  var __defProp = Object.defineProperty;
@@ -1506,10 +1508,10 @@ var require_dayjs_min = /* @__PURE__ */ __commonJSMin(((exports, module) => {
1506
1508
  //#region src/internal.ts
1507
1509
  var import_dist = /* @__PURE__ */ __toESM(require_dist(), 1);
1508
1510
  var import_dayjs_min = /* @__PURE__ */ __toESM(require_dayjs_min(), 1);
1509
- var JSON5 = __resolveDefaultExport$3(import_dist.default, false);
1510
- var dayjs$1 = __resolveDefaultExport$3(import_dayjs_min.default, false);
1511
+ var JSON5 = __resolveDefaultExport$2(import_dist.default, false);
1512
+ var dayjs$1 = __resolveDefaultExport$2(import_dayjs_min.default, false);
1511
1513
  globalThis.__screwUpIsInCJS_db7919f73ec9 = false;
1512
- function __resolveDefaultExport$3(module, isESM) {
1514
+ function __resolveDefaultExport$2(module, isESM) {
1513
1515
  const __isInCJS = typeof globalThis !== "undefined" && globalThis.__screwUpIsInCJS_db7919f73ec9 === true;
1514
1516
  const maybe = module;
1515
1517
  const hasDefault = !!(maybe && typeof maybe === "object" && "default" in maybe);
@@ -1879,26 +1881,16 @@ var resolveRawPackageJsonObject = async (projectRoot, fetchGitMetadata, alwaysOv
1879
1881
  };
1880
1882
  //#endregion
1881
1883
  //#region src/git-ref-utils.ts
1882
- var git$2 = __resolveDefaultExport$2(__screwUpDefaultImportModule0, false);
1883
- globalThis.__screwUpIsInCJS_89cc61422477 = false;
1884
- function __resolveDefaultExport$2(module, isESM) {
1885
- const __isInCJS = typeof globalThis !== "undefined" && globalThis.__screwUpIsInCJS_89cc61422477 === true;
1886
- const maybe = module;
1887
- const hasDefault = !!(maybe && typeof maybe === "object" && "default" in maybe);
1888
- const unwrapNamespaceDefault = (value) => {
1889
- if (!value || typeof value !== "object") return value;
1890
- const inner = value;
1891
- if ((inner.__esModule === true || typeof Symbol !== "undefined" && inner[Symbol.toStringTag] === "Module") && "default" in inner) return inner.default;
1892
- return value;
1893
- };
1894
- const resolvedDefault = hasDefault ? unwrapNamespaceDefault(maybe.default) : void 0;
1895
- if (__isInCJS) return hasDefault ? resolvedDefault !== null && resolvedDefault !== void 0 ? resolvedDefault : module : module;
1896
- if (isESM) {
1897
- if (hasDefault) return resolvedDefault;
1898
- throw new Error("Default export not found.");
1899
- }
1900
- return hasDefault ? resolvedDefault !== null && resolvedDefault !== void 0 ? resolvedDefault : module : module;
1901
- }
1884
+ var PACK_TRAILER_SIZE = 20;
1885
+ var LOOSE_TAG_RESOLUTION_CONCURRENCY = 4;
1886
+ var PACKED_OBJECT_TYPE_BY_CODE = new Map([
1887
+ [1, "commit"],
1888
+ [2, "tree"],
1889
+ [3, "blob"],
1890
+ [4, "tag"],
1891
+ [6, "ofs-delta"],
1892
+ [7, "ref-delta"]
1893
+ ]);
1902
1894
  /**
1903
1895
  * Resolve the actual Git directory for repositories, worktrees, and submodules.
1904
1896
  * @param repoPath - Repository path
@@ -1912,24 +1904,354 @@ var getActualGitDir = async (repoPath) => {
1912
1904
  if (!match) return gitDir;
1913
1905
  return isAbsolute(match[1]) ? match[1] : join(repoPath, match[1]);
1914
1906
  };
1907
+ var readFixedRange = async (fileHandle, offset, length) => {
1908
+ const buffer = Buffer.alloc(length);
1909
+ const { bytesRead } = await fileHandle.read(buffer, 0, length, offset);
1910
+ if (bytesRead !== length) throw new Error(`Unexpected EOF while reading pack entry at offset ${offset} (expected ${length}, got ${bytesRead})`);
1911
+ return buffer;
1912
+ };
1913
+ var readLooseObject = async (gitDir, oid) => {
1914
+ try {
1915
+ const wrapped = inflateSync(await readFile(join(gitDir, "objects", oid.slice(0, 2), oid.slice(2))));
1916
+ const headerEnd = wrapped.indexOf(0);
1917
+ if (headerEnd < 0) throw new Error(`Invalid loose object header: ${oid}`);
1918
+ const header = wrapped.subarray(0, headerEnd).toString("utf-8");
1919
+ const match = header.match(/^(commit|tree|blob|tag) (\d+)$/);
1920
+ if (!match) throw new Error(`Unsupported loose object header: ${header}`);
1921
+ const content = wrapped.subarray(headerEnd + 1);
1922
+ const expectedSize = Number(match[2]);
1923
+ if (content.length !== expectedSize) throw new Error(`Loose object size mismatch: ${oid} (expected ${expectedSize}, got ${content.length})`);
1924
+ return {
1925
+ oid,
1926
+ type: match[1],
1927
+ content
1928
+ };
1929
+ } catch (error) {
1930
+ if (error.code === "ENOENT") return null;
1931
+ throw error;
1932
+ }
1933
+ };
1934
+ var readLargePackOffset = (idxBuffer, largeOffsetsStart, largeOffsetIndex) => {
1935
+ const offset = Number(idxBuffer.readBigUInt64BE(largeOffsetsStart + largeOffsetIndex * 8));
1936
+ if (!Number.isSafeInteger(offset)) throw new Error(`Pack offset exceeds safe integer range: ${offset}`);
1937
+ return offset;
1938
+ };
1939
+ var loadPackIndex = async (idxPath) => {
1940
+ const packPath = idxPath.replace(/\.idx$/, ".pack");
1941
+ const [idxBuffer, packStat, fileHandle] = await Promise.all([
1942
+ readFile(idxPath),
1943
+ stat(packPath),
1944
+ open(packPath, "r")
1945
+ ]);
1946
+ if (idxBuffer.readUInt32BE(0) !== 4285812579) throw new Error(`Unsupported pack index signature: ${idxPath}`);
1947
+ if (idxBuffer.readUInt32BE(4) !== 2) throw new Error(`Unsupported pack index version: ${idxPath}`);
1948
+ const objectCount = idxBuffer.readUInt32BE(1028);
1949
+ const oidStart = 1032;
1950
+ const offsetStart = oidStart + objectCount * 20 + objectCount * 4;
1951
+ const largeOffsetStart = offsetStart + objectCount * 4;
1952
+ const objectByOid = /* @__PURE__ */ new Map();
1953
+ const objectByOffset = /* @__PURE__ */ new Map();
1954
+ const sortedObjects = [];
1955
+ const packIndex = {
1956
+ fileHandle,
1957
+ objectByOid,
1958
+ objectByOffset
1959
+ };
1960
+ for (let index = 0; index < objectCount; index++) {
1961
+ const oidOffset = oidStart + index * 20;
1962
+ const oid = idxBuffer.subarray(oidOffset, oidOffset + 20).toString("hex");
1963
+ const rawOffset = idxBuffer.readUInt32BE(offsetStart + index * 4);
1964
+ const offset = (rawOffset & 2147483648) === 0 ? rawOffset : readLargePackOffset(idxBuffer, largeOffsetStart, rawOffset & 2147483647);
1965
+ sortedObjects.push({
1966
+ oid,
1967
+ offset
1968
+ });
1969
+ }
1970
+ sortedObjects.sort((left, right) => left.offset - right.offset);
1971
+ const packEndOffset = packStat.size - PACK_TRAILER_SIZE;
1972
+ for (let index = 0; index < sortedObjects.length; index++) {
1973
+ var _sortedObjects$offset, _sortedObjects;
1974
+ const currentObject = sortedObjects[index];
1975
+ const nextOffset = (_sortedObjects$offset = (_sortedObjects = sortedObjects[index + 1]) === null || _sortedObjects === void 0 ? void 0 : _sortedObjects.offset) !== null && _sortedObjects$offset !== void 0 ? _sortedObjects$offset : packEndOffset;
1976
+ const location = {
1977
+ oid: currentObject.oid,
1978
+ offset: currentObject.offset,
1979
+ nextOffset,
1980
+ packIndex
1981
+ };
1982
+ objectByOid.set(currentObject.oid, location);
1983
+ objectByOffset.set(currentObject.offset, location);
1984
+ }
1985
+ return packIndex;
1986
+ };
1987
+ var loadPackStore = async (gitDir) => {
1988
+ try {
1989
+ const packDir = join(gitDir, "objects", "pack");
1990
+ const idxPaths = (await readdir(packDir)).filter((entryName) => entryName.endsWith(".idx")).map((entryName) => join(packDir, entryName));
1991
+ const packs = await Promise.all(idxPaths.map(loadPackIndex));
1992
+ const objectByOid = /* @__PURE__ */ new Map();
1993
+ for (const pack of packs) for (const [oid, location] of pack.objectByOid.entries()) objectByOid.set(oid, location);
1994
+ return {
1995
+ packs,
1996
+ objectByOid
1997
+ };
1998
+ } catch (error) {
1999
+ if (error.code === "ENOENT") return {
2000
+ packs: [],
2001
+ objectByOid: /* @__PURE__ */ new Map()
2002
+ };
2003
+ throw error;
2004
+ }
2005
+ };
2006
+ var decodeOfsDeltaDistance = (buffer, startOffset) => {
2007
+ let cursor = startOffset;
2008
+ let byte = buffer[cursor++];
2009
+ let distance = byte & 127;
2010
+ while (byte & 128) {
2011
+ byte = buffer[cursor++];
2012
+ distance = distance + 1 << 7 | byte & 127;
2013
+ }
2014
+ return {
2015
+ distance,
2016
+ nextOffset: cursor
2017
+ };
2018
+ };
2019
+ var parsePackedEntryHeader = (entryBuffer, objectOffset) => {
2020
+ let cursor = 0;
2021
+ let byte = entryBuffer[cursor++];
2022
+ const packedType = PACKED_OBJECT_TYPE_BY_CODE.get(byte >> 4 & 7);
2023
+ if (!packedType) throw new Error(`Unsupported packed object type at offset ${objectOffset}`);
2024
+ let declaredSize = byte & 15;
2025
+ let shift = 4;
2026
+ while (byte & 128) {
2027
+ byte = entryBuffer[cursor++];
2028
+ declaredSize |= (byte & 127) << shift;
2029
+ shift += 7;
2030
+ }
2031
+ let baseOffset;
2032
+ let baseOid;
2033
+ if (packedType === "ofs-delta") {
2034
+ const decoded = decodeOfsDeltaDistance(entryBuffer, cursor);
2035
+ cursor = decoded.nextOffset;
2036
+ baseOffset = objectOffset - decoded.distance;
2037
+ } else if (packedType === "ref-delta") {
2038
+ baseOid = entryBuffer.subarray(cursor, cursor + 20).toString("hex");
2039
+ cursor += 20;
2040
+ }
2041
+ return {
2042
+ packedType,
2043
+ declaredSize,
2044
+ headerLength: cursor,
2045
+ baseOffset,
2046
+ baseOid
2047
+ };
2048
+ };
2049
+ var readDeltaSize = (buffer, startOffset) => {
2050
+ let cursor = startOffset;
2051
+ let size = 0;
2052
+ let shift = 0;
2053
+ while (cursor < buffer.length) {
2054
+ const byte = buffer[cursor++];
2055
+ size |= (byte & 127) << shift;
2056
+ if ((byte & 128) === 0) return {
2057
+ size,
2058
+ nextOffset: cursor
2059
+ };
2060
+ shift += 7;
2061
+ }
2062
+ throw new Error("Invalid git delta size encoding");
2063
+ };
2064
+ var applyGitDelta = (baseContent, deltaContent) => {
2065
+ const baseSizeInfo = readDeltaSize(deltaContent, 0);
2066
+ if (baseSizeInfo.size !== baseContent.length) throw new Error(`Git delta base size mismatch: expected ${baseSizeInfo.size}, got ${baseContent.length}`);
2067
+ const targetSizeInfo = readDeltaSize(deltaContent, baseSizeInfo.nextOffset);
2068
+ const result = Buffer.alloc(targetSizeInfo.size);
2069
+ let deltaOffset = targetSizeInfo.nextOffset;
2070
+ let resultOffset = 0;
2071
+ while (deltaOffset < deltaContent.length) {
2072
+ const opcode = deltaContent[deltaOffset++];
2073
+ if ((opcode & 128) !== 0) {
2074
+ let copyOffset = 0;
2075
+ let copySize = 0;
2076
+ if (opcode & 1) copyOffset |= deltaContent[deltaOffset++];
2077
+ if (opcode & 2) copyOffset |= deltaContent[deltaOffset++] << 8;
2078
+ if (opcode & 4) copyOffset |= deltaContent[deltaOffset++] << 16;
2079
+ if (opcode & 8) copyOffset |= deltaContent[deltaOffset++] << 24;
2080
+ if (opcode & 16) copySize |= deltaContent[deltaOffset++];
2081
+ if (opcode & 32) copySize |= deltaContent[deltaOffset++] << 8;
2082
+ if (opcode & 64) copySize |= deltaContent[deltaOffset++] << 16;
2083
+ if (copySize === 0) copySize = 65536;
2084
+ baseContent.copy(result, resultOffset, copyOffset, copyOffset + copySize);
2085
+ resultOffset += copySize;
2086
+ continue;
2087
+ }
2088
+ if (opcode === 0) throw new Error("Invalid git delta opcode");
2089
+ deltaContent.copy(result, resultOffset, deltaOffset, deltaOffset + opcode);
2090
+ deltaOffset += opcode;
2091
+ resultOffset += opcode;
2092
+ }
2093
+ if (resultOffset !== result.length) throw new Error(`Git delta size mismatch: expected ${result.length}, got ${resultOffset}`);
2094
+ return result;
2095
+ };
2096
+ var inflatePackedObject = (compressedContent) => Buffer.from(inflateSync(compressedContent));
2097
+ var parseTagTargetOid = (tagContent) => {
2098
+ const firstLineEnd = tagContent.indexOf(10);
2099
+ const firstLine = firstLineEnd >= 0 ? tagContent.subarray(0, firstLineEnd).toString("utf-8") : tagContent.toString("utf-8");
2100
+ const match = firstLine.match(/^object ([0-9a-f]{40})$/);
2101
+ if (!match) throw new Error(`Invalid annotated tag payload: ${firstLine}`);
2102
+ return match[1];
2103
+ };
2104
+ var parseTreeEntries = (treeContent) => {
2105
+ const entries = [];
2106
+ let offset = 0;
2107
+ while (offset < treeContent.length) {
2108
+ const modeEnd = treeContent.indexOf(32, offset);
2109
+ if (modeEnd < 0) throw new Error("Invalid tree entry mode");
2110
+ const nameEnd = treeContent.indexOf(0, modeEnd + 1);
2111
+ if (nameEnd < 0 || nameEnd + 21 > treeContent.length) throw new Error("Invalid tree entry name");
2112
+ entries.push({
2113
+ mode: treeContent.subarray(offset, modeEnd).toString("utf-8"),
2114
+ name: treeContent.subarray(modeEnd + 1, nameEnd).toString("utf-8"),
2115
+ oid: treeContent.subarray(nameEnd + 1, nameEnd + 21).toString("hex")
2116
+ });
2117
+ offset = nameEnd + 21;
2118
+ }
2119
+ return entries;
2120
+ };
2121
+ var createGitObjectResolver = async (repoPath) => {
2122
+ const actualGitDir = await getActualGitDir(repoPath);
2123
+ const resolvedObjects = /* @__PURE__ */ new Map();
2124
+ let packStorePromise;
2125
+ const getPackStore = async () => {
2126
+ if (!packStorePromise) packStorePromise = loadPackStore(actualGitDir);
2127
+ return packStorePromise;
2128
+ };
2129
+ const readPackedObject = async (location) => {
2130
+ var _location$packIndex$o, _location$packIndex$o2, _header$baseOid;
2131
+ const entryLength = location.nextOffset - location.offset;
2132
+ const entryBuffer = await readFixedRange(location.packIndex.fileHandle, location.offset, entryLength);
2133
+ const header = parsePackedEntryHeader(entryBuffer, location.offset);
2134
+ const compressedContent = entryBuffer.subarray(header.headerLength);
2135
+ if (header.packedType === "commit" || header.packedType === "tree" || header.packedType === "blob" || header.packedType === "tag") {
2136
+ const content = inflatePackedObject(compressedContent);
2137
+ if (content.length !== header.declaredSize) throw new Error(`Packed object size mismatch: ${location.oid} (expected ${header.declaredSize}, got ${content.length})`);
2138
+ return {
2139
+ oid: location.oid,
2140
+ type: header.packedType,
2141
+ content
2142
+ };
2143
+ }
2144
+ const deltaContent = inflatePackedObject(compressedContent);
2145
+ if (deltaContent.length !== header.declaredSize) throw new Error(`Packed delta size mismatch: ${location.oid} (expected ${header.declaredSize}, got ${deltaContent.length})`);
2146
+ const baseObject = header.packedType === "ofs-delta" ? await readObject((_location$packIndex$o = (_location$packIndex$o2 = location.packIndex.objectByOffset.get(header.baseOffset)) === null || _location$packIndex$o2 === void 0 ? void 0 : _location$packIndex$o2.oid) !== null && _location$packIndex$o !== void 0 ? _location$packIndex$o : (() => {
2147
+ throw new Error(`Missing ofs-delta base object at offset ${header.baseOffset}`);
2148
+ })()) : await readObject((_header$baseOid = header.baseOid) !== null && _header$baseOid !== void 0 ? _header$baseOid : (() => {
2149
+ throw new Error("Missing ref-delta base object id");
2150
+ })());
2151
+ const content = applyGitDelta(baseObject.content, deltaContent);
2152
+ return {
2153
+ oid: location.oid,
2154
+ type: baseObject.type,
2155
+ content
2156
+ };
2157
+ };
2158
+ const readObject = async (oid) => {
2159
+ const cachedObject = resolvedObjects.get(oid);
2160
+ if (cachedObject) return cachedObject;
2161
+ const objectPromise = (async () => {
2162
+ const looseObject = await readLooseObject(actualGitDir, oid);
2163
+ if (looseObject) return looseObject;
2164
+ const location = (await getPackStore()).objectByOid.get(oid);
2165
+ if (!location) throw new Error(`Git object not found: ${oid}`);
2166
+ return readPackedObject(location);
2167
+ })();
2168
+ resolvedObjects.set(oid, objectPromise);
2169
+ try {
2170
+ return await objectPromise;
2171
+ } catch (error) {
2172
+ resolvedObjects.delete(oid);
2173
+ throw error;
2174
+ }
2175
+ };
2176
+ return {
2177
+ close: async () => {
2178
+ if (!packStorePromise) return;
2179
+ const packStore = await packStorePromise;
2180
+ await Promise.allSettled(packStore.packs.map(async (pack) => {
2181
+ await pack.fileHandle.close();
2182
+ }));
2183
+ },
2184
+ readObject,
2185
+ resolveTagOidToCommit: async (tagOid) => {
2186
+ let currentOid = tagOid;
2187
+ const visitedOids = /* @__PURE__ */ new Set();
2188
+ while (true) {
2189
+ if (visitedOids.has(currentOid)) throw new Error(`Detected cyclic tag reference: ${currentOid}`);
2190
+ visitedOids.add(currentOid);
2191
+ const object = await readObject(currentOid);
2192
+ if (object.type !== "tag") return currentOid;
2193
+ currentOid = parseTagTargetOid(object.content);
2194
+ }
2195
+ }
2196
+ };
2197
+ };
2198
+ var runWithConcurrency = async (values, concurrency, worker) => {
2199
+ let nextIndex = 0;
2200
+ const runWorker = async () => {
2201
+ while (nextIndex < values.length) {
2202
+ const currentIndex = nextIndex;
2203
+ nextIndex += 1;
2204
+ await worker(values[currentIndex]);
2205
+ }
2206
+ };
2207
+ await Promise.all(Array.from({ length: Math.min(concurrency, Math.max(values.length, 1)) }, () => runWorker()));
2208
+ };
1915
2209
  /**
1916
- * Resolve a tag object OID to the commit OID it ultimately points to.
1917
- * Lightweight tags are returned unchanged.
2210
+ * Resolve multiple tag object OIDs to their peeled commit OIDs.
1918
2211
  * @param repoPath - Repository path
1919
- * @param tagOid - Tag or commit OID
1920
- * @returns Commit hash this tag points to
2212
+ * @param tagOids - Tag or commit OIDs
2213
+ * @returns Map of tag object OID to peeled commit OID
1921
2214
  */
1922
- var resolveTagOidToCommit = async (repoPath, tagOid) => {
2215
+ var resolveTagOidsToCommits = async (repoPath, tagOids) => {
2216
+ const resolver = await createGitObjectResolver(repoPath);
2217
+ const result = /* @__PURE__ */ new Map();
2218
+ const uniqueTagOids = Array.from(new Set(tagOids));
1923
2219
  try {
1924
- var _tagObject$tag;
1925
- const tagObject = await git$2.readTag({
1926
- fs,
1927
- dir: repoPath,
1928
- oid: tagOid
2220
+ await runWithConcurrency(uniqueTagOids, LOOSE_TAG_RESOLUTION_CONCURRENCY, async (tagOid) => {
2221
+ result.set(tagOid, await resolver.resolveTagOidToCommit(tagOid));
1929
2222
  });
1930
- if (tagObject === null || tagObject === void 0 || (_tagObject$tag = tagObject.tag) === null || _tagObject$tag === void 0 ? void 0 : _tagObject$tag.object) return tagObject.tag.object;
1931
- } catch (_unused) {}
1932
- return tagOid;
2223
+ } finally {
2224
+ await resolver.close();
2225
+ }
2226
+ return result;
2227
+ };
2228
+ var collectTreeFiles = async (resolver, treeOid, prefix, files) => {
2229
+ const treeObject = await resolver.readObject(treeOid);
2230
+ if (treeObject.type !== "tree") throw new Error(`Expected tree object: ${treeOid}`);
2231
+ for (const entry of parseTreeEntries(treeObject.content)) {
2232
+ const path = prefix ? `${prefix}/${entry.name}` : entry.name;
2233
+ if (entry.mode === "40000") {
2234
+ await collectTreeFiles(resolver, entry.oid, path, files);
2235
+ continue;
2236
+ }
2237
+ if (entry.mode !== "160000") files.set(path, entry.oid);
2238
+ }
2239
+ };
2240
+ /**
2241
+ * Collect all tracked file blob OIDs under the specified tree.
2242
+ * @param repoPath - Repository path
2243
+ * @param treeOid - Tree object OID
2244
+ * @returns Map of repository-relative file path to blob OID
2245
+ */
2246
+ var listTreeFiles = async (repoPath, treeOid) => {
2247
+ const resolver = await createGitObjectResolver(repoPath);
2248
+ const files = /* @__PURE__ */ new Map();
2249
+ try {
2250
+ await collectTreeFiles(resolver, treeOid, "", files);
2251
+ } finally {
2252
+ await resolver.close();
2253
+ }
2254
+ return files;
1933
2255
  };
1934
2256
  //#endregion
1935
2257
  //#region src/fast-tags.ts
@@ -2023,19 +2345,28 @@ var resolveTagsBatchWithCommit = async (repoPath, tagNames, logger) => {
2023
2345
  const remainingTags = tagNames.filter((tag) => !result.has(tag));
2024
2346
  if (remainingTags.length > 0) {
2025
2347
  const looseRefsStart = Date.now();
2026
- await Promise.all(remainingTags.map(async (tagName) => {
2348
+ const looseTagEntries = (await Promise.all(remainingTags.map(async (tagName) => {
2027
2349
  const looseRefPath = join(actualGitDir, "refs", "tags", tagName);
2028
2350
  try {
2029
- const oid = (await readFile(looseRefPath, "utf-8")).trim();
2030
- const commitOid = await resolveTagOidToCommit(repoPath, oid);
2351
+ return {
2352
+ tagName,
2353
+ oid: (await readFile(looseRefPath, "utf-8")).trim()
2354
+ };
2355
+ } catch (error) {
2356
+ if (error.code !== "ENOENT") throw error;
2357
+ return;
2358
+ }
2359
+ }))).filter((entry) => entry !== void 0);
2360
+ if (looseTagEntries.length > 0) {
2361
+ const commitOids = await resolveTagOidsToCommits(repoPath, looseTagEntries.map((entry) => entry.oid));
2362
+ for (const { tagName, oid } of looseTagEntries) {
2363
+ var _commitOids$get;
2031
2364
  result.set(tagName, {
2032
2365
  oid,
2033
- commitOid
2366
+ commitOid: (_commitOids$get = commitOids.get(oid)) !== null && _commitOids$get !== void 0 ? _commitOids$get : oid
2034
2367
  });
2035
- } catch (error) {
2036
- if (error.code !== "ENOENT") throw error;
2037
2368
  }
2038
- }));
2369
+ }
2039
2370
  logger.debug(`[fast-tags] read loose refs: ${Date.now() - looseRefsStart}ms`);
2040
2371
  }
2041
2372
  const totalTime = Date.now() - startTime;
@@ -2248,7 +2579,8 @@ var getCommit = async (repositoryPath, hash) => {
2248
2579
  shortHash: commit.oid.substring(0, 7),
2249
2580
  date: (/* @__PURE__ */ new Date(commit.commit.author.timestamp * 1e3)).toISOString(),
2250
2581
  message: commit.commit.message.trim(),
2251
- parents: commit.commit.parent || []
2582
+ parents: commit.commit.parent || [],
2583
+ tree: commit.commit.tree
2252
2584
  };
2253
2585
  } catch (_unused) {
2254
2586
  return;
@@ -2276,7 +2608,8 @@ var getCurrentCommit = async (repositoryPath) => {
2276
2608
  shortHash: commit.oid.substring(0, 7),
2277
2609
  date: (/* @__PURE__ */ new Date(commit.commit.author.timestamp * 1e3)).toISOString(),
2278
2610
  message: commit.commit.message.trim(),
2279
- parents: commit.commit.parent || []
2611
+ parents: commit.commit.parent || [],
2612
+ tree: commit.commit.tree
2280
2613
  };
2281
2614
  } catch (_unused2) {
2282
2615
  return;
@@ -2316,94 +2649,133 @@ var getRelatedBranches = async (repositoryPath, commitHash) => {
2316
2649
  return [];
2317
2650
  }
2318
2651
  };
2319
- /**
2320
- * Check if the repository has modified files (following RelaxVersioner logic).
2321
- * Checks for staged files, unstaged files, and untracked files (respecting .gitignore).
2322
- * @param repositoryPath - Local Git repository directory
2323
- * @returns Modified files
2324
- */
2325
- var isModifiedFile = ([, head, workdir, stage]) => {
2326
- return workdir === 2 || stage === 2 || stage === 3 || head === 1 && workdir === 0 || head === 0 && workdir === 1;
2652
+ var parseGitIndex = async (gitDir) => {
2653
+ try {
2654
+ const buffer = await fs.readFile(join(gitDir, "index"));
2655
+ if (buffer.subarray(0, 4).toString("ascii") !== "DIRC") throw new Error("Unsupported git index signature");
2656
+ const version = buffer.readUInt32BE(4);
2657
+ if (version !== 2 && version !== 3) throw new Error(`Unsupported git index version: ${version}`);
2658
+ const entryCount = buffer.readUInt32BE(8);
2659
+ let offset = 12;
2660
+ const entries = /* @__PURE__ */ new Map();
2661
+ for (let index = 0; index < entryCount; index++) {
2662
+ const entryStart = offset;
2663
+ const size = buffer.readUInt32BE(entryStart + 36);
2664
+ const oid = buffer.subarray(entryStart + 40, entryStart + 60).toString("hex");
2665
+ const flags = buffer.readUInt16BE(entryStart + 60);
2666
+ const stage = flags >> 12 & 3;
2667
+ offset = entryStart + 62;
2668
+ if (version >= 3 && (flags & 16384) !== 0) offset += 2;
2669
+ const pathEnd = buffer.indexOf(0, offset);
2670
+ if (pathEnd < 0) throw new Error("Invalid git index path entry");
2671
+ const path = buffer.subarray(offset, pathEnd).toString("utf-8");
2672
+ offset = pathEnd + 1;
2673
+ while ((offset - entryStart) % 8 !== 0) offset += 1;
2674
+ entries.set(path, {
2675
+ path,
2676
+ oid,
2677
+ size,
2678
+ stage
2679
+ });
2680
+ }
2681
+ return entries;
2682
+ } catch (error) {
2683
+ if (error.code === "ENOENT") return /* @__PURE__ */ new Map();
2684
+ throw error;
2685
+ }
2327
2686
  };
2328
- var getStatusRow = async (filepath, entries) => {
2329
- const [head, workdir, stage] = entries;
2330
- const [headType, workdirType, stageType] = await Promise.all([
2331
- head ? head.type() : void 0,
2332
- workdir ? workdir.type() : void 0,
2333
- stage ? stage.type() : void 0
2334
- ]);
2335
- const isBlob = [
2336
- headType,
2337
- workdirType,
2338
- stageType
2339
- ].includes("blob");
2340
- if ((headType === "tree" || headType === "special") && !isBlob) return;
2341
- if (headType === "commit") return;
2342
- if ((workdirType === "tree" || workdirType === "special") && !isBlob) return;
2343
- if (stageType === "commit") return;
2344
- if ((stageType === "tree" || stageType === "special") && !isBlob) return;
2345
- const headOid = headType === "blob" ? await head.oid() : void 0;
2346
- const stageOid = stageType === "blob" ? await stage.oid() : void 0;
2347
- let workdirOid;
2348
- if (headType !== "blob" && workdirType === "blob" && stageType !== "blob") workdirOid = "42";
2349
- else if (workdirType === "blob") workdirOid = await workdir.oid();
2350
- const entry = [
2351
- void 0,
2352
- headOid,
2353
- workdirOid,
2354
- stageOid
2355
- ];
2356
- const statusValues = entry.map((value) => entry.indexOf(value));
2357
- return [
2358
- filepath,
2359
- statusValues[1],
2360
- statusValues[2],
2361
- statusValues[3]
2362
- ];
2687
+ var listTrackedDirectories = (indexEntries) => {
2688
+ const directories = new Set([""]);
2689
+ for (const path of indexEntries.keys()) {
2690
+ const segments = path.split("/");
2691
+ let currentPath = "";
2692
+ for (let index = 0; index < segments.length - 1; index++) {
2693
+ currentPath = currentPath ? `${currentPath}/${segments[index]}` : segments[index];
2694
+ directories.add(currentPath);
2695
+ }
2696
+ }
2697
+ return directories;
2363
2698
  };
2364
- var reduceModifiedFiles = async (parent, children) => {
2365
- const modifiedFiles = parent ? [parent] : [];
2366
- for (const child of children) modifiedFiles.push(...child);
2367
- return modifiedFiles;
2699
+ var listWorkingDirectoryFiles = async (repositoryPath, trackedDirectories, relativePath = "") => {
2700
+ const directoryPath = relativePath ? join(repositoryPath, relativePath) : repositoryPath;
2701
+ const entries = await fs.readdir(directoryPath, { withFileTypes: true });
2702
+ const files = [];
2703
+ for (const entry of entries) {
2704
+ if (entry.name === ".git") continue;
2705
+ const entryPath = relativePath ? `${relativePath}/${entry.name}` : entry.name;
2706
+ if (entry.isDirectory()) {
2707
+ if (!trackedDirectories.has(entryPath)) {
2708
+ if (await git.isIgnored({
2709
+ fs,
2710
+ dir: repositoryPath,
2711
+ filepath: entryPath
2712
+ })) continue;
2713
+ }
2714
+ files.push(...await listWorkingDirectoryFiles(repositoryPath, trackedDirectories, entryPath));
2715
+ continue;
2716
+ }
2717
+ if (entry.isFile() || entry.isSymbolicLink()) files.push(entryPath);
2718
+ }
2719
+ return files;
2368
2720
  };
2369
- var iterateSequentially = async (walk, children) => {
2370
- const results = [];
2371
- for (const child of children) results.push(await walk(child));
2372
- return results;
2721
+ var calculateBlobOid = async (filePath) => {
2722
+ const content = await fs.readFile(filePath);
2723
+ return createHash("sha1").update(`blob ${content.length}\0`).update(content).digest("hex");
2373
2724
  };
2374
- var getModifiedFiles = async (repositoryPath) => {
2725
+ var getModifiedFiles = async (repositoryPath, headTreeOid) => {
2375
2726
  try {
2376
- return await git.walk({
2377
- fs,
2378
- dir: repositoryPath,
2379
- trees: [
2380
- git.TREE({ ref: "HEAD" }),
2381
- git.WORKDIR(),
2382
- git.STAGE()
2383
- ],
2384
- map: async (filepath, entries) => {
2385
- const [head, workdir, stage] = entries;
2386
- if (!head && !stage && workdir) {
2387
- if (await git.isIgnored({
2388
- fs,
2389
- dir: repositoryPath,
2390
- filepath
2391
- })) return null;
2727
+ const gitDir = await getActualGitDir(repositoryPath);
2728
+ const [headFiles, indexEntries] = await Promise.all([listTreeFiles(repositoryPath, headTreeOid), parseGitIndex(gitDir)]);
2729
+ const workdirFiles = await listWorkingDirectoryFiles(repositoryPath, listTrackedDirectories(indexEntries));
2730
+ const modifiedFiles = /* @__PURE__ */ new Map();
2731
+ const rememberModifiedFile = (path, reason) => {
2732
+ if (!modifiedFiles.has(path)) modifiedFiles.set(path, {
2733
+ path,
2734
+ reason
2735
+ });
2736
+ };
2737
+ for (const [path, headOid] of headFiles.entries()) {
2738
+ const indexEntry = indexEntries.get(path);
2739
+ if (!indexEntry) rememberModifiedFile(path, "staged");
2740
+ else if (indexEntry.stage !== 0 || indexEntry.oid !== headOid) rememberModifiedFile(path, "staged");
2741
+ }
2742
+ for (const indexEntry of indexEntries.values()) {
2743
+ if (!headFiles.has(indexEntry.path)) rememberModifiedFile(indexEntry.path, "staged");
2744
+ const absolutePath = join(repositoryPath, indexEntry.path);
2745
+ try {
2746
+ const stats = await fs.lstat(absolutePath);
2747
+ if (!stats.isFile() && !stats.isSymbolicLink()) {
2748
+ rememberModifiedFile(indexEntry.path, "worktree");
2749
+ continue;
2392
2750
  }
2393
- const statusRow = await getStatusRow(filepath, entries);
2394
- if (!statusRow || !isModifiedFile(statusRow)) return;
2395
- return statusRow;
2396
- },
2397
- reduce: reduceModifiedFiles,
2398
- iterate: iterateSequentially
2399
- });
2751
+ if (indexEntry.stage !== 0) {
2752
+ rememberModifiedFile(indexEntry.path, "staged");
2753
+ continue;
2754
+ }
2755
+ if (indexEntry.size !== stats.size || await calculateBlobOid(absolutePath) !== indexEntry.oid) rememberModifiedFile(indexEntry.path, "worktree");
2756
+ } catch (error) {
2757
+ if (error.code === "ENOENT") {
2758
+ rememberModifiedFile(indexEntry.path, "worktree");
2759
+ continue;
2760
+ }
2761
+ throw error;
2762
+ }
2763
+ }
2764
+ const trackedPaths = new Set(indexEntries.keys());
2765
+ for (const filepath of workdirFiles) {
2766
+ if (trackedPaths.has(filepath)) continue;
2767
+ if (!await git.isIgnored({
2768
+ fs,
2769
+ dir: repositoryPath,
2770
+ filepath
2771
+ })) rememberModifiedFile(filepath, "untracked");
2772
+ }
2773
+ return Array.from(modifiedFiles.values());
2400
2774
  } catch (_unused5) {
2401
2775
  return [];
2402
2776
  }
2403
2777
  };
2404
- var formatModifiedFile = (modifiedFile) => {
2405
- return `'${modifiedFile[0]}':${modifiedFile[1]}:${modifiedFile[2]}:${modifiedFile[3]}`;
2406
- };
2778
+ var formatModifiedFile = (modifiedFile) => `'${modifiedFile.path}':${modifiedFile.reason}`;
2407
2779
  /**
2408
2780
  * Lookup version label recursively core analyzer
2409
2781
  * @param cwd - The directory to check
@@ -2503,7 +2875,7 @@ var getGitMetadata = async (repositoryPath, checkWorkingDirectoryStatus, logger)
2503
2875
  metadata.git = gitMetadata;
2504
2876
  if (version) {
2505
2877
  if (checkWorkingDirectoryStatus) {
2506
- const modifiedFiles = await getModifiedFiles(gitRootPath);
2878
+ const modifiedFiles = await getModifiedFiles(gitRootPath, currentCommit.tree);
2507
2879
  if (modifiedFiles.length >= 1) {
2508
2880
  const newVersion = incrementLastVersionComponent(version);
2509
2881
  logger.debug(`Increased git version by detected modified items: ${formatVersion(version)} ---> ${formatVersion(newVersion)}, Files=[${modifiedFiles.map(formatModifiedFile).join(", ")}]`);
@@ -2609,4 +2981,4 @@ var ensureMetadataGitignore = async (metadataSourcePath, logger) => {
2609
2981
  //#endregion
2610
2982
  export { collectWorkspaceSiblings as a, replacePeerDependenciesWildcards as c, require_dist as d, __exportAll as f, getFetchGitMetadata as i, resolvePackageMetadata as l, generateMetadataFileContent as n, createConsoleLogger as o, __toESM as p, writeFileIfChanged as r, findWorkspaceRoot as s, ensureMetadataGitignore as t, resolveRawPackageJsonObject as u };
2611
2983
 
2612
- //# sourceMappingURL=metadata-file-BWd04LhD.js.map
2984
+ //# sourceMappingURL=metadata-file-D79yMa_A.js.map