@lage-run/hasher 1.9.2 → 1.9.3

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 (45) hide show
  1. package/lib/PackageTree.d.ts +2 -2
  2. package/lib/PackageTree.js.map +1 -1
  3. package/lib/TargetHasher.d.ts +14 -21
  4. package/lib/TargetHasher.js +14 -32
  5. package/lib/TargetHasher.js.map +1 -1
  6. package/lib/resolveExternalDependencies.d.ts +14 -11
  7. package/lib/resolveExternalDependencies.js +25 -28
  8. package/lib/resolveExternalDependencies.js.map +1 -1
  9. package/package.json +13 -11
  10. package/CHANGELOG.json +0 -735
  11. package/CHANGELOG.md +0 -323
  12. package/jest.config.js +0 -1
  13. package/lib/__fixtures__/config/backfill.config.d.ts +0 -1
  14. package/lib/__fixtures__/config/packages/package-1/backfill.config.d.ts +0 -0
  15. package/lib/__fixtures__/monorepo-nested/packages/package-a/build/another/file.d.ts +0 -1
  16. package/lib/__fixtures__/monorepo-nested/packages/package-a/build/another/file.js +0 -2
  17. package/lib/__fixtures__/monorepo-nested/packages/package-a/build/another/file.js.map +0 -1
  18. package/lib/__fixtures__/monorepo-with-global-files/some-global.config.d.ts +0 -1
  19. package/lib/__fixtures__/monorepo-with-global-files/some-global2.config.d.ts +0 -1
  20. package/lib/__fixtures__/monorepo-with-global-files-different-tasks/some-global.config.d.ts +0 -1
  21. package/lib/__tests__/PackageTree.test.d.ts +0 -1
  22. package/lib/__tests__/PackageTree.test.js +0 -76
  23. package/lib/__tests__/PackageTree.test.js.map +0 -1
  24. package/lib/__tests__/TargetHasher.test.d.ts +0 -1
  25. package/lib/__tests__/TargetHasher.test.js +0 -213
  26. package/lib/__tests__/TargetHasher.test.js.map +0 -1
  27. package/lib/__tests__/getPackageDeps.test.d.ts +0 -1
  28. package/lib/__tests__/getPackageDeps.test.js +0 -310
  29. package/lib/__tests__/getPackageDeps.test.js.map +0 -1
  30. package/lib/__tests__/resolveDependenciesHelper.d.ts +0 -3
  31. package/lib/__tests__/resolveDependenciesHelper.js +0 -66
  32. package/lib/__tests__/resolveDependenciesHelper.js.map +0 -1
  33. package/lib/__tests__/resolveExternalDependencies.test.d.ts +0 -1
  34. package/lib/__tests__/resolveExternalDependencies.test.js +0 -154
  35. package/lib/__tests__/resolveExternalDependencies.test.js.map +0 -1
  36. package/lib/__tests__/resolveInternalDependencies.test.d.ts +0 -1
  37. package/lib/__tests__/resolveInternalDependencies.test.js +0 -131
  38. package/lib/__tests__/resolveInternalDependencies.test.js.map +0 -1
  39. package/lib/nameAtVersion.d.ts +0 -1
  40. package/lib/nameAtVersion.js +0 -13
  41. package/lib/nameAtVersion.js.map +0 -1
  42. package/lib/resolveInternalDependencies.d.ts +0 -6
  43. package/lib/resolveInternalDependencies.js +0 -26
  44. package/lib/resolveInternalDependencies.js.map +0 -1
  45. package/tsconfig.json +0 -7
@@ -13,8 +13,8 @@ export declare class PackageTree {
13
13
  #private;
14
14
  private options;
15
15
  constructor(options: PackageTreeOptions);
16
- reset(): void;
16
+ private reset;
17
17
  initialize(): Promise<void>;
18
- addToPackageTree(filePaths: string[]): void;
18
+ private addToPackageTree;
19
19
  getPackageFiles(packageName: string, patterns: string[]): string[];
20
20
  }
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/PackageTree.ts"],"sourcesContent":["import { type PackageInfos } from \"workspace-tools\";\n\nimport execa from \"execa\";\nimport path from \"path\";\nimport fs from \"fs\";\nimport micromatch from \"micromatch\";\n\nexport interface PackageTreeOptions {\n root: string;\n packageInfos: PackageInfos;\n includeUntracked: boolean;\n}\n\ninterface PathNode {\n children: {\n [key: string]: PathNode;\n };\n\n isPackage: boolean;\n}\n\n/**\n * Package Tree keeps a data structure to quickly find all files in a package.\n *\n * TODO: add a watcher to make sure the tree is up to date during a \"watched\" run.\n */\nexport class PackageTree {\n #tree: PathNode = { children: {}, isPackage: true };\n #packageFiles: Record<string, string[]> = {};\n #memoizedPackageFiles: Record<string, string[]> = {};\n\n constructor(private options: PackageTreeOptions) {}\n\n reset(): void {\n // reset the internal state\n this.#tree = { children: {}, isPackage: true };\n this.#packageFiles = {};\n this.#memoizedPackageFiles = {};\n }\n\n async initialize(): Promise<void> {\n const { root, includeUntracked, packageInfos } = this.options;\n\n this.reset();\n\n // Generate path tree of all packages in workspace (scale: ~2000 * ~3)\n for (const info of Object.values(packageInfos)) {\n const packagePath = path.dirname(info.packageJsonPath);\n const pathParts = path.relative(root, packagePath).split(/[\\\\/]/);\n\n let currentNode = this.#tree;\n\n for (const part of pathParts) {\n // initialize the children if not already done\n currentNode.children[part] = currentNode.children[part] || { children: {}, isPackage: false };\n currentNode = currentNode.children[part];\n }\n\n currentNode.isPackage = true;\n }\n\n // Get all files in the workspace (scale: ~2000) according to git\n const lsFilesResults = await execa(\"git\", [\"ls-files\", \"-z\"], { cwd: root });\n\n if (lsFilesResults.exitCode === 0) {\n const files = lsFilesResults.stdout.split(\"\\0\").filter((f) => Boolean(f) && fs.existsSync(path.join(root, f)));\n this.addToPackageTree(files);\n }\n\n if (includeUntracked) {\n // Also get all untracked files in the workspace according to git\n const lsOtherResults = await execa(\"git\", [\"ls-files\", \"-o\", \"-z\", \"--exclude-standard\"], { cwd: root });\n if (lsOtherResults.exitCode === 0) {\n const files = lsOtherResults.stdout.split(\"\\0\").filter(Boolean);\n this.addToPackageTree(files);\n }\n }\n }\n\n addToPackageTree(filePaths: string[]): void {\n // key: path/to/package (packageRoot), value: array of a tuple of [file, hash]\n const packageFiles = this.#packageFiles;\n\n for (const entry of filePaths) {\n const pathParts = entry.split(/[\\\\/]/);\n\n let node = this.#tree;\n\n const pathPartsBuffer: string[] = [];\n let packagePathParts: string[] = [];\n\n for (const part of pathParts) {\n if (node.children[part]) {\n node = node.children[part] as PathNode;\n pathPartsBuffer.push(part);\n\n if (node.isPackage) {\n packagePathParts = [...pathPartsBuffer];\n }\n } else {\n break;\n }\n }\n\n const packageRoot = packagePathParts.join(\"/\");\n packageFiles[packageRoot] = packageFiles[packageRoot] || [];\n packageFiles[packageRoot].push(entry);\n }\n }\n\n getPackageFiles(packageName: string, patterns: string[]): string[] {\n const { root, packageInfos } = this.options;\n const packagePath = path.relative(root, path.dirname(packageInfos[packageName].packageJsonPath)).replace(/\\\\/g, \"/\");\n\n const packageFiles = this.#packageFiles[packagePath];\n\n if (!packageFiles) {\n return [];\n }\n\n const key = `${packageName}\\0${patterns.join(\"\\0\")}`;\n\n if (!this.#memoizedPackageFiles[key]) {\n const packagePatterns = patterns.map((pattern) => {\n if (pattern.startsWith(\"!\")) {\n return `!${path.join(packagePath, pattern.slice(1)).replace(/\\\\/g, \"/\")}`;\n }\n\n return path.join(packagePath, pattern).replace(/\\\\/g, \"/\");\n });\n this.#memoizedPackageFiles[key] = micromatch(packageFiles, packagePatterns, { dot: true });\n }\n\n return this.#memoizedPackageFiles[key];\n }\n}\n"],"names":["PackageTree","reset","children","isPackage","initialize","root","includeUntracked","packageInfos","options","info","Object","values","packagePath","path","dirname","packageJsonPath","pathParts","relative","split","currentNode","part","lsFilesResults","execa","cwd","exitCode","files","stdout","filter","f","Boolean","fs","existsSync","join","addToPackageTree","lsOtherResults","filePaths","packageFiles","entry","node","pathPartsBuffer","packagePathParts","push","packageRoot","getPackageFiles","packageName","patterns","replace","key","packagePatterns","map","pattern","startsWith","slice","micromatch","dot"],"mappings":"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"}
1
+ {"version":3,"sources":["../src/PackageTree.ts"],"sourcesContent":["import { type PackageInfos } from \"workspace-tools\";\n\nimport execa from \"execa\";\nimport path from \"path\";\nimport fs from \"fs\";\nimport micromatch from \"micromatch\";\n\nexport interface PackageTreeOptions {\n root: string;\n packageInfos: PackageInfos;\n includeUntracked: boolean;\n}\n\ninterface PathNode {\n children: {\n [key: string]: PathNode;\n };\n\n isPackage: boolean;\n}\n\n/**\n * Package Tree keeps a data structure to quickly find all files in a package.\n *\n * TODO: add a watcher to make sure the tree is up to date during a \"watched\" run.\n */\nexport class PackageTree {\n #tree: PathNode = { children: {}, isPackage: true };\n #packageFiles: Record<string, string[]> = {};\n #memoizedPackageFiles: Record<string, string[]> = {};\n\n constructor(private options: PackageTreeOptions) {}\n\n private reset(): void {\n // reset the internal state\n this.#tree = { children: {}, isPackage: true };\n this.#packageFiles = {};\n this.#memoizedPackageFiles = {};\n }\n\n public async initialize(): Promise<void> {\n const { root, includeUntracked, packageInfos } = this.options;\n\n this.reset();\n\n // Generate path tree of all packages in workspace (scale: ~2000 * ~3)\n for (const info of Object.values(packageInfos)) {\n const packagePath = path.dirname(info.packageJsonPath);\n const pathParts = path.relative(root, packagePath).split(/[\\\\/]/);\n\n let currentNode = this.#tree;\n\n for (const part of pathParts) {\n // initialize the children if not already done\n currentNode.children[part] = currentNode.children[part] || { children: {}, isPackage: false };\n currentNode = currentNode.children[part];\n }\n\n currentNode.isPackage = true;\n }\n\n // Get all files in the workspace (scale: ~2000) according to git\n const lsFilesResults = await execa(\"git\", [\"ls-files\", \"-z\"], { cwd: root });\n\n if (lsFilesResults.exitCode === 0) {\n const files = lsFilesResults.stdout.split(\"\\0\").filter((f) => Boolean(f) && fs.existsSync(path.join(root, f)));\n this.addToPackageTree(files);\n }\n\n if (includeUntracked) {\n // Also get all untracked files in the workspace according to git\n const lsOtherResults = await execa(\"git\", [\"ls-files\", \"-o\", \"-z\", \"--exclude-standard\"], { cwd: root });\n if (lsOtherResults.exitCode === 0) {\n const files = lsOtherResults.stdout.split(\"\\0\").filter(Boolean);\n this.addToPackageTree(files);\n }\n }\n }\n\n private addToPackageTree(filePaths: string[]): void {\n // key: path/to/package (packageRoot), value: array of a tuple of [file, hash]\n const packageFiles = this.#packageFiles;\n\n for (const entry of filePaths) {\n const pathParts = entry.split(/[\\\\/]/);\n\n let node = this.#tree;\n\n const pathPartsBuffer: string[] = [];\n let packagePathParts: string[] = [];\n\n for (const part of pathParts) {\n if (node.children[part]) {\n node = node.children[part] as PathNode;\n pathPartsBuffer.push(part);\n\n if (node.isPackage) {\n packagePathParts = [...pathPartsBuffer];\n }\n } else {\n break;\n }\n }\n\n const packageRoot = packagePathParts.join(\"/\");\n packageFiles[packageRoot] = packageFiles[packageRoot] || [];\n packageFiles[packageRoot].push(entry);\n }\n }\n\n public getPackageFiles(packageName: string, patterns: string[]): string[] {\n const { root, packageInfos } = this.options;\n const packagePath = path.relative(root, path.dirname(packageInfos[packageName].packageJsonPath)).replace(/\\\\/g, \"/\");\n\n const packageFiles = this.#packageFiles[packagePath];\n\n if (!packageFiles) {\n return [];\n }\n\n const key = `${packageName}\\0${patterns.join(\"\\0\")}`;\n\n if (!this.#memoizedPackageFiles[key]) {\n const packagePatterns = patterns.map((pattern) => {\n if (pattern.startsWith(\"!\")) {\n return `!${path.join(packagePath, pattern.slice(1)).replace(/\\\\/g, \"/\")}`;\n }\n\n return path.join(packagePath, pattern).replace(/\\\\/g, \"/\");\n });\n this.#memoizedPackageFiles[key] = micromatch(packageFiles, packagePatterns, { dot: true });\n }\n\n return this.#memoizedPackageFiles[key];\n }\n}\n"],"names":["PackageTree","reset","children","isPackage","initialize","root","includeUntracked","packageInfos","options","info","Object","values","packagePath","path","dirname","packageJsonPath","pathParts","relative","split","currentNode","part","lsFilesResults","execa","cwd","exitCode","files","stdout","filter","f","Boolean","fs","existsSync","join","addToPackageTree","lsOtherResults","filePaths","packageFiles","entry","node","pathPartsBuffer","packagePathParts","push","packageRoot","getPackageFiles","packageName","patterns","replace","key","packagePatterns","map","pattern","startsWith","slice","micromatch","dot"],"mappings":"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"}
@@ -1,6 +1,5 @@
1
1
  import type { Target } from "@lage-run/target-graph";
2
- import { type ParsedLock, type WorkspaceInfos, type PackageInfos } from "workspace-tools";
3
- import type { DependencyMap } from "workspace-tools/lib/graph/createDependencyMap.js";
2
+ import { type DependencyMap } from "workspace-tools";
4
3
  import { FileHasher } from "./FileHasher.js";
5
4
  import type { Logger } from "@lage-run/logger";
6
5
  import { PackageTree } from "./PackageTree.js";
@@ -25,32 +24,26 @@ export interface TargetManifest {
25
24
  }
26
25
  /**
27
26
  * TargetHasher is a class that can be used to generate a hash of a target.
28
- *
29
- * Currently, it encapsulates the use of `backfill-hasher` to generate a hash.
27
+ * It uses `glob-hasher` internally.
30
28
  */
31
29
  export declare class TargetHasher {
32
30
  private options;
33
- targetHashesLog: Record<string, {
34
- fileHashes: Record<string, string>;
35
- globalFileHashes: Record<string, string>;
36
- }>;
37
- targetHashesDirectory: string;
38
- logger: Logger | undefined;
39
- fileHasher: FileHasher;
31
+ private targetHashesLog;
32
+ private targetHashesDirectory;
33
+ private logger;
34
+ private fileHasher;
40
35
  packageTree: PackageTree | undefined;
41
- initializedPromise: Promise<unknown> | undefined;
42
- packageInfos: PackageInfos;
43
- workspaceInfo: WorkspaceInfos | undefined;
44
- globalInputsHash: Record<string, string> | undefined;
45
- lockInfo: ParsedLock | undefined;
46
- targetHashes: Record<string, string>;
36
+ private initializedPromise;
37
+ private packageInfos;
38
+ private globalInputsHash;
39
+ private lockInfo;
40
+ private targetHashes;
47
41
  dependencyMap: DependencyMap;
48
- getPackageInfos(workspacePackages: WorkspaceInfos): PackageInfos;
49
42
  constructor(options: TargetHasherOptions);
50
- ensureInitialized(): void;
43
+ private ensureInitialized;
51
44
  initialize(): Promise<void>;
52
45
  hash(target: Target): Promise<string>;
53
- writeTargetHashesManifest(): void;
54
- getEnvironmentGlobHashes(root: string, target: Target): Promise<Record<string, string>>;
46
+ private writeTargetHashesManifest;
47
+ private getEnvironmentGlobHashes;
55
48
  cleanup(): Promise<void>;
56
49
  }
@@ -13,9 +13,7 @@ const _globby = require("@lage-run/globby");
13
13
  const _fs = /*#__PURE__*/ _interop_require_default(require("fs"));
14
14
  const _path = /*#__PURE__*/ _interop_require_default(require("path"));
15
15
  const _workspacetools = require("workspace-tools");
16
- const _infoFromPackageJson = require("workspace-tools/lib/infoFromPackageJson.js");
17
16
  const _hashStrings = require("./hashStrings.js");
18
- const _resolveInternalDependencies = require("./resolveInternalDependencies.js");
19
17
  const _resolveExternalDependencies = require("./resolveExternalDependencies.js");
20
18
  const _FileHasher = require("./FileHasher.js");
21
19
  const _PackageTree = require("./PackageTree.js");
@@ -39,29 +37,6 @@ function _interop_require_default(obj) {
39
37
  };
40
38
  }
41
39
  class TargetHasher {
42
- getPackageInfos(workspacePackages) {
43
- const { root } = this.options;
44
- const packageInfos = {};
45
- if (workspacePackages.length) {
46
- for (const pkg of workspacePackages){
47
- packageInfos[pkg.name] = pkg.packageJson;
48
- }
49
- } else {
50
- const packageJsonPath = _path.default.join(root, "package.json");
51
- if (_fs.default.existsSync(packageJsonPath)) {
52
- try {
53
- const packageJson = JSON.parse(_fs.default.readFileSync(packageJsonPath, "utf-8"));
54
- const rootInfo = (0, _infoFromPackageJson.infoFromPackageJson)(packageJson, packageJsonPath);
55
- if (rootInfo) {
56
- packageInfos[rootInfo.name] = rootInfo;
57
- }
58
- } catch (e) {
59
- throw new Error(`Invalid package.json file detected ${packageJsonPath}: ${e?.message || e}`);
60
- }
61
- }
62
- }
63
- return packageInfos;
64
- }
65
40
  ensureInitialized() {
66
41
  if (!this.initializedPromise) {
67
42
  throw new Error("TargetHasher is not initialized");
@@ -77,8 +52,17 @@ class TargetHasher {
77
52
  this.fileHasher.readManifest().then(()=>(0, _globby.globAsync)(environmentGlob, {
78
53
  cwd: root
79
54
  })).then((files)=>this.fileHasher.hash(files)).then((hash)=>this.globalInputsHash = hash),
80
- (0, _workspacetools.getWorkspaceInfosAsync)(root).then((workspaceInfo)=>this.workspaceInfo = workspaceInfo).then(()=>{
81
- this.packageInfos = this.getPackageInfos(this.workspaceInfo);
55
+ (0, _workspacetools.getPackageInfosAsync)(root).then((packageInfos)=>{
56
+ if (Object.keys(packageInfos).length) {
57
+ this.packageInfos = packageInfos;
58
+ } else {
59
+ const rootInfo = (0, _workspacetools.getPackageInfo)(root);
60
+ if (rootInfo) {
61
+ this.packageInfos = {
62
+ [rootInfo.name]: rootInfo
63
+ };
64
+ }
65
+ }
82
66
  this.dependencyMap = (0, _workspacetools.createDependencyMap)(this.packageInfos, {
83
67
  withDevDependencies: true,
84
68
  withPeerDependencies: false
@@ -118,14 +102,13 @@ class TargetHasher {
118
102
  // 1. add hash of target's inputs
119
103
  // 2. add hash of target packages' internal and external deps
120
104
  const { dependencies, devDependencies } = this.packageInfos[target.packageName];
121
- const workspaceInfo = this.workspaceInfo;
122
105
  const parsedLock = this.lockInfo;
123
106
  const allDependencies = {
124
107
  ...dependencies,
125
108
  ...devDependencies
126
109
  };
127
- const internalDeps = (0, _resolveInternalDependencies.resolveInternalDependencies)(allDependencies, workspaceInfo);
128
- const externalDeps = (0, _resolveExternalDependencies.resolveExternalDependencies)(allDependencies, workspaceInfo, parsedLock);
110
+ const internalDeps = Object.keys(allDependencies).filter((dep)=>this.packageInfos[dep]);
111
+ const externalDeps = (0, _resolveExternalDependencies.resolveExternalDependencies)(allDependencies, this.packageInfos, parsedLock);
129
112
  const resolvedDependencies = [
130
113
  ...internalDeps,
131
114
  ...externalDeps
@@ -176,7 +159,7 @@ class TargetHasher {
176
159
  }
177
160
  async cleanup() {
178
161
  this.writeTargetHashesManifest();
179
- await this.fileHasher.writeManifest();
162
+ this.fileHasher.writeManifest();
180
163
  }
181
164
  constructor(options){
182
165
  _define_property(this, "options", void 0);
@@ -187,7 +170,6 @@ class TargetHasher {
187
170
  _define_property(this, "packageTree", void 0);
188
171
  _define_property(this, "initializedPromise", void 0);
189
172
  _define_property(this, "packageInfos", void 0);
190
- _define_property(this, "workspaceInfo", void 0);
191
173
  _define_property(this, "globalInputsHash", void 0);
192
174
  _define_property(this, "lockInfo", void 0);
193
175
  _define_property(this, "targetHashes", void 0);
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/TargetHasher.ts"],"sourcesContent":["import type { Target } from \"@lage-run/target-graph\";\nimport { hash } from \"glob-hasher\";\nimport { globAsync } from \"@lage-run/globby\";\n\nimport fs from \"fs\";\nimport path from \"path\";\nimport {\n type ParsedLock,\n type WorkspaceInfos,\n type PackageInfos,\n getWorkspaceInfosAsync,\n parseLockFile,\n createDependencyMap,\n} from \"workspace-tools\";\nimport type { DependencyMap } from \"workspace-tools/lib/graph/createDependencyMap.js\";\nimport { infoFromPackageJson } from \"workspace-tools/lib/infoFromPackageJson.js\";\n\nimport { hashStrings } from \"./hashStrings.js\";\nimport { resolveInternalDependencies } from \"./resolveInternalDependencies.js\";\nimport { resolveExternalDependencies } from \"./resolveExternalDependencies.js\";\nimport { FileHasher } from \"./FileHasher.js\";\nimport type { Logger } from \"@lage-run/logger\";\nimport { PackageTree } from \"./PackageTree.js\";\nimport { getInputFiles } from \"./getInputFiles.js\";\n\nexport interface TargetHasherOptions {\n root: string;\n environmentGlob: string[];\n cacheKey?: string;\n cliArgs?: string[];\n logger?: Logger;\n}\n\nexport interface TargetManifest {\n id: string;\n hash: string;\n globalInputsHash: string;\n dependency: Record<string, string>;\n fileHasher: FileHasher;\n files: Record<\n string,\n {\n mtimeMs: number;\n size: number;\n hash: string;\n }\n >;\n}\n\n/**\n * TargetHasher is a class that can be used to generate a hash of a target.\n *\n * Currently, it encapsulates the use of `backfill-hasher` to generate a hash.\n */\nexport class TargetHasher {\n targetHashesLog: Record<string, { fileHashes: Record<string, string>; globalFileHashes: Record<string, string> }> = {};\n targetHashesDirectory: string;\n\n logger: Logger | undefined;\n fileHasher: FileHasher;\n packageTree: PackageTree | undefined;\n\n initializedPromise: Promise<unknown> | undefined;\n\n packageInfos: PackageInfos = {};\n workspaceInfo: WorkspaceInfos | undefined;\n globalInputsHash: Record<string, string> | undefined;\n lockInfo: ParsedLock | undefined;\n targetHashes: Record<string, string> = {};\n\n dependencyMap: DependencyMap = {\n dependencies: new Map(),\n dependents: new Map(),\n };\n\n getPackageInfos(workspacePackages: WorkspaceInfos): PackageInfos {\n const { root } = this.options;\n const packageInfos: PackageInfos = {};\n\n if (workspacePackages.length) {\n for (const pkg of workspacePackages) {\n packageInfos[pkg.name] = pkg.packageJson;\n }\n } else {\n const packageJsonPath = path.join(root, \"package.json\");\n if (fs.existsSync(packageJsonPath)) {\n try {\n const packageJson = JSON.parse(fs.readFileSync(packageJsonPath, \"utf-8\"));\n const rootInfo = infoFromPackageJson(packageJson, packageJsonPath);\n if (rootInfo) {\n packageInfos[rootInfo.name] = rootInfo;\n }\n } catch (e) {\n throw new Error(`Invalid package.json file detected ${packageJsonPath}: ${(e as Error)?.message || e}`);\n }\n }\n }\n\n return packageInfos;\n }\n\n constructor(private options: TargetHasherOptions) {\n const { root, logger } = options;\n this.logger = logger;\n\n this.fileHasher = new FileHasher({\n root,\n });\n\n this.targetHashesDirectory = path.join(root, \"node_modules\", \".cache\", \"lage\", \"hashes\");\n\n if (!fs.existsSync(this.targetHashesDirectory)) {\n fs.mkdirSync(this.targetHashesDirectory, { recursive: true });\n }\n }\n\n ensureInitialized(): void {\n if (!this.initializedPromise) {\n throw new Error(\"TargetHasher is not initialized\");\n }\n }\n\n async initialize(): Promise<void> {\n const { environmentGlob, root } = this.options;\n\n if (this.initializedPromise) {\n await this.initializedPromise;\n return;\n }\n\n this.initializedPromise = Promise.all([\n this.fileHasher\n .readManifest()\n .then(() => globAsync(environmentGlob, { cwd: root }))\n .then((files) => this.fileHasher.hash(files))\n .then((hash) => (this.globalInputsHash = hash)),\n\n getWorkspaceInfosAsync(root)\n .then((workspaceInfo) => (this.workspaceInfo = workspaceInfo))\n .then(() => {\n this.packageInfos = this.getPackageInfos(this.workspaceInfo!);\n\n this.dependencyMap = createDependencyMap(this.packageInfos, { withDevDependencies: true, withPeerDependencies: false });\n this.packageTree = new PackageTree({\n root,\n packageInfos: this.packageInfos,\n\n // TODO: (optimization) false if process.env.TF_BUILD || process.env.CI\n includeUntracked: true,\n });\n\n return this.packageTree.initialize();\n }),\n\n parseLockFile(root).then((lockInfo) => (this.lockInfo = lockInfo)),\n ]);\n\n await this.initializedPromise;\n\n if (this.logger !== undefined) {\n const globalInputsHash = hashStrings(Object.values(this.globalInputsHash ?? {}));\n this.logger.verbose(`Global inputs hash: ${globalInputsHash}`);\n }\n }\n\n async hash(target: Target): Promise<string> {\n this.ensureInitialized();\n\n const { root } = this.options;\n\n if (target.cwd === root && target.cache) {\n if (!target.inputs) {\n throw new Error(`No \"inputs\" specified for target \"${target.id}\"; cannot cache.`);\n }\n\n const files = await globAsync(target.inputs, { cwd: root });\n const fileFashes = hash(files, { cwd: root }) ?? {};\n\n const hashes = Object.values(fileFashes) as string[];\n\n return hashStrings(hashes);\n }\n\n // 1. add hash of target's inputs\n // 2. add hash of target packages' internal and external deps\n const { dependencies, devDependencies } = this.packageInfos[target.packageName!];\n\n const workspaceInfo = this.workspaceInfo!;\n const parsedLock = this.lockInfo!;\n\n const allDependencies: Record<string, string> = {\n ...dependencies,\n ...devDependencies,\n };\n\n const internalDeps = resolveInternalDependencies(allDependencies, workspaceInfo);\n const externalDeps = resolveExternalDependencies(allDependencies, workspaceInfo, parsedLock);\n const resolvedDependencies = [...internalDeps, ...externalDeps].sort();\n\n const files = getInputFiles(target, this.dependencyMap, this.packageTree!);\n const fileHashes = this.fileHasher.hash(files) ?? {}; // this list is sorted by file name\n\n // get target hashes\n const targetDepHashes = target.dependencies?.sort().map((targetDep) => this.targetHashes[targetDep]);\n\n const globalFileHashes = await this.getEnvironmentGlobHashes(root, target);\n\n const combinedHashes = [\n // Environmental hashes\n ...Object.values(globalFileHashes),\n `${target.id}|${JSON.stringify(this.options.cliArgs)}`,\n this.options.cacheKey || \"\",\n\n // File content hashes based on target.inputs\n ...Object.values(fileHashes),\n\n // Dependency hashes\n ...resolvedDependencies,\n ...targetDepHashes,\n ].filter(Boolean);\n\n const hashString = hashStrings(combinedHashes);\n\n this.targetHashes[target.id] = hashString;\n\n this.targetHashesLog[target.id] = { fileHashes, globalFileHashes };\n\n return hashString;\n }\n\n writeTargetHashesManifest(): void {\n for (const [id, { fileHashes, globalFileHashes }] of Object.entries(this.targetHashesLog)) {\n const targetHashesManifestPath = path.join(this.targetHashesDirectory, `${id}.json`);\n if (!fs.existsSync(path.dirname(targetHashesManifestPath))) {\n fs.mkdirSync(path.dirname(targetHashesManifestPath), { recursive: true });\n }\n fs.writeFileSync(targetHashesManifestPath, JSON.stringify({ fileHashes, globalFileHashes }), \"utf-8\");\n }\n }\n\n async getEnvironmentGlobHashes(root: string, target: Target): Promise<Record<string, string>> {\n const globalFileHashes = target.environmentGlob\n ? this.fileHasher.hash(await globAsync(target.environmentGlob ?? [], { cwd: root }))\n : (this.globalInputsHash ?? {});\n\n return globalFileHashes;\n }\n\n async cleanup(): Promise<void> {\n this.writeTargetHashesManifest();\n await this.fileHasher.writeManifest();\n }\n}\n"],"names":["TargetHasher","getPackageInfos","workspacePackages","root","options","packageInfos","length","pkg","name","packageJson","packageJsonPath","path","join","fs","existsSync","JSON","parse","readFileSync","rootInfo","infoFromPackageJson","e","Error","message","ensureInitialized","initializedPromise","initialize","environmentGlob","Promise","all","fileHasher","readManifest","then","globAsync","cwd","files","hash","globalInputsHash","getWorkspaceInfosAsync","workspaceInfo","dependencyMap","createDependencyMap","withDevDependencies","withPeerDependencies","packageTree","PackageTree","includeUntracked","parseLockFile","lockInfo","logger","undefined","hashStrings","Object","values","verbose","target","cache","inputs","id","fileFashes","hashes","dependencies","devDependencies","packageName","parsedLock","allDependencies","internalDeps","resolveInternalDependencies","externalDeps","resolveExternalDependencies","resolvedDependencies","sort","getInputFiles","fileHashes","targetDepHashes","map","targetDep","targetHashes","globalFileHashes","getEnvironmentGlobHashes","combinedHashes","stringify","cliArgs","cacheKey","filter","Boolean","hashString","targetHashesLog","writeTargetHashesManifest","entries","targetHashesManifestPath","targetHashesDirectory","dirname","mkdirSync","recursive","writeFileSync","cleanup","writeManifest","Map","dependents","FileHasher"],"mappings":"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"}
1
+ {"version":3,"sources":["../src/TargetHasher.ts"],"sourcesContent":["import type { Target } from \"@lage-run/target-graph\";\nimport { hash } from \"glob-hasher\";\nimport { globAsync } from \"@lage-run/globby\";\n\nimport fs from \"fs\";\nimport path from \"path\";\nimport {\n type DependencyMap,\n type ParsedLock,\n type PackageInfos,\n parseLockFile,\n createDependencyMap,\n getPackageInfo,\n getPackageInfosAsync,\n} from \"workspace-tools\";\n\nimport { hashStrings } from \"./hashStrings.js\";\nimport { resolveExternalDependencies } from \"./resolveExternalDependencies.js\";\nimport { FileHasher } from \"./FileHasher.js\";\nimport type { Logger } from \"@lage-run/logger\";\nimport { PackageTree } from \"./PackageTree.js\";\nimport { getInputFiles } from \"./getInputFiles.js\";\n\nexport interface TargetHasherOptions {\n root: string;\n environmentGlob: string[];\n cacheKey?: string;\n cliArgs?: string[];\n logger?: Logger;\n}\n\nexport interface TargetManifest {\n id: string;\n hash: string;\n globalInputsHash: string;\n dependency: Record<string, string>;\n fileHasher: FileHasher;\n files: Record<\n string,\n {\n mtimeMs: number;\n size: number;\n hash: string;\n }\n >;\n}\n\n/**\n * TargetHasher is a class that can be used to generate a hash of a target.\n * It uses `glob-hasher` internally.\n */\nexport class TargetHasher {\n private targetHashesLog: Record<string, { fileHashes: Record<string, string>; globalFileHashes: Record<string, string> }> = {};\n private targetHashesDirectory: string;\n\n private logger: Logger | undefined;\n private fileHasher: FileHasher;\n public packageTree: PackageTree | undefined;\n\n private initializedPromise: Promise<unknown> | undefined;\n\n private packageInfos: PackageInfos = {};\n private globalInputsHash: Record<string, string> | undefined;\n private lockInfo: ParsedLock | undefined;\n private targetHashes: Record<string, string> = {};\n\n public dependencyMap: DependencyMap = {\n dependencies: new Map(),\n dependents: new Map(),\n };\n\n constructor(private options: TargetHasherOptions) {\n const { root, logger } = options;\n this.logger = logger;\n\n this.fileHasher = new FileHasher({\n root,\n });\n\n this.targetHashesDirectory = path.join(root, \"node_modules\", \".cache\", \"lage\", \"hashes\");\n\n if (!fs.existsSync(this.targetHashesDirectory)) {\n fs.mkdirSync(this.targetHashesDirectory, { recursive: true });\n }\n }\n\n private ensureInitialized(): void {\n if (!this.initializedPromise) {\n throw new Error(\"TargetHasher is not initialized\");\n }\n }\n\n public async initialize(): Promise<void> {\n const { environmentGlob, root } = this.options;\n\n if (this.initializedPromise) {\n await this.initializedPromise;\n return;\n }\n\n this.initializedPromise = Promise.all([\n this.fileHasher\n .readManifest()\n .then(() => globAsync(environmentGlob, { cwd: root }))\n .then((files) => this.fileHasher.hash(files))\n .then((hash) => (this.globalInputsHash = hash)),\n\n getPackageInfosAsync(root).then((packageInfos) => {\n if (Object.keys(packageInfos).length) {\n this.packageInfos = packageInfos;\n } else {\n const rootInfo = getPackageInfo(root);\n if (rootInfo) {\n this.packageInfos = { [rootInfo.name]: rootInfo };\n }\n }\n\n this.dependencyMap = createDependencyMap(this.packageInfos, { withDevDependencies: true, withPeerDependencies: false });\n this.packageTree = new PackageTree({\n root,\n packageInfos: this.packageInfos,\n\n // TODO: (optimization) false if process.env.TF_BUILD || process.env.CI\n includeUntracked: true,\n });\n\n return this.packageTree.initialize();\n }),\n\n parseLockFile(root).then((lockInfo) => (this.lockInfo = lockInfo)),\n ]);\n\n await this.initializedPromise;\n\n if (this.logger !== undefined) {\n const globalInputsHash = hashStrings(Object.values(this.globalInputsHash ?? {}));\n this.logger.verbose(`Global inputs hash: ${globalInputsHash}`);\n }\n }\n\n public async hash(target: Target): Promise<string> {\n this.ensureInitialized();\n\n const { root } = this.options;\n\n if (target.cwd === root && target.cache) {\n if (!target.inputs) {\n throw new Error(`No \"inputs\" specified for target \"${target.id}\"; cannot cache.`);\n }\n\n const files = await globAsync(target.inputs, { cwd: root });\n const fileFashes = hash(files, { cwd: root }) ?? {};\n\n const hashes = Object.values(fileFashes) as string[];\n\n return hashStrings(hashes);\n }\n\n // 1. add hash of target's inputs\n // 2. add hash of target packages' internal and external deps\n const { dependencies, devDependencies } = this.packageInfos[target.packageName!];\n\n const parsedLock = this.lockInfo!;\n\n const allDependencies: Record<string, string> = {\n ...dependencies,\n ...devDependencies,\n };\n\n const internalDeps = Object.keys(allDependencies).filter((dep) => this.packageInfos[dep]);\n const externalDeps = resolveExternalDependencies(allDependencies, this.packageInfos, parsedLock);\n const resolvedDependencies = [...internalDeps, ...externalDeps].sort();\n\n const files = getInputFiles(target, this.dependencyMap, this.packageTree!);\n const fileHashes = this.fileHasher.hash(files) ?? {}; // this list is sorted by file name\n\n // get target hashes\n const targetDepHashes = target.dependencies?.sort().map((targetDep) => this.targetHashes[targetDep]);\n\n const globalFileHashes = await this.getEnvironmentGlobHashes(root, target);\n\n const combinedHashes = [\n // Environmental hashes\n ...Object.values(globalFileHashes),\n `${target.id}|${JSON.stringify(this.options.cliArgs)}`,\n this.options.cacheKey || \"\",\n\n // File content hashes based on target.inputs\n ...Object.values(fileHashes),\n\n // Dependency hashes\n ...resolvedDependencies,\n ...targetDepHashes,\n ].filter(Boolean);\n\n const hashString = hashStrings(combinedHashes);\n\n this.targetHashes[target.id] = hashString;\n\n this.targetHashesLog[target.id] = { fileHashes, globalFileHashes };\n\n return hashString;\n }\n\n private writeTargetHashesManifest(): void {\n for (const [id, { fileHashes, globalFileHashes }] of Object.entries(this.targetHashesLog)) {\n const targetHashesManifestPath = path.join(this.targetHashesDirectory, `${id}.json`);\n if (!fs.existsSync(path.dirname(targetHashesManifestPath))) {\n fs.mkdirSync(path.dirname(targetHashesManifestPath), { recursive: true });\n }\n fs.writeFileSync(targetHashesManifestPath, JSON.stringify({ fileHashes, globalFileHashes }), \"utf-8\");\n }\n }\n\n private async getEnvironmentGlobHashes(root: string, target: Target): Promise<Record<string, string>> {\n const globalFileHashes = target.environmentGlob\n ? this.fileHasher.hash(await globAsync(target.environmentGlob ?? [], { cwd: root }))\n : (this.globalInputsHash ?? {});\n\n return globalFileHashes;\n }\n\n public async cleanup(): Promise<void> {\n this.writeTargetHashesManifest();\n this.fileHasher.writeManifest();\n }\n}\n"],"names":["TargetHasher","ensureInitialized","initializedPromise","Error","initialize","environmentGlob","root","options","Promise","all","fileHasher","readManifest","then","globAsync","cwd","files","hash","globalInputsHash","getPackageInfosAsync","packageInfos","Object","keys","length","rootInfo","getPackageInfo","name","dependencyMap","createDependencyMap","withDevDependencies","withPeerDependencies","packageTree","PackageTree","includeUntracked","parseLockFile","lockInfo","logger","undefined","hashStrings","values","verbose","target","cache","inputs","id","fileFashes","hashes","dependencies","devDependencies","packageName","parsedLock","allDependencies","internalDeps","filter","dep","externalDeps","resolveExternalDependencies","resolvedDependencies","sort","getInputFiles","fileHashes","targetDepHashes","map","targetDep","targetHashes","globalFileHashes","getEnvironmentGlobHashes","combinedHashes","JSON","stringify","cliArgs","cacheKey","Boolean","hashString","targetHashesLog","writeTargetHashesManifest","entries","targetHashesManifestPath","path","join","targetHashesDirectory","fs","existsSync","dirname","mkdirSync","recursive","writeFileSync","cleanup","writeManifest","Map","dependents","FileHasher"],"mappings":"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"}
@@ -1,11 +1,14 @@
1
- import type { ParsedLock, WorkspaceInfos } from "workspace-tools";
2
- export type Dependencies = {
3
- [key in string]: string;
4
- };
5
- export type ExternalDependenciesQueue = {
6
- name: string;
7
- versionRange: string;
8
- }[];
9
- export declare function filterExternalDependencies(dependencies: Dependencies, workspaces: WorkspaceInfos): Dependencies;
10
- export declare function addToQueue(dependencies: Dependencies | undefined, done: string[], queue: [string, string][]): void;
11
- export declare function resolveExternalDependencies(allDependencies: Dependencies, workspaces: WorkspaceInfos, lockInfo: ParsedLock): string[];
1
+ import { type PackageInfos, type ParsedLock } from "workspace-tools";
2
+ type Dependencies = Record<string, string>;
3
+ export type DependencyQueue = [name: string, versionRange: string][];
4
+ export type DependencySpec = `${string}@${string}`;
5
+ /** Filter the `dependencies` object to only contain deps from outside the repo. */
6
+ export declare function _filterExternalDependencies(dependencies: Dependencies, packageInfos: PackageInfos): Dependencies;
7
+ export declare function _addToQueue(dependencies: Dependencies | undefined, done: Set<DependencySpec>, queue: DependencyQueue): void;
8
+ /**
9
+ * Resolve versions for external (outside repo) dependencies and their transitive dependencies
10
+ * using the lock file.
11
+ * @returns Array of strings in the format `name@version`
12
+ */
13
+ export declare function resolveExternalDependencies(allDependencies: Dependencies, packageInfos: PackageInfos, lockInfo: ParsedLock): DependencySpec[];
14
+ export {};
@@ -9,51 +9,46 @@ function _export(target, all) {
9
9
  });
10
10
  }
11
11
  _export(exports, {
12
- get addToQueue () {
13
- return addToQueue;
12
+ get _addToQueue () {
13
+ return _addToQueue;
14
14
  },
15
- get filterExternalDependencies () {
16
- return filterExternalDependencies;
15
+ get _filterExternalDependencies () {
16
+ return _filterExternalDependencies;
17
17
  },
18
18
  get resolveExternalDependencies () {
19
19
  return resolveExternalDependencies;
20
20
  }
21
21
  });
22
22
  const _workspacetools = require("workspace-tools");
23
- const _nameAtVersion = require("./nameAtVersion.js");
24
- function filterExternalDependencies(dependencies, workspaces) {
25
- const workspacePackageNames = workspaces.map((ws)=>ws.name);
23
+ function _filterExternalDependencies(dependencies, packageInfos) {
26
24
  const externalDependencies = {};
27
- Object.entries(dependencies).forEach(([name, versionRange])=>{
28
- if (workspacePackageNames.indexOf(name) < 0) {
25
+ for (const [name, versionRange] of Object.entries(dependencies)){
26
+ if (!packageInfos[name]) {
29
27
  externalDependencies[name] = versionRange;
30
28
  }
31
- });
29
+ }
32
30
  return externalDependencies;
33
31
  }
34
- function isDone(done, key) {
35
- return done.indexOf(key) >= 0;
36
- }
37
32
  function isInQueue(queue, key) {
38
- return Boolean(queue.find(([name, versionRange])=>(0, _nameAtVersion.nameAtVersion)(name, versionRange) === key));
33
+ return queue.some(([name, versionRange])=>`${name}@${versionRange}` === key);
39
34
  }
40
- function addToQueue(dependencies, done, queue) {
35
+ function _addToQueue(dependencies, done, queue) {
41
36
  if (dependencies) {
42
- Object.entries(dependencies).forEach(([name, versionRange])=>{
43
- const versionRangeSignature = (0, _nameAtVersion.nameAtVersion)(name, versionRange);
44
- if (!isDone(done, versionRangeSignature) && !isInQueue(queue, versionRangeSignature)) {
37
+ for (const [name, versionRange] of Object.entries(dependencies)){
38
+ const versionRangeSignature = `${name}@${versionRange}`;
39
+ if (!done.has(versionRangeSignature) && !isInQueue(queue, versionRangeSignature)) {
45
40
  queue.push([
46
41
  name,
47
42
  versionRange
48
43
  ]);
49
44
  }
50
- });
45
+ }
51
46
  }
52
47
  }
53
- function resolveExternalDependencies(allDependencies, workspaces, lockInfo) {
54
- const externalDependencies = filterExternalDependencies(allDependencies, workspaces);
55
- const done = [];
56
- const doneRange = [];
48
+ function resolveExternalDependencies(allDependencies, packageInfos, lockInfo) {
49
+ const externalDependencies = _filterExternalDependencies(allDependencies, packageInfos);
50
+ const done = new Set();
51
+ const doneRange = new Set();
57
52
  const queue = Object.entries(externalDependencies);
58
53
  while(queue.length > 0){
59
54
  const next = queue.shift();
@@ -61,15 +56,17 @@ function resolveExternalDependencies(allDependencies, workspaces, lockInfo) {
61
56
  continue;
62
57
  }
63
58
  const [name, versionRange] = next;
64
- doneRange.push((0, _nameAtVersion.nameAtVersion)(name, versionRange));
59
+ doneRange.add(`${name}@${versionRange}`);
65
60
  const lockFileResult = (0, _workspacetools.queryLockFile)(name, versionRange, lockInfo);
66
61
  if (lockFileResult) {
67
62
  const { version, dependencies } = lockFileResult;
68
- addToQueue(dependencies, doneRange, queue);
69
- done.push((0, _nameAtVersion.nameAtVersion)(name, version));
63
+ _addToQueue(dependencies, doneRange, queue);
64
+ done.add(`${name}@${version}`);
70
65
  } else {
71
- done.push((0, _nameAtVersion.nameAtVersion)(name, versionRange));
66
+ done.add(`${name}@${versionRange}`);
72
67
  }
73
68
  }
74
- return done;
69
+ return [
70
+ ...done
71
+ ];
75
72
  }
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/resolveExternalDependencies.ts"],"sourcesContent":["import type { ParsedLock, WorkspaceInfos } from \"workspace-tools\";\nimport { queryLockFile } from \"workspace-tools\";\nimport { nameAtVersion } from \"./nameAtVersion.js\";\n\nexport type Dependencies = { [key in string]: string };\n\nexport type ExternalDependenciesQueue = {\n name: string;\n versionRange: string;\n}[];\n\nexport function filterExternalDependencies(dependencies: Dependencies, workspaces: WorkspaceInfos): Dependencies {\n const workspacePackageNames = workspaces.map((ws) => ws.name);\n const externalDependencies: Dependencies = {};\n\n Object.entries(dependencies).forEach(([name, versionRange]) => {\n if (workspacePackageNames.indexOf(name) < 0) {\n externalDependencies[name] = versionRange;\n }\n });\n\n return externalDependencies;\n}\n\nfunction isDone(done: string[], key: string): boolean {\n return done.indexOf(key) >= 0;\n}\n\nfunction isInQueue(queue: [string, string][], key: string): boolean {\n return Boolean(queue.find(([name, versionRange]) => nameAtVersion(name, versionRange) === key));\n}\n\nexport function addToQueue(dependencies: Dependencies | undefined, done: string[], queue: [string, string][]): void {\n if (dependencies) {\n Object.entries(dependencies).forEach(([name, versionRange]) => {\n const versionRangeSignature = nameAtVersion(name, versionRange);\n\n if (!isDone(done, versionRangeSignature) && !isInQueue(queue, versionRangeSignature)) {\n queue.push([name, versionRange]);\n }\n });\n }\n}\n\nexport function resolveExternalDependencies(allDependencies: Dependencies, workspaces: WorkspaceInfos, lockInfo: ParsedLock): string[] {\n const externalDependencies = filterExternalDependencies(allDependencies, workspaces);\n\n const done: string[] = [];\n const doneRange: string[] = [];\n const queue = Object.entries(externalDependencies);\n\n while (queue.length > 0) {\n const next = queue.shift();\n\n if (!next) {\n continue;\n }\n\n const [name, versionRange] = next;\n doneRange.push(nameAtVersion(name, versionRange));\n\n const lockFileResult = queryLockFile(name, versionRange, lockInfo);\n\n if (lockFileResult) {\n const { version, dependencies } = lockFileResult;\n\n addToQueue(dependencies, doneRange, queue);\n done.push(nameAtVersion(name, version));\n } else {\n done.push(nameAtVersion(name, versionRange));\n }\n }\n\n return done;\n}\n"],"names":["addToQueue","filterExternalDependencies","resolveExternalDependencies","dependencies","workspaces","workspacePackageNames","map","ws","name","externalDependencies","Object","entries","forEach","versionRange","indexOf","isDone","done","key","isInQueue","queue","Boolean","find","nameAtVersion","versionRangeSignature","push","allDependencies","lockInfo","doneRange","length","next","shift","lockFileResult","queryLockFile","version"],"mappings":";;;;;;;;;;;QAgCgBA;eAAAA;;QArBAC;eAAAA;;QAiCAC;eAAAA;;;gCA3Cc;+BACA;AASvB,SAASD,2BAA2BE,YAA0B,EAAEC,UAA0B;IAC/F,MAAMC,wBAAwBD,WAAWE,GAAG,CAAC,CAACC,KAAOA,GAAGC,IAAI;IAC5D,MAAMC,uBAAqC,CAAC;IAE5CC,OAAOC,OAAO,CAACR,cAAcS,OAAO,CAAC,CAAC,CAACJ,MAAMK,aAAa;QACxD,IAAIR,sBAAsBS,OAAO,CAACN,QAAQ,GAAG;YAC3CC,oBAAoB,CAACD,KAAK,GAAGK;QAC/B;IACF;IAEA,OAAOJ;AACT;AAEA,SAASM,OAAOC,IAAc,EAAEC,GAAW;IACzC,OAAOD,KAAKF,OAAO,CAACG,QAAQ;AAC9B;AAEA,SAASC,UAAUC,KAAyB,EAAEF,GAAW;IACvD,OAAOG,QAAQD,MAAME,IAAI,CAAC,CAAC,CAACb,MAAMK,aAAa,GAAKS,IAAAA,4BAAa,EAACd,MAAMK,kBAAkBI;AAC5F;AAEO,SAASjB,WAAWG,YAAsC,EAAEa,IAAc,EAAEG,KAAyB;IAC1G,IAAIhB,cAAc;QAChBO,OAAOC,OAAO,CAACR,cAAcS,OAAO,CAAC,CAAC,CAACJ,MAAMK,aAAa;YACxD,MAAMU,wBAAwBD,IAAAA,4BAAa,EAACd,MAAMK;YAElD,IAAI,CAACE,OAAOC,MAAMO,0BAA0B,CAACL,UAAUC,OAAOI,wBAAwB;gBACpFJ,MAAMK,IAAI,CAAC;oBAAChB;oBAAMK;iBAAa;YACjC;QACF;IACF;AACF;AAEO,SAASX,4BAA4BuB,eAA6B,EAAErB,UAA0B,EAAEsB,QAAoB;IACzH,MAAMjB,uBAAuBR,2BAA2BwB,iBAAiBrB;IAEzE,MAAMY,OAAiB,EAAE;IACzB,MAAMW,YAAsB,EAAE;IAC9B,MAAMR,QAAQT,OAAOC,OAAO,CAACF;IAE7B,MAAOU,MAAMS,MAAM,GAAG,EAAG;QACvB,MAAMC,OAAOV,MAAMW,KAAK;QAExB,IAAI,CAACD,MAAM;YACT;QACF;QAEA,MAAM,CAACrB,MAAMK,aAAa,GAAGgB;QAC7BF,UAAUH,IAAI,CAACF,IAAAA,4BAAa,EAACd,MAAMK;QAEnC,MAAMkB,iBAAiBC,IAAAA,6BAAa,EAACxB,MAAMK,cAAca;QAEzD,IAAIK,gBAAgB;YAClB,MAAM,EAAEE,OAAO,EAAE9B,YAAY,EAAE,GAAG4B;YAElC/B,WAAWG,cAAcwB,WAAWR;YACpCH,KAAKQ,IAAI,CAACF,IAAAA,4BAAa,EAACd,MAAMyB;QAChC,OAAO;YACLjB,KAAKQ,IAAI,CAACF,IAAAA,4BAAa,EAACd,MAAMK;QAChC;IACF;IAEA,OAAOG;AACT"}
1
+ {"version":3,"sources":["../src/resolveExternalDependencies.ts"],"sourcesContent":["import { queryLockFile, type PackageInfos, type ParsedLock } from \"workspace-tools\";\n\ntype Dependencies = Record<string, string>;\n\nexport type DependencyQueue = [name: string, versionRange: string][];\n\nexport type DependencySpec = `${string}@${string}`;\n\n/** Filter the `dependencies` object to only contain deps from outside the repo. */\nexport function _filterExternalDependencies(dependencies: Dependencies, packageInfos: PackageInfos): Dependencies {\n const externalDependencies: Dependencies = {};\n\n for (const [name, versionRange] of Object.entries(dependencies)) {\n if (!packageInfos[name]) {\n externalDependencies[name] = versionRange;\n }\n }\n\n return externalDependencies;\n}\n\nfunction isInQueue(queue: DependencyQueue, key: string): boolean {\n return queue.some(([name, versionRange]) => `${name}@${versionRange}` === key);\n}\n\nexport function _addToQueue(dependencies: Dependencies | undefined, done: Set<DependencySpec>, queue: DependencyQueue): void {\n if (dependencies) {\n for (const [name, versionRange] of Object.entries(dependencies)) {\n const versionRangeSignature = `${name}@${versionRange}` as const;\n\n if (!done.has(versionRangeSignature) && !isInQueue(queue, versionRangeSignature)) {\n queue.push([name, versionRange]);\n }\n }\n }\n}\n\n/**\n * Resolve versions for external (outside repo) dependencies and their transitive dependencies\n * using the lock file.\n * @returns Array of strings in the format `name@version`\n */\nexport function resolveExternalDependencies(\n allDependencies: Dependencies,\n packageInfos: PackageInfos,\n lockInfo: ParsedLock\n): DependencySpec[] {\n const externalDependencies = _filterExternalDependencies(allDependencies, packageInfos);\n\n const done = new Set<DependencySpec>();\n const doneRange = new Set<DependencySpec>();\n const queue: DependencyQueue = Object.entries(externalDependencies);\n\n while (queue.length > 0) {\n const next = queue.shift();\n\n if (!next) {\n continue;\n }\n\n const [name, versionRange] = next;\n doneRange.add(`${name}@${versionRange}`);\n\n const lockFileResult = queryLockFile(name, versionRange, lockInfo);\n\n if (lockFileResult) {\n const { version, dependencies } = lockFileResult;\n\n _addToQueue(dependencies, doneRange, queue);\n done.add(`${name}@${version}`);\n } else {\n done.add(`${name}@${versionRange}`);\n }\n }\n\n return [...done];\n}\n"],"names":["_addToQueue","_filterExternalDependencies","resolveExternalDependencies","dependencies","packageInfos","externalDependencies","name","versionRange","Object","entries","isInQueue","queue","key","some","done","versionRangeSignature","has","push","allDependencies","lockInfo","Set","doneRange","length","next","shift","add","lockFileResult","queryLockFile","version"],"mappings":";;;;;;;;;;;QAyBgBA;eAAAA;;QAhBAC;eAAAA;;QAiCAC;eAAAA;;;gCA1CkD;AAS3D,SAASD,4BAA4BE,YAA0B,EAAEC,YAA0B;IAChG,MAAMC,uBAAqC,CAAC;IAE5C,KAAK,MAAM,CAACC,MAAMC,aAAa,IAAIC,OAAOC,OAAO,CAACN,cAAe;QAC/D,IAAI,CAACC,YAAY,CAACE,KAAK,EAAE;YACvBD,oBAAoB,CAACC,KAAK,GAAGC;QAC/B;IACF;IAEA,OAAOF;AACT;AAEA,SAASK,UAAUC,KAAsB,EAAEC,GAAW;IACpD,OAAOD,MAAME,IAAI,CAAC,CAAC,CAACP,MAAMC,aAAa,GAAK,GAAGD,KAAK,CAAC,EAAEC,cAAc,KAAKK;AAC5E;AAEO,SAASZ,YAAYG,YAAsC,EAAEW,IAAyB,EAAEH,KAAsB;IACnH,IAAIR,cAAc;QAChB,KAAK,MAAM,CAACG,MAAMC,aAAa,IAAIC,OAAOC,OAAO,CAACN,cAAe;YAC/D,MAAMY,wBAAwB,GAAGT,KAAK,CAAC,EAAEC,cAAc;YAEvD,IAAI,CAACO,KAAKE,GAAG,CAACD,0BAA0B,CAACL,UAAUC,OAAOI,wBAAwB;gBAChFJ,MAAMM,IAAI,CAAC;oBAACX;oBAAMC;iBAAa;YACjC;QACF;IACF;AACF;AAOO,SAASL,4BACdgB,eAA6B,EAC7Bd,YAA0B,EAC1Be,QAAoB;IAEpB,MAAMd,uBAAuBJ,4BAA4BiB,iBAAiBd;IAE1E,MAAMU,OAAO,IAAIM;IACjB,MAAMC,YAAY,IAAID;IACtB,MAAMT,QAAyBH,OAAOC,OAAO,CAACJ;IAE9C,MAAOM,MAAMW,MAAM,GAAG,EAAG;QACvB,MAAMC,OAAOZ,MAAMa,KAAK;QAExB,IAAI,CAACD,MAAM;YACT;QACF;QAEA,MAAM,CAACjB,MAAMC,aAAa,GAAGgB;QAC7BF,UAAUI,GAAG,CAAC,GAAGnB,KAAK,CAAC,EAAEC,cAAc;QAEvC,MAAMmB,iBAAiBC,IAAAA,6BAAa,EAACrB,MAAMC,cAAcY;QAEzD,IAAIO,gBAAgB;YAClB,MAAM,EAAEE,OAAO,EAAEzB,YAAY,EAAE,GAAGuB;YAElC1B,YAAYG,cAAckB,WAAWV;YACrCG,KAAKW,GAAG,CAAC,GAAGnB,KAAK,CAAC,EAAEsB,SAAS;QAC/B,OAAO;YACLd,KAAKW,GAAG,CAAC,GAAGnB,KAAK,CAAC,EAAEC,cAAc;QACpC;IACF;IAEA,OAAO;WAAIO;KAAK;AAClB"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lage-run/hasher",
3
- "version": "1.9.2",
3
+ "version": "1.9.3",
4
4
  "description": "Hasher for Lage Targets",
5
5
  "repository": {
6
6
  "url": "https://github.com/microsoft/lage"
@@ -9,20 +9,21 @@
9
9
  "main": "lib/index.js",
10
10
  "types": "lib/index.d.ts",
11
11
  "scripts": {
12
- "build": "tsc",
13
- "start": "tsc -w --preserveWatchOutput",
14
- "test": "monorepo-scripts jest",
12
+ "build": "yarn types && yarn transpile",
13
+ "transpile": "monorepo-scripts transpile",
14
+ "types": "yarn run -T tsc",
15
+ "test": "yarn run -T jest",
15
16
  "lint": "monorepo-scripts lint"
16
17
  },
17
18
  "dependencies": {
18
- "@lage-run/globby": "^14.2.2",
19
- "@lage-run/logger": "^1.3.2",
20
- "@lage-run/target-graph": "^0.12.2",
19
+ "@lage-run/globby": "^13.0.1",
20
+ "@lage-run/logger": "^1.3.3",
21
+ "@lage-run/target-graph": "^0.12.3",
21
22
  "execa": "^5.1.1",
22
23
  "glob-hasher": "^1.4.2",
23
24
  "graceful-fs": "^4.2.11",
24
25
  "micromatch": "^4.0.8",
25
- "workspace-tools": "^0.40.4"
26
+ "workspace-tools": "^0.41.0"
26
27
  },
27
28
  "devDependencies": {
28
29
  "@lage-run/monorepo-fixture": "^0.1.0",
@@ -30,7 +31,8 @@
30
31
  "@types/graceful-fs": "^4.1.6",
31
32
  "@types/micromatch": "^4.0.0"
32
33
  },
33
- "publishConfig": {
34
- "access": "public"
35
- }
34
+ "files": [
35
+ "lib/!(__*)",
36
+ "lib/!(__*)/**"
37
+ ]
36
38
  }