@decohere/forge 0.0.1-dev.13 → 0.0.1-dev.130

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 (195) hide show
  1. package/LICENSE +15 -0
  2. package/README.md +150 -0
  3. package/commonjs/src/actions/build.action.js +8 -6
  4. package/commonjs/src/actions/clean.action.js +6 -8
  5. package/commonjs/src/actions/commit.action.js +4 -6
  6. package/commonjs/src/actions/copy.action.js +62 -12
  7. package/commonjs/src/actions/dependency-report.action.js +8 -6
  8. package/commonjs/src/actions/dependency-sync.action.js +9 -5
  9. package/commonjs/src/actions/docker.action.js +209 -0
  10. package/commonjs/src/actions/index.js +6 -2
  11. package/commonjs/src/actions/link.action.js +154 -0
  12. package/commonjs/src/actions/package.action.js +234 -0
  13. package/commonjs/src/actions/paths.action.js +120 -0
  14. package/commonjs/src/actions/publish.action.js +4 -6
  15. package/commonjs/src/actions/sync-lock-file.action.js +2 -4
  16. package/commonjs/src/actions/tag.action.js +6 -9
  17. package/commonjs/src/actions/typecheck.action.js +67 -0
  18. package/commonjs/src/actions/unlink.action.js +74 -0
  19. package/commonjs/src/actions/version.action.js +14 -16
  20. package/commonjs/src/actions/watch.action.js +3 -5
  21. package/commonjs/src/commands/build.command.js +4 -3
  22. package/commonjs/src/commands/dependency.command.js +1 -3
  23. package/commonjs/src/commands/docker.command.js +26 -0
  24. package/commonjs/src/commands/forge.command.js +1 -3
  25. package/commonjs/src/commands/index.js +5 -2
  26. package/commonjs/src/commands/link.command.js +90 -0
  27. package/commonjs/src/commands/package.command.js +36 -0
  28. package/commonjs/src/commands/paths.command.js +24 -0
  29. package/commonjs/src/commands/publish.command.js +1 -3
  30. package/commonjs/src/commands/tag.command.js +1 -3
  31. package/commonjs/src/commands/typecheck.command.js +24 -0
  32. package/commonjs/src/commands/version.command.js +1 -3
  33. package/commonjs/src/const.js +0 -2
  34. package/commonjs/src/create-workspace.js +38 -0
  35. package/commonjs/src/errors.js +2 -4
  36. package/commonjs/src/extensions/project.extensions.js +11 -13
  37. package/commonjs/src/factories/swc-config.factory.js +29 -9
  38. package/commonjs/src/forge.module.js +23 -22
  39. package/commonjs/src/index.js +11 -2
  40. package/commonjs/src/packaging/dependency-pinner.service.js +118 -0
  41. package/commonjs/src/packaging/deployable.js +44 -0
  42. package/commonjs/src/packaging/import-graph.service.js +137 -0
  43. package/commonjs/src/packaging/release-exports.js +90 -0
  44. package/commonjs/src/packaging/ui-assets.js +75 -0
  45. package/commonjs/src/semver/index.js +18 -0
  46. package/commonjs/src/semver/semver.js +92 -0
  47. package/commonjs/src/services/dependency-resolver.service.js +70 -26
  48. package/commonjs/src/services/file-writer.service.js +2 -11
  49. package/commonjs/src/services/incremental-watch.js +24 -0
  50. package/commonjs/src/services/output-cache.js +39 -0
  51. package/commonjs/src/services/swc-transpiler.js +85 -99
  52. package/commonjs/src/services/transpile-cache.js +44 -0
  53. package/commonjs/src/services/ts-program-host.js +4 -6
  54. package/commonjs/src/services/type-emission-program.js +24 -9
  55. package/commonjs/src/services/type-emitter.js +51 -16
  56. package/commonjs/src/types/build-target.type.js +0 -2
  57. package/commonjs/src/types/configuration.type.js +0 -2
  58. package/commonjs/src/types/dependency.types.js +0 -2
  59. package/commonjs/src/types/swc-config.type.js +0 -2
  60. package/commonjs/src/types/transform-response.model.js +3 -18
  61. package/commonjs/src/types/transformer.type.js +0 -2
  62. package/commonjs/src/types/workspace-config.type.js +0 -2
  63. package/commonjs/src/vitest/forge-build.plugin.js +28 -44
  64. package/commonjs/src/vitest/index.js +0 -2
  65. package/commonjs/src/workspace.config.js +39 -6
  66. package/es6/src/actions/build.action.js +7 -7
  67. package/es6/src/actions/clean.action.js +5 -8
  68. package/es6/src/actions/commit.action.js +3 -6
  69. package/es6/src/actions/copy.action.js +61 -12
  70. package/es6/src/actions/dependency-report.action.js +7 -7
  71. package/es6/src/actions/dependency-sync.action.js +8 -6
  72. package/es6/src/actions/docker.action.js +194 -0
  73. package/es6/src/actions/index.js +6 -2
  74. package/es6/src/actions/link.action.js +128 -0
  75. package/es6/src/actions/package.action.js +219 -0
  76. package/es6/src/actions/paths.action.js +97 -0
  77. package/es6/src/actions/publish.action.js +3 -6
  78. package/es6/src/actions/sync-lock-file.action.js +2 -4
  79. package/es6/src/actions/tag.action.js +5 -9
  80. package/es6/src/actions/typecheck.action.js +52 -0
  81. package/es6/src/actions/unlink.action.js +59 -0
  82. package/es6/src/actions/version.action.js +9 -12
  83. package/es6/src/actions/watch.action.js +2 -5
  84. package/es6/src/commands/build.command.js +4 -3
  85. package/es6/src/commands/dependency.command.js +1 -3
  86. package/es6/src/commands/docker.command.js +16 -0
  87. package/es6/src/commands/forge.command.js +1 -3
  88. package/es6/src/commands/index.js +5 -2
  89. package/es6/src/commands/link.command.js +67 -0
  90. package/es6/src/commands/package.command.js +26 -0
  91. package/es6/src/commands/paths.command.js +14 -0
  92. package/es6/src/commands/publish.command.js +1 -3
  93. package/es6/src/commands/tag.command.js +1 -3
  94. package/es6/src/commands/typecheck.command.js +14 -0
  95. package/es6/src/commands/version.command.js +1 -3
  96. package/es6/src/const.js +0 -2
  97. package/es6/src/create-workspace.js +26 -0
  98. package/es6/src/errors.js +1 -3
  99. package/es6/src/extensions/project.extensions.js +5 -7
  100. package/es6/src/factories/swc-config.factory.js +29 -9
  101. package/es6/src/forge.module.js +23 -22
  102. package/es6/src/index.js +3 -3
  103. package/es6/src/packaging/dependency-pinner.service.js +103 -0
  104. package/es6/src/packaging/deployable.js +21 -0
  105. package/es6/src/packaging/import-graph.service.js +122 -0
  106. package/es6/src/packaging/release-exports.js +80 -0
  107. package/es6/src/packaging/ui-assets.js +49 -0
  108. package/es6/src/semver/index.js +1 -0
  109. package/es6/src/semver/semver.js +71 -0
  110. package/es6/src/services/dependency-resolver.service.js +70 -26
  111. package/es6/src/services/file-writer.service.js +2 -11
  112. package/es6/src/services/incremental-watch.js +18 -0
  113. package/es6/src/services/output-cache.js +29 -0
  114. package/es6/src/services/swc-transpiler.js +85 -99
  115. package/es6/src/services/transpile-cache.js +29 -0
  116. package/es6/src/services/ts-program-host.js +4 -6
  117. package/es6/src/services/type-emission-program.js +24 -9
  118. package/es6/src/services/type-emitter.js +48 -16
  119. package/es6/src/types/build-target.type.js +0 -2
  120. package/es6/src/types/configuration.type.js +0 -2
  121. package/es6/src/types/dependency.types.js +0 -2
  122. package/es6/src/types/swc-config.type.js +0 -2
  123. package/es6/src/types/transform-response.model.js +0 -7
  124. package/es6/src/types/transformer.type.js +0 -2
  125. package/es6/src/types/workspace-config.type.js +0 -2
  126. package/es6/src/vitest/forge-build.plugin.js +27 -43
  127. package/es6/src/vitest/index.js +0 -2
  128. package/es6/src/workspace.config.js +39 -5
  129. package/package.json +15 -5
  130. package/types/src/actions/build.action.d.ts +5 -4
  131. package/types/src/actions/clean.action.d.ts +3 -3
  132. package/types/src/actions/commit.action.d.ts +3 -3
  133. package/types/src/actions/copy.action.d.ts +18 -3
  134. package/types/src/actions/dependency-report.action.d.ts +3 -3
  135. package/types/src/actions/dependency-sync.action.d.ts +3 -3
  136. package/types/src/actions/docker.action.d.ts +38 -0
  137. package/types/src/actions/index.d.ts +6 -0
  138. package/types/src/actions/link.action.d.ts +25 -0
  139. package/types/src/actions/package.action.d.ts +38 -0
  140. package/types/src/actions/paths.action.d.ts +28 -0
  141. package/types/src/actions/publish.action.d.ts +4 -4
  142. package/types/src/actions/sync-lock-file.action.d.ts +2 -2
  143. package/types/src/actions/tag.action.d.ts +3 -3
  144. package/types/src/actions/typecheck.action.d.ts +14 -0
  145. package/types/src/actions/unlink.action.d.ts +9 -0
  146. package/types/src/actions/version.action.d.ts +4 -4
  147. package/types/src/actions/watch.action.d.ts +3 -3
  148. package/types/src/commands/build.command.d.ts +3 -2
  149. package/types/src/commands/dependency.command.d.ts +2 -2
  150. package/types/src/commands/docker.command.d.ts +6 -0
  151. package/types/src/commands/forge.command.d.ts +2 -2
  152. package/types/src/commands/index.d.ts +5 -0
  153. package/types/src/commands/link.command.d.ts +29 -0
  154. package/types/src/commands/package.command.d.ts +11 -0
  155. package/types/src/commands/paths.command.d.ts +6 -0
  156. package/types/src/commands/publish.command.d.ts +1 -1
  157. package/types/src/commands/tag.command.d.ts +1 -1
  158. package/types/src/commands/typecheck.command.d.ts +6 -0
  159. package/types/src/commands/version.command.d.ts +1 -1
  160. package/types/src/create-workspace.d.ts +7 -0
  161. package/types/src/errors.d.ts +1 -1
  162. package/types/src/extensions/project.extensions.d.ts +2 -2
  163. package/types/src/factories/swc-config.factory.d.ts +3 -2
  164. package/types/src/forge.module.d.ts +16 -4
  165. package/types/src/index.d.ts +3 -1
  166. package/types/src/packaging/dependency-pinner.service.d.ts +20 -0
  167. package/types/src/packaging/deployable.d.ts +17 -0
  168. package/types/src/packaging/import-graph.service.d.ts +33 -0
  169. package/types/src/packaging/release-exports.d.ts +18 -0
  170. package/types/src/packaging/ui-assets.d.ts +21 -0
  171. package/types/src/semver/index.d.ts +1 -0
  172. package/types/src/semver/semver.d.ts +18 -0
  173. package/types/src/services/dependency-resolver.service.d.ts +8 -1
  174. package/types/src/services/file-writer.service.d.ts +1 -2
  175. package/types/src/services/incremental-watch.d.ts +13 -0
  176. package/types/src/services/output-cache.d.ts +10 -0
  177. package/types/src/services/swc-transpiler.d.ts +28 -15
  178. package/types/src/services/transpile-cache.d.ts +17 -0
  179. package/types/src/services/ts-program-host.d.ts +2 -2
  180. package/types/src/services/type-emission-program.d.ts +8 -3
  181. package/types/src/services/type-emitter.d.ts +21 -8
  182. package/types/src/types/configuration.type.d.ts +6 -1
  183. package/types/src/types/dependency.types.d.ts +8 -9
  184. package/types/src/types/swc-config.type.d.ts +7 -1
  185. package/types/src/types/transform-response.model.d.ts +2 -7
  186. package/types/src/types/transformer.type.d.ts +2 -11
  187. package/types/src/types/workspace-config.type.d.ts +3 -3
  188. package/types/src/vitest/forge-build.plugin.d.ts +0 -2
  189. package/types/src/workspace.config.d.ts +6 -0
  190. package/commonjs/src/mixins/caches-outputs.mixin.js +0 -44
  191. package/commonjs/src/mixins/incremental-transform.mixin.js +0 -36
  192. package/es6/src/mixins/caches-outputs.mixin.js +0 -34
  193. package/es6/src/mixins/incremental-transform.mixin.js +0 -26
  194. package/types/src/mixins/caches-outputs.mixin.d.ts +0 -7
  195. package/types/src/mixins/incremental-transform.mixin.d.ts +0 -13
@@ -5,30 +5,28 @@ function _ts_decorate(decorators, target, key, desc) {
5
5
  return c > 3 && r && Object.defineProperty(target, key, r), r;
6
6
  }
7
7
  import { injectable } from "@decohere/crucible/decorators";
8
- import { io } from "@decohere/nexus/io";
8
+ import { io } from "@decohere/core/io";
9
9
  import { parseImports } from "parse-imports";
10
10
  import { BUILT_IN_MODULES } from "../const.js";
11
11
  import { ForgeError } from "../errors.js";
12
12
  export class DependencyResolver {
13
13
  computeDrift(current, computed) {
14
- const sortKeys = (obj)=>Object.fromEntries(Object.entries(obj).sort());
15
- const currentDeps = sortKeys(current.dependencies ?? {});
16
- const computedDeps = sortKeys(computed.dependencies ?? {});
17
- const currentDevDeps = sortKeys(current.devDependencies ?? {});
18
- const computedDevDeps = sortKeys(computed.devDependencies ?? {});
19
- const hasDrift = JSON.stringify(currentDeps) !== JSON.stringify(computedDeps) || JSON.stringify(currentDevDeps) !== JSON.stringify(computedDevDeps);
20
- if (!hasDrift) {
14
+ const lists = (pkg)=>{
15
+ const sortKeys = (obj)=>Object.fromEntries(Object.entries(obj ?? {}).sort());
16
+ return {
17
+ dependencies: sortKeys(pkg.dependencies),
18
+ devDependencies: sortKeys(pkg.devDependencies),
19
+ peerDependencies: sortKeys(pkg.peerDependencies)
20
+ };
21
+ };
22
+ const original = lists(current);
23
+ const updated = lists(computed);
24
+ if (JSON.stringify(original) === JSON.stringify(updated)) {
21
25
  return null;
22
26
  }
23
27
  return {
24
- original: {
25
- dependencies: currentDeps,
26
- devDependencies: currentDevDeps
27
- },
28
- updated: {
29
- dependencies: computedDeps,
30
- devDependencies: computedDevDeps
31
- }
28
+ original,
29
+ updated
32
30
  };
33
31
  }
34
32
  async getWorkspacePackages(workspace, projects) {
@@ -68,29 +66,77 @@ export class DependencyResolver {
68
66
  ]);
69
67
  }
70
68
  async computeProjectDependencies(project, workspacePackages) {
71
- const { dependencies, devDependencies, warnings } = await this.getDependencies(project, workspacePackages);
72
69
  const pkg = await project.getPackageJson();
73
- const updatedPackage = pkg.withDependencies(dependencies).withDevDependencies(devDependencies);
70
+ const peerNames = Object.keys(pkg.peerDependencies ?? {});
71
+ const peerDependencies = this.getPeerDependencies(project, peerNames, workspacePackages);
72
+ const { dependencies, devDependencies, warnings } = await this.getDependencies(project, workspacePackages, new Set(peerNames));
73
+ let updatedPackage = pkg.withDependencies(dependencies).withDevDependencies(devDependencies);
74
+ if (peerNames.length > 0) {
75
+ updatedPackage = updatedPackage.withPeerDependencies(peerDependencies);
76
+ }
74
77
  return {
75
78
  project,
76
79
  updatedPackage,
77
80
  warnings
78
81
  };
79
82
  }
80
- async getDependencies(project, workspacePackages) {
83
+ /**
84
+ * A package declares its peers by name in its own `peerDependencies` (and marks optional ones in
85
+ * `peerDependenciesMeta`, which sync leaves as written). The root owns every version, so each
86
+ * peer gets the root's range; a peer the root doesn't list is an error. A declared peer stays
87
+ * even when no code imports it: a pino transport, say, is loaded by name.
88
+ */ getPeerDependencies(project, peerNames, workspacePackages) {
89
+ const peers = {};
90
+ for (const name of [
91
+ ...peerNames
92
+ ].sort()){
93
+ const version = workspacePackages.get(name)?.version;
94
+ if (version == null) {
95
+ throw new ForgeError(`"${name}" is declared a peer of ${project.name}, but the root package.json doesn't list it. ` + "Add it there: the root owns every version.");
96
+ }
97
+ peers[name] = version;
98
+ }
99
+ return peers;
100
+ }
101
+ async getDependencies(project, workspacePackages, peers) {
81
102
  const files = await project.getAllFiles();
82
- const results = await Promise.all(files.map((file)=>this.getFileImports(file)));
83
- const imports = results.flatMap((r)=>r.imports);
103
+ const results = await Promise.all(files.map(async (file)=>({
104
+ file,
105
+ ...await this.getFileImports(file)
106
+ })));
84
107
  const warnings = results.flatMap((r)=>r.warnings);
85
- const allDependencies = [
86
- ...new Set(imports)
87
- ].map((fileImport)=>this.getDependencyFrom(fileImport, workspacePackages)).filter((dep)=>dep != null);
108
+ /** Which files import each package, for errors that point at the code. */ const importedBy = new Map();
109
+ const allDependencies = [];
110
+ for (const { file, imports } of results){
111
+ for (const fileImport of imports){
112
+ const dep = this.getDependencyFrom(fileImport, workspacePackages);
113
+ if (dep == null || peers.has(dep.name)) {
114
+ continue;
115
+ }
116
+ if (!importedBy.has(dep.name)) {
117
+ importedBy.set(dep.name, new Set());
118
+ allDependencies.push(dep);
119
+ }
120
+ importedBy.get(dep.name)?.add(file.relativePath);
121
+ }
122
+ }
88
123
  const missing = allDependencies.filter((dep)=>dep.missing);
89
124
  if (missing.length > 0) {
90
125
  const names = missing.map((dep)=>dep.name).join(", ");
91
126
  throw new ForgeError(`Missing packages in project "${project.name}": ${names}`);
92
127
  }
93
128
  const resolved = allDependencies.filter((dep)=>!dep.missing);
129
+ // A configuration that packs is the published shape: its files ship, so a package they
130
+ // import that the root keeps for development would be missing for the consumer.
131
+ if (project.configuration.pack === true) {
132
+ const devOnly = resolved.filter((dep)=>dep.isDev && !dep.internal);
133
+ if (devOnly.length > 0) {
134
+ const lines = devOnly.map((dep)=>` - ${dep.name}, imported by ${[
135
+ ...importedBy.get(dep.name) ?? []
136
+ ].sort().join(", ")}`);
137
+ throw new ForgeError(`${project.name} ships code that imports packages the root lists only as a devDependency:\n` + `${lines.join("\n")}\n` + "Move each to the root's dependencies, or, if the consumer provides it, " + `declare it in ${project.name}'s peerDependencies.`);
138
+ }
139
+ }
94
140
  const dependencies = Object.fromEntries(resolved.filter((dep)=>!dep.isDev).map((dep)=>[
95
141
  dep.name,
96
142
  dep.version
@@ -158,5 +204,3 @@ export class DependencyResolver {
158
204
  DependencyResolver = _ts_decorate([
159
205
  injectable()
160
206
  ], DependencyResolver);
161
-
162
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi9ob21lL3J1bm5lci93b3JrL2RlY29oZXJlL2RlY29oZXJlL3Byb2plY3RzL2ZvcmdlL3NyYy9zZXJ2aWNlcy9kZXBlbmRlbmN5LXJlc29sdmVyLnNlcnZpY2UudHMiXSwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgaW5qZWN0YWJsZSB9IGZyb20gXCJAZGVjb2hlcmUvY3J1Y2libGUvZGVjb3JhdG9yc1wiO1xuaW1wb3J0IHR5cGUgeyBQYWNrYWdlSnNvbiwgUHJvamVjdCwgV29ya3NwYWNlIH0gZnJvbSBcIkBkZWNvaGVyZS9tZXNoXCI7XG5pbXBvcnQgeyB0eXBlIEZpbGVFeCwgaW8gfSBmcm9tIFwiQGRlY29oZXJlL25leHVzL2lvXCI7XG5pbXBvcnQgeyBwYXJzZUltcG9ydHMgfSBmcm9tIFwicGFyc2UtaW1wb3J0c1wiO1xuaW1wb3J0IHsgQlVJTFRfSU5fTU9EVUxFUyB9IGZyb20gXCIuLi9jb25zdC5qc1wiO1xuaW1wb3J0IHsgRm9yZ2VFcnJvciB9IGZyb20gXCIuLi9lcnJvcnMuanNcIjtcbmltcG9ydCB0eXBlIHtcblx0RGVwZW5kZW5jeVdhcm5pbmcsXG5cdERyaWZ0RW50cnksXG5cdFBhY2thZ2UsXG5cdFJlc29sdmVkRGVwZW5kZW5jeSxcbn0gZnJvbSBcIi4uL3R5cGVzL2RlcGVuZGVuY3kudHlwZXMuanNcIjtcblxuZXhwb3J0IHR5cGUgUHJvamVjdERlcGVuZGVuY2llcyA9IHtcblx0cHJvamVjdDogUHJvamVjdDtcblx0dXBkYXRlZFBhY2thZ2U6IFBhY2thZ2VKc29uO1xuXHR3YXJuaW5nczogRGVwZW5kZW5jeVdhcm5pbmdbXTtcbn07XG5cbkBpbmplY3RhYmxlKClcbmV4cG9ydCBjbGFzcyBEZXBlbmRlbmN5UmVzb2x2ZXIge1xuXHRwdWJsaWMgY29tcHV0ZURyaWZ0KGN1cnJlbnQ6IFBhY2thZ2VKc29uLCBjb21wdXRlZDogUGFja2FnZUpzb24pOiBEcmlmdEVudHJ5IHwgbnVsbCB7XG5cdFx0Y29uc3Qgc29ydEtleXMgPSAob2JqOiBSZWNvcmQ8c3RyaW5nLCBzdHJpbmc+KSA9PlxuXHRcdFx0T2JqZWN0LmZyb21FbnRyaWVzKE9iamVjdC5lbnRyaWVzKG9iaikuc29ydCgpKTtcblxuXHRcdGNvbnN0IGN1cnJlbnREZXBzID0gc29ydEtleXMoY3VycmVudC5kZXBlbmRlbmNpZXMgPz8ge30pO1xuXHRcdGNvbnN0IGNvbXB1dGVkRGVwcyA9IHNvcnRLZXlzKGNvbXB1dGVkLmRlcGVuZGVuY2llcyA/PyB7fSk7XG5cdFx0Y29uc3QgY3VycmVudERldkRlcHMgPSBzb3J0S2V5cyhjdXJyZW50LmRldkRlcGVuZGVuY2llcyA/PyB7fSk7XG5cdFx0Y29uc3QgY29tcHV0ZWREZXZEZXBzID0gc29ydEtleXMoY29tcHV0ZWQuZGV2RGVwZW5kZW5jaWVzID8/IHt9KTtcblxuXHRcdGNvbnN0IGhhc0RyaWZ0ID1cblx0XHRcdEpTT04uc3RyaW5naWZ5KGN1cnJlbnREZXBzKSAhPT0gSlNPTi5zdHJpbmdpZnkoY29tcHV0ZWREZXBzKSB8fFxuXHRcdFx0SlNPTi5zdHJpbmdpZnkoY3VycmVudERldkRlcHMpICE9PSBKU09OLnN0cmluZ2lmeShjb21wdXRlZERldkRlcHMpO1xuXG5cdFx0aWYgKCFoYXNEcmlmdCkge1xuXHRcdFx0cmV0dXJuIG51bGw7XG5cdFx0fVxuXG5cdFx0cmV0dXJuIHtcblx0XHRcdG9yaWdpbmFsOiB7IGRlcGVuZGVuY2llczogY3VycmVudERlcHMsIGRldkRlcGVuZGVuY2llczogY3VycmVudERldkRlcHMgfSxcblx0XHRcdHVwZGF0ZWQ6IHsgZGVwZW5kZW5jaWVzOiBjb21wdXRlZERlcHMsIGRldkRlcGVuZGVuY2llczogY29tcHV0ZWREZXZEZXBzIH0sXG5cdFx0fTtcblx0fVxuXG5cdHB1YmxpYyBhc3luYyBnZXRXb3Jrc3BhY2VQYWNrYWdlcyhcblx0XHR3b3Jrc3BhY2U6IFdvcmtzcGFjZSxcblx0XHRwcm9qZWN0czogcmVhZG9ubHkgUHJvamVjdFtdLFxuXHQpOiBQcm9taXNlPE1hcDxzdHJpbmcsIFBhY2thZ2U+PiB7XG5cdFx0Y29uc3QgcGFja2FnZUpzb24gPSBhd2FpdCB3b3Jrc3BhY2UuZ2V0UGFja2FnZUpzb24oKS5jYXRjaCgoKSA9PiB7XG5cdFx0XHR0aHJvdyBuZXcgRXJyb3IoXG5cdFx0XHRcdGBSb290IHBhY2thZ2UuanNvbiBub3QgZm91bmQgYXQgXCIke3dvcmtzcGFjZS5wYWNrYWdlSnNvbkRpcmVjdG9yeX0vcGFja2FnZS5qc29uXCIuIGAgK1xuXHRcdFx0XHRcdGBFbnN1cmUgdGhlIHdvcmtzcGFjZSByb290IGhhcyBhIHBhY2thZ2UuanNvbiB3aXRoIGRlcGVuZGVuY2llcyBsaXN0ZWQuYCxcblx0XHRcdCk7XG5cdFx0fSk7XG5cblx0XHRjb25zdCBpbnRlcm5hbHMgPSBuZXcgTWFwKFxuXHRcdFx0YXdhaXQgUHJvbWlzZS5hbGwoXG5cdFx0XHRcdHByb2plY3RzLm1hcChhc3luYyAocHJvaik6IFByb21pc2U8W3N0cmluZywgUGFja2FnZV0+ID0+IHtcblx0XHRcdFx0XHRjb25zdCBwYWNrYWdlSnNvbiA9IGF3YWl0IHByb2ouZ2V0UGFja2FnZUpzb24oKTtcblx0XHRcdFx0XHRyZXR1cm4gW1xuXHRcdFx0XHRcdFx0cGFja2FnZUpzb24ubmFtZSxcblx0XHRcdFx0XHRcdHtcblx0XHRcdFx0XHRcdFx0bmFtZTogcGFja2FnZUpzb24ubmFtZSxcblx0XHRcdFx0XHRcdFx0dmVyc2lvbjogcGFja2FnZUpzb24udmVyc2lvbixcblx0XHRcdFx0XHRcdFx0aXNJbnRlcm5hbDogdHJ1ZSxcblx0XHRcdFx0XHRcdH0sXG5cdFx0XHRcdFx0XTtcblx0XHRcdFx0fSksXG5cdFx0XHQpLFxuXHRcdCk7XG5cblx0XHRjb25zdCBwYWNrYWdlcyA9IE9iamVjdC5lbnRyaWVzKHBhY2thZ2VKc29uLmRlcGVuZGVuY2llcylcblx0XHRcdC5maWx0ZXIoKFtrZXldKSA9PiAhaW50ZXJuYWxzLmhhcyhrZXkpKVxuXHRcdFx0Lm1hcDxbc3RyaW5nLCBQYWNrYWdlXT4oKFtrZXksIHZhbF0pID0+IFtrZXksIHsgbmFtZToga2V5LCB2ZXJzaW9uOiB2YWwgfV0pO1xuXG5cdFx0Y29uc3QgZGV2UGFja2FnZXMgPSBPYmplY3QuZW50cmllcyhwYWNrYWdlSnNvbi5kZXZEZXBlbmRlbmNpZXMpXG5cdFx0XHQuZmlsdGVyKChba2V5XSkgPT4gIWludGVybmFscy5oYXMoa2V5KSlcblx0XHRcdC5tYXA8W3N0cmluZywgUGFja2FnZV0+KChba2V5LCB2YWxdKSA9PiBba2V5LCB7IG5hbWU6IGtleSwgdmVyc2lvbjogdmFsLCBpc0RldjogdHJ1ZSB9XSk7XG5cblx0XHRyZXR1cm4gbmV3IE1hcChbLi4ucGFja2FnZXMsIC4uLmRldlBhY2thZ2VzLCAuLi5pbnRlcm5hbHNdKTtcblx0fVxuXG5cdHB1YmxpYyBhc3luYyBjb21wdXRlUHJvamVjdERlcGVuZGVuY2llcyhcblx0XHRwcm9qZWN0OiBQcm9qZWN0LFxuXHRcdHdvcmtzcGFjZVBhY2thZ2VzOiBNYXA8c3RyaW5nLCBQYWNrYWdlPixcblx0KTogUHJvbWlzZTxQcm9qZWN0RGVwZW5kZW5jaWVzPiB7XG5cdFx0Y29uc3QgeyBkZXBlbmRlbmNpZXMsIGRldkRlcGVuZGVuY2llcywgd2FybmluZ3MgfSA9IGF3YWl0IHRoaXMuZ2V0RGVwZW5kZW5jaWVzKFxuXHRcdFx0cHJvamVjdCxcblx0XHRcdHdvcmtzcGFjZVBhY2thZ2VzLFxuXHRcdCk7XG5cblx0XHRjb25zdCBwa2cgPSBhd2FpdCBwcm9qZWN0LmdldFBhY2thZ2VKc29uKCk7XG5cdFx0Y29uc3QgdXBkYXRlZFBhY2thZ2UgPSBwa2dcblx0XHRcdC53aXRoRGVwZW5kZW5jaWVzKGRlcGVuZGVuY2llcylcblx0XHRcdC53aXRoRGV2RGVwZW5kZW5jaWVzKGRldkRlcGVuZGVuY2llcyk7XG5cblx0XHRyZXR1cm4geyBwcm9qZWN0LCB1cGRhdGVkUGFja2FnZSwgd2FybmluZ3MgfTtcblx0fVxuXG5cdHByaXZhdGUgYXN5bmMgZ2V0RGVwZW5kZW5jaWVzKHByb2plY3Q6IFByb2plY3QsIHdvcmtzcGFjZVBhY2thZ2VzOiBNYXA8c3RyaW5nLCBQYWNrYWdlPikge1xuXHRcdGNvbnN0IGZpbGVzID0gYXdhaXQgcHJvamVjdC5nZXRBbGxGaWxlcygpO1xuXHRcdGNvbnN0IHJlc3VsdHMgPSBhd2FpdCBQcm9taXNlLmFsbChmaWxlcy5tYXAoKGZpbGUpID0+IHRoaXMuZ2V0RmlsZUltcG9ydHMoZmlsZSkpKTtcblx0XHRjb25zdCBpbXBvcnRzID0gcmVzdWx0cy5mbGF0TWFwKChyKSA9PiByLmltcG9ydHMpO1xuXHRcdGNvbnN0IHdhcm5pbmdzID0gcmVzdWx0cy5mbGF0TWFwKChyKSA9PiByLndhcm5pbmdzKTtcblxuXHRcdGNvbnN0IGFsbERlcGVuZGVuY2llcyA9IFsuLi5uZXcgU2V0KGltcG9ydHMpXVxuXHRcdFx0Lm1hcCgoZmlsZUltcG9ydCkgPT4gdGhpcy5nZXREZXBlbmRlbmN5RnJvbShmaWxlSW1wb3J0LCB3b3Jrc3BhY2VQYWNrYWdlcykpXG5cdFx0XHQuZmlsdGVyKChkZXApID0+IGRlcCAhPSBudWxsKTtcblxuXHRcdGNvbnN0IG1pc3NpbmcgPSBhbGxEZXBlbmRlbmNpZXMuZmlsdGVyKFxuXHRcdFx0KGRlcCk6IGRlcCBpcyBSZXNvbHZlZERlcGVuZGVuY3kgJiB7IG1pc3Npbmc6IHRydWUgfSA9PiBkZXAubWlzc2luZyxcblx0XHQpO1xuXG5cdFx0aWYgKG1pc3NpbmcubGVuZ3RoID4gMCkge1xuXHRcdFx0Y29uc3QgbmFtZXMgPSBtaXNzaW5nLm1hcCgoZGVwKSA9PiBkZXAubmFtZSkuam9pbihcIiwgXCIpO1xuXHRcdFx0dGhyb3cgbmV3IEZvcmdlRXJyb3IoYE1pc3NpbmcgcGFja2FnZXMgaW4gcHJvamVjdCBcIiR7cHJvamVjdC5uYW1lfVwiOiAke25hbWVzfWApO1xuXHRcdH1cblxuXHRcdGNvbnN0IHJlc29sdmVkID0gYWxsRGVwZW5kZW5jaWVzLmZpbHRlcihcblx0XHRcdChkZXApOiBkZXAgaXMgUmVzb2x2ZWREZXBlbmRlbmN5ICYgeyBtaXNzaW5nOiBmYWxzZSB9ID0+ICFkZXAubWlzc2luZyxcblx0XHQpO1xuXG5cdFx0Y29uc3QgZGVwZW5kZW5jaWVzID0gT2JqZWN0LmZyb21FbnRyaWVzKFxuXHRcdFx0cmVzb2x2ZWRcblx0XHRcdFx0LmZpbHRlcigoZGVwKSA9PiAhZGVwLmlzRGV2KVxuXHRcdFx0XHQubWFwPFtzdHJpbmcsIHN0cmluZ10+KChkZXApID0+IFtkZXAubmFtZSwgZGVwLnZlcnNpb25dKSxcblx0XHQpO1xuXG5cdFx0Y29uc3QgZGV2RGVwZW5kZW5jaWVzID0gT2JqZWN0LmZyb21FbnRyaWVzKFxuXHRcdFx0cmVzb2x2ZWRcblx0XHRcdFx0LmZpbHRlcigoZGVwKSA9PiBkZXAuaXNEZXYpXG5cdFx0XHRcdC5tYXA8W3N0cmluZywgc3RyaW5nXT4oKGRlcCkgPT4gW2RlcC5uYW1lLCBkZXAudmVyc2lvbl0pLFxuXHRcdCk7XG5cblx0XHRyZXR1cm4geyBkZXBlbmRlbmNpZXMsIGRldkRlcGVuZGVuY2llcywgd2FybmluZ3MgfTtcblx0fVxuXG5cdHByaXZhdGUgZ2V0RGVwZW5kZW5jeUZyb20oXG5cdFx0aW1wb3J0TmFtZTogc3RyaW5nLFxuXHRcdHdvcmtzcGFjZVBhY2thZ2VzOiBNYXA8c3RyaW5nLCBQYWNrYWdlPixcblx0KTogUmVzb2x2ZWREZXBlbmRlbmN5IHwgdW5kZWZpbmVkIHtcblx0XHRpZiAoaW1wb3J0TmFtZS5zdGFydHNXaXRoKFwiLlwiKSB8fCBpbXBvcnROYW1lLnN0YXJ0c1dpdGgoXCJub2RlOlwiKSkge1xuXHRcdFx0cmV0dXJuO1xuXHRcdH1cblxuXHRcdGNvbnN0IHBhY2thZ2VOYW1lTWF0Y2ggPSBpbXBvcnROYW1lLm1hdGNoKC9eKD86KEBbXi9dK1xcL1teL10rKXwoW14vXSspKS8pO1xuXHRcdGNvbnN0IHBhY2thZ2VOYW1lID0gcGFja2FnZU5hbWVNYXRjaD8uWzBdO1xuXG5cdFx0aWYgKHBhY2thZ2VOYW1lID09IG51bGwgfHwgQlVJTFRfSU5fTU9EVUxFUy5pbmNsdWRlcyhwYWNrYWdlTmFtZSkpIHtcblx0XHRcdHJldHVybjtcblx0XHR9XG5cblx0XHRjb25zdCBwYWNrZyA9IHdvcmtzcGFjZVBhY2thZ2VzLmdldChwYWNrYWdlTmFtZSk7XG5cblx0XHRpZiAocGFja2cgPT0gbnVsbCkge1xuXHRcdFx0cmV0dXJuIHtcblx0XHRcdFx0bmFtZTogcGFja2FnZU5hbWUsXG5cdFx0XHRcdHZlcnNpb246IHVuZGVmaW5lZCxcblx0XHRcdFx0aW50ZXJuYWw6IHVuZGVmaW5lZCxcblx0XHRcdFx0bWlzc2luZzogdHJ1ZSxcblx0XHRcdFx0aXNEZXY6IGZhbHNlLFxuXHRcdFx0fTtcblx0XHR9XG5cblx0XHRyZXR1cm4ge1xuXHRcdFx0bmFtZTogcGFja2FnZU5hbWUsXG5cdFx0XHR2ZXJzaW9uOiBwYWNrZy52ZXJzaW9uID8/IFwiXCIsXG5cdFx0XHRpbnRlcm5hbDogcGFja2cuaXNJbnRlcm5hbCA/PyBmYWxzZSxcblx0XHRcdG1pc3Npbmc6IGZhbHNlLFxuXHRcdFx0aXNEZXY6IHBhY2tnLmlzRGV2ID8/IGZhbHNlLFxuXHRcdH07XG5cdH1cblxuXHRwcml2YXRlIGFzeW5jIGdldEZpbGVJbXBvcnRzKFxuXHRcdGZpbGU6IEZpbGVFeCxcblx0KTogUHJvbWlzZTx7IGltcG9ydHM6IHN0cmluZ1tdOyB3YXJuaW5nczogRGVwZW5kZW5jeVdhcm5pbmdbXSB9PiB7XG5cdFx0Y29uc3QgY29udGVudHMgPSBhd2FpdCBpby5yZWFkRmlsZShmaWxlLmZ1bGxQYXRoKTtcblx0XHRjb25zdCBwYXJzZWQgPSBBcnJheS5mcm9tKGF3YWl0IHBhcnNlSW1wb3J0cyhjb250ZW50cykpO1xuXG5cdFx0Y29uc3QgaW1wb3J0czogc3RyaW5nW10gPSBbXTtcblx0XHRjb25zdCB3YXJuaW5nczogRGVwZW5kZW5jeVdhcm5pbmdbXSA9IFtdO1xuXG5cdFx0Zm9yIChjb25zdCBpbXB0IG9mIHBhcnNlZCkge1xuXHRcdFx0aWYgKGltcHQubW9kdWxlU3BlY2lmaWVyLnZhbHVlICE9IG51bGwpIHtcblx0XHRcdFx0aW1wb3J0cy5wdXNoKGltcHQubW9kdWxlU3BlY2lmaWVyLnZhbHVlKTtcblx0XHRcdH0gZWxzZSBpZiAoaW1wdC5pc0R5bmFtaWNJbXBvcnQpIHtcblx0XHRcdFx0Y29uc3QgbGluZSA9IGNvbnRlbnRzLnN1YnN0cmluZygwLCBpbXB0LnN0YXJ0SW5kZXgpLnNwbGl0KFwiXFxuXCIpLmxlbmd0aDtcblx0XHRcdFx0d2FybmluZ3MucHVzaCh7XG5cdFx0XHRcdFx0ZmlsZTogZmlsZS5mdWxsUGF0aCxcblx0XHRcdFx0XHRsaW5lLFxuXHRcdFx0XHRcdG1lc3NhZ2U6IGBEeW5hbWljIGltcG9ydCB3aXRoIG5vbi1saXRlcmFsIHNwZWNpZmllciBcXGAke2ltcHQubW9kdWxlU3BlY2lmaWVyLmNvZGV9XFxgIGNhbm5vdCBiZSBzdGF0aWNhbGx5IHJlc29sdmVkYCxcblx0XHRcdFx0fSk7XG5cdFx0XHR9XG5cdFx0fVxuXG5cdFx0cmV0dXJuIHsgaW1wb3J0cywgd2FybmluZ3MgfTtcblx0fVxufVxuIl0sIm5hbWVzIjpbImluamVjdGFibGUiLCJpbyIsInBhcnNlSW1wb3J0cyIsIkJVSUxUX0lOX01PRFVMRVMiLCJGb3JnZUVycm9yIiwiRGVwZW5kZW5jeVJlc29sdmVyIiwiY29tcHV0ZURyaWZ0IiwiY3VycmVudCIsImNvbXB1dGVkIiwic29ydEtleXMiLCJvYmoiLCJPYmplY3QiLCJmcm9tRW50cmllcyIsImVudHJpZXMiLCJzb3J0IiwiY3VycmVudERlcHMiLCJkZXBlbmRlbmNpZXMiLCJjb21wdXRlZERlcHMiLCJjdXJyZW50RGV2RGVwcyIsImRldkRlcGVuZGVuY2llcyIsImNvbXB1dGVkRGV2RGVwcyIsImhhc0RyaWZ0IiwiSlNPTiIsInN0cmluZ2lmeSIsIm9yaWdpbmFsIiwidXBkYXRlZCIsImdldFdvcmtzcGFjZVBhY2thZ2VzIiwid29ya3NwYWNlIiwicHJvamVjdHMiLCJwYWNrYWdlSnNvbiIsImdldFBhY2thZ2VKc29uIiwiY2F0Y2giLCJFcnJvciIsInBhY2thZ2VKc29uRGlyZWN0b3J5IiwiaW50ZXJuYWxzIiwiTWFwIiwiUHJvbWlzZSIsImFsbCIsIm1hcCIsInByb2oiLCJuYW1lIiwidmVyc2lvbiIsImlzSW50ZXJuYWwiLCJwYWNrYWdlcyIsImZpbHRlciIsImtleSIsImhhcyIsInZhbCIsImRldlBhY2thZ2VzIiwiaXNEZXYiLCJjb21wdXRlUHJvamVjdERlcGVuZGVuY2llcyIsInByb2plY3QiLCJ3b3Jrc3BhY2VQYWNrYWdlcyIsIndhcm5pbmdzIiwiZ2V0RGVwZW5kZW5jaWVzIiwicGtnIiwidXBkYXRlZFBhY2thZ2UiLCJ3aXRoRGVwZW5kZW5jaWVzIiwid2l0aERldkRlcGVuZGVuY2llcyIsImZpbGVzIiwiZ2V0QWxsRmlsZXMiLCJyZXN1bHRzIiwiZmlsZSIsImdldEZpbGVJbXBvcnRzIiwiaW1wb3J0cyIsImZsYXRNYXAiLCJyIiwiYWxsRGVwZW5kZW5jaWVzIiwiU2V0IiwiZmlsZUltcG9ydCIsImdldERlcGVuZGVuY3lGcm9tIiwiZGVwIiwibWlzc2luZyIsImxlbmd0aCIsIm5hbWVzIiwiam9pbiIsInJlc29sdmVkIiwiaW1wb3J0TmFtZSIsInN0YXJ0c1dpdGgiLCJwYWNrYWdlTmFtZU1hdGNoIiwibWF0Y2giLCJwYWNrYWdlTmFtZSIsImluY2x1ZGVzIiwicGFja2ciLCJnZXQiLCJ1bmRlZmluZWQiLCJpbnRlcm5hbCIsImNvbnRlbnRzIiwicmVhZEZpbGUiLCJmdWxsUGF0aCIsInBhcnNlZCIsIkFycmF5IiwiZnJvbSIsImltcHQiLCJtb2R1bGVTcGVjaWZpZXIiLCJ2YWx1ZSIsInB1c2giLCJpc0R5bmFtaWNJbXBvcnQiLCJsaW5lIiwic3Vic3RyaW5nIiwic3RhcnRJbmRleCIsInNwbGl0IiwibWVzc2FnZSIsImNvZGUiXSwibWFwcGluZ3MiOiI7Ozs7OztBQUFBLFNBQVNBLFVBQVUsUUFBUSxnQ0FBZ0M7QUFFM0QsU0FBc0JDLEVBQUUsUUFBUSxxQkFBcUI7QUFDckQsU0FBU0MsWUFBWSxRQUFRLGdCQUFnQjtBQUM3QyxTQUFTQyxnQkFBZ0IsUUFBUSxjQUFjO0FBQy9DLFNBQVNDLFVBQVUsUUFBUSxlQUFlO0FBZTFDLE9BQU8sTUFBTUM7SUFDTEMsYUFBYUMsT0FBb0IsRUFBRUMsUUFBcUIsRUFBcUI7UUFDbkYsTUFBTUMsV0FBVyxDQUFDQyxNQUNqQkMsT0FBT0MsV0FBVyxDQUFDRCxPQUFPRSxPQUFPLENBQUNILEtBQUtJLElBQUk7UUFFNUMsTUFBTUMsY0FBY04sU0FBU0YsUUFBUVMsWUFBWSxJQUFJLENBQUM7UUFDdEQsTUFBTUMsZUFBZVIsU0FBU0QsU0FBU1EsWUFBWSxJQUFJLENBQUM7UUFDeEQsTUFBTUUsaUJBQWlCVCxTQUFTRixRQUFRWSxlQUFlLElBQUksQ0FBQztRQUM1RCxNQUFNQyxrQkFBa0JYLFNBQVNELFNBQVNXLGVBQWUsSUFBSSxDQUFDO1FBRTlELE1BQU1FLFdBQ0xDLEtBQUtDLFNBQVMsQ0FBQ1IsaUJBQWlCTyxLQUFLQyxTQUFTLENBQUNOLGlCQUMvQ0ssS0FBS0MsU0FBUyxDQUFDTCxvQkFBb0JJLEtBQUtDLFNBQVMsQ0FBQ0g7UUFFbkQsSUFBSSxDQUFDQyxVQUFVO1lBQ2QsT0FBTztRQUNSO1FBRUEsT0FBTztZQUNORyxVQUFVO2dCQUFFUixjQUFjRDtnQkFBYUksaUJBQWlCRDtZQUFlO1lBQ3ZFTyxTQUFTO2dCQUFFVCxjQUFjQztnQkFBY0UsaUJBQWlCQztZQUFnQjtRQUN6RTtJQUNEO0lBRUEsTUFBYU0scUJBQ1pDLFNBQW9CLEVBQ3BCQyxRQUE0QixFQUNJO1FBQ2hDLE1BQU1DLGNBQWMsTUFBTUYsVUFBVUcsY0FBYyxHQUFHQyxLQUFLLENBQUM7WUFDMUQsTUFBTSxJQUFJQyxNQUNULENBQUMsZ0NBQWdDLEVBQUVMLFVBQVVNLG9CQUFvQixDQUFDLGdCQUFnQixDQUFDLEdBQ2xGLENBQUMsc0VBQXNFLENBQUM7UUFFM0U7UUFFQSxNQUFNQyxZQUFZLElBQUlDLElBQ3JCLE1BQU1DLFFBQVFDLEdBQUcsQ0FDaEJULFNBQVNVLEdBQUcsQ0FBQyxPQUFPQztZQUNuQixNQUFNVixjQUFjLE1BQU1VLEtBQUtULGNBQWM7WUFDN0MsT0FBTztnQkFDTkQsWUFBWVcsSUFBSTtnQkFDaEI7b0JBQ0NBLE1BQU1YLFlBQVlXLElBQUk7b0JBQ3RCQyxTQUFTWixZQUFZWSxPQUFPO29CQUM1QkMsWUFBWTtnQkFDYjthQUNBO1FBQ0Y7UUFJRixNQUFNQyxXQUFXaEMsT0FBT0UsT0FBTyxDQUFDZ0IsWUFBWWIsWUFBWSxFQUN0RDRCLE1BQU0sQ0FBQyxDQUFDLENBQUNDLElBQUksR0FBSyxDQUFDWCxVQUFVWSxHQUFHLENBQUNELE1BQ2pDUCxHQUFHLENBQW9CLENBQUMsQ0FBQ08sS0FBS0UsSUFBSSxHQUFLO2dCQUFDRjtnQkFBSztvQkFBRUwsTUFBTUs7b0JBQUtKLFNBQVNNO2dCQUFJO2FBQUU7UUFFM0UsTUFBTUMsY0FBY3JDLE9BQU9FLE9BQU8sQ0FBQ2dCLFlBQVlWLGVBQWUsRUFDNUR5QixNQUFNLENBQUMsQ0FBQyxDQUFDQyxJQUFJLEdBQUssQ0FBQ1gsVUFBVVksR0FBRyxDQUFDRCxNQUNqQ1AsR0FBRyxDQUFvQixDQUFDLENBQUNPLEtBQUtFLElBQUksR0FBSztnQkFBQ0Y7Z0JBQUs7b0JBQUVMLE1BQU1LO29CQUFLSixTQUFTTTtvQkFBS0UsT0FBTztnQkFBSzthQUFFO1FBRXhGLE9BQU8sSUFBSWQsSUFBSTtlQUFJUTtlQUFhSztlQUFnQmQ7U0FBVTtJQUMzRDtJQUVBLE1BQWFnQiwyQkFDWkMsT0FBZ0IsRUFDaEJDLGlCQUF1QyxFQUNSO1FBQy9CLE1BQU0sRUFBRXBDLFlBQVksRUFBRUcsZUFBZSxFQUFFa0MsUUFBUSxFQUFFLEdBQUcsTUFBTSxJQUFJLENBQUNDLGVBQWUsQ0FDN0VILFNBQ0FDO1FBR0QsTUFBTUcsTUFBTSxNQUFNSixRQUFRckIsY0FBYztRQUN4QyxNQUFNMEIsaUJBQWlCRCxJQUNyQkUsZ0JBQWdCLENBQUN6QyxjQUNqQjBDLG1CQUFtQixDQUFDdkM7UUFFdEIsT0FBTztZQUFFZ0M7WUFBU0s7WUFBZ0JIO1FBQVM7SUFDNUM7SUFFQSxNQUFjQyxnQkFBZ0JILE9BQWdCLEVBQUVDLGlCQUF1QyxFQUFFO1FBQ3hGLE1BQU1PLFFBQVEsTUFBTVIsUUFBUVMsV0FBVztRQUN2QyxNQUFNQyxVQUFVLE1BQU16QixRQUFRQyxHQUFHLENBQUNzQixNQUFNckIsR0FBRyxDQUFDLENBQUN3QixPQUFTLElBQUksQ0FBQ0MsY0FBYyxDQUFDRDtRQUMxRSxNQUFNRSxVQUFVSCxRQUFRSSxPQUFPLENBQUMsQ0FBQ0MsSUFBTUEsRUFBRUYsT0FBTztRQUNoRCxNQUFNWCxXQUFXUSxRQUFRSSxPQUFPLENBQUMsQ0FBQ0MsSUFBTUEsRUFBRWIsUUFBUTtRQUVsRCxNQUFNYyxrQkFBa0I7ZUFBSSxJQUFJQyxJQUFJSjtTQUFTLENBQzNDMUIsR0FBRyxDQUFDLENBQUMrQixhQUFlLElBQUksQ0FBQ0MsaUJBQWlCLENBQUNELFlBQVlqQixvQkFDdkRSLE1BQU0sQ0FBQyxDQUFDMkIsTUFBUUEsT0FBTztRQUV6QixNQUFNQyxVQUFVTCxnQkFBZ0J2QixNQUFNLENBQ3JDLENBQUMyQixNQUF1REEsSUFBSUMsT0FBTztRQUdwRSxJQUFJQSxRQUFRQyxNQUFNLEdBQUcsR0FBRztZQUN2QixNQUFNQyxRQUFRRixRQUFRbEMsR0FBRyxDQUFDLENBQUNpQyxNQUFRQSxJQUFJL0IsSUFBSSxFQUFFbUMsSUFBSSxDQUFDO1lBQ2xELE1BQU0sSUFBSXZFLFdBQVcsQ0FBQyw2QkFBNkIsRUFBRStDLFFBQVFYLElBQUksQ0FBQyxHQUFHLEVBQUVrQyxPQUFPO1FBQy9FO1FBRUEsTUFBTUUsV0FBV1QsZ0JBQWdCdkIsTUFBTSxDQUN0QyxDQUFDMkIsTUFBd0QsQ0FBQ0EsSUFBSUMsT0FBTztRQUd0RSxNQUFNeEQsZUFBZUwsT0FBT0MsV0FBVyxDQUN0Q2dFLFNBQ0VoQyxNQUFNLENBQUMsQ0FBQzJCLE1BQVEsQ0FBQ0EsSUFBSXRCLEtBQUssRUFDMUJYLEdBQUcsQ0FBbUIsQ0FBQ2lDLE1BQVE7Z0JBQUNBLElBQUkvQixJQUFJO2dCQUFFK0IsSUFBSTlCLE9BQU87YUFBQztRQUd6RCxNQUFNdEIsa0JBQWtCUixPQUFPQyxXQUFXLENBQ3pDZ0UsU0FDRWhDLE1BQU0sQ0FBQyxDQUFDMkIsTUFBUUEsSUFBSXRCLEtBQUssRUFDekJYLEdBQUcsQ0FBbUIsQ0FBQ2lDLE1BQVE7Z0JBQUNBLElBQUkvQixJQUFJO2dCQUFFK0IsSUFBSTlCLE9BQU87YUFBQztRQUd6RCxPQUFPO1lBQUV6QjtZQUFjRztZQUFpQmtDO1FBQVM7SUFDbEQ7SUFFUWlCLGtCQUNQTyxVQUFrQixFQUNsQnpCLGlCQUF1QyxFQUNOO1FBQ2pDLElBQUl5QixXQUFXQyxVQUFVLENBQUMsUUFBUUQsV0FBV0MsVUFBVSxDQUFDLFVBQVU7WUFDakU7UUFDRDtRQUVBLE1BQU1DLG1CQUFtQkYsV0FBV0csS0FBSyxDQUFDO1FBQzFDLE1BQU1DLGNBQWNGLGtCQUFrQixDQUFDLEVBQUU7UUFFekMsSUFBSUUsZUFBZSxRQUFROUUsaUJBQWlCK0UsUUFBUSxDQUFDRCxjQUFjO1lBQ2xFO1FBQ0Q7UUFFQSxNQUFNRSxRQUFRL0Isa0JBQWtCZ0MsR0FBRyxDQUFDSDtRQUVwQyxJQUFJRSxTQUFTLE1BQU07WUFDbEIsT0FBTztnQkFDTjNDLE1BQU15QztnQkFDTnhDLFNBQVM0QztnQkFDVEMsVUFBVUQ7Z0JBQ1ZiLFNBQVM7Z0JBQ1R2QixPQUFPO1lBQ1I7UUFDRDtRQUVBLE9BQU87WUFDTlQsTUFBTXlDO1lBQ054QyxTQUFTMEMsTUFBTTFDLE9BQU8sSUFBSTtZQUMxQjZDLFVBQVVILE1BQU16QyxVQUFVLElBQUk7WUFDOUI4QixTQUFTO1lBQ1R2QixPQUFPa0MsTUFBTWxDLEtBQUssSUFBSTtRQUN2QjtJQUNEO0lBRUEsTUFBY2MsZUFDYkQsSUFBWSxFQUNvRDtRQUNoRSxNQUFNeUIsV0FBVyxNQUFNdEYsR0FBR3VGLFFBQVEsQ0FBQzFCLEtBQUsyQixRQUFRO1FBQ2hELE1BQU1DLFNBQVNDLE1BQU1DLElBQUksQ0FBQyxNQUFNMUYsYUFBYXFGO1FBRTdDLE1BQU12QixVQUFvQixFQUFFO1FBQzVCLE1BQU1YLFdBQWdDLEVBQUU7UUFFeEMsS0FBSyxNQUFNd0MsUUFBUUgsT0FBUTtZQUMxQixJQUFJRyxLQUFLQyxlQUFlLENBQUNDLEtBQUssSUFBSSxNQUFNO2dCQUN2Qy9CLFFBQVFnQyxJQUFJLENBQUNILEtBQUtDLGVBQWUsQ0FBQ0MsS0FBSztZQUN4QyxPQUFPLElBQUlGLEtBQUtJLGVBQWUsRUFBRTtnQkFDaEMsTUFBTUMsT0FBT1gsU0FBU1ksU0FBUyxDQUFDLEdBQUdOLEtBQUtPLFVBQVUsRUFBRUMsS0FBSyxDQUFDLE1BQU01QixNQUFNO2dCQUN0RXBCLFNBQVMyQyxJQUFJLENBQUM7b0JBQ2JsQyxNQUFNQSxLQUFLMkIsUUFBUTtvQkFDbkJTO29CQUNBSSxTQUFTLENBQUMsNENBQTRDLEVBQUVULEtBQUtDLGVBQWUsQ0FBQ1MsSUFBSSxDQUFDLGdDQUFnQyxDQUFDO2dCQUNwSDtZQUNEO1FBQ0Q7UUFFQSxPQUFPO1lBQUV2QztZQUFTWDtRQUFTO0lBQzVCO0FBQ0QifQ==
@@ -6,27 +6,20 @@ function _ts_decorate(decorators, target, key, desc) {
6
6
  }
7
7
  import fs from "node:fs/promises";
8
8
  import { injectable } from "@decohere/crucible/decorators";
9
- import { Trace } from "@decohere/nexus/diagnostics";
10
- import { io } from "@decohere/nexus/io";
9
+ import { Trace } from "@decohere/devkit/diagnostics";
10
+ import { io } from "@decohere/core/io";
11
11
  import "../extensions/project.extensions.js";
12
12
  const DEFAULT_WRITE_CONCURRENCY = 16;
13
13
  export class FileWriterService {
14
14
  #artifactByPath = new Map();
15
15
  #warmupSignature = "";
16
16
  #warmupPromise;
17
- #initialized = false;
18
17
  #pendingWrites = [];
19
18
  #activeWorkers = 0;
20
19
  #drainResolvers = [];
21
20
  #ensuredDirs = new Set();
22
21
  #ensureDirPromises = new Map();
23
22
  #workerError;
24
- async initialize() {
25
- if (this.#initialized) {
26
- return;
27
- }
28
- this.#initialized = true;
29
- }
30
23
  async warmup(projects) {
31
24
  const outputDirs = this.getOutputDirs(projects);
32
25
  const signature = outputDirs.join("|");
@@ -213,5 +206,3 @@ FileWriterService = _ts_decorate([
213
206
  Trace,
214
207
  injectable()
215
208
  ], FileWriterService);
216
-
217
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi9ob21lL3J1bm5lci93b3JrL2RlY29oZXJlL2RlY29oZXJlL3Byb2plY3RzL2ZvcmdlL3NyYy9zZXJ2aWNlcy9maWxlLXdyaXRlci5zZXJ2aWNlLnRzIl0sInNvdXJjZXNDb250ZW50IjpbImltcG9ydCBmcyBmcm9tIFwibm9kZTpmcy9wcm9taXNlc1wiO1xuaW1wb3J0IHsgaW5qZWN0YWJsZSB9IGZyb20gXCJAZGVjb2hlcmUvY3J1Y2libGUvZGVjb3JhdG9yc1wiO1xuaW1wb3J0IHR5cGUgeyBQcm9qZWN0IH0gZnJvbSBcIkBkZWNvaGVyZS9tZXNoXCI7XG5pbXBvcnQgeyBUcmFjZSB9IGZyb20gXCJAZGVjb2hlcmUvbmV4dXMvZGlhZ25vc3RpY3NcIjtcbmltcG9ydCB7IGlvIH0gZnJvbSBcIkBkZWNvaGVyZS9uZXh1cy9pb1wiO1xuaW1wb3J0IFwiLi4vZXh0ZW5zaW9ucy9wcm9qZWN0LmV4dGVuc2lvbnMuanNcIjtcbmltcG9ydCB0eXBlIHsgQnVpbGRUYXJnZXQgfSBmcm9tIFwiLi4vdHlwZXMvYnVpbGQtdGFyZ2V0LnR5cGUuanNcIjtcbmltcG9ydCB0eXBlIHsgVHJhbnNmb3JtUmVzcG9uc2UgfSBmcm9tIFwiLi4vdHlwZXMvdHJhbnNmb3JtLXJlc3BvbnNlLm1vZGVsLmpzXCI7XG5cbmNvbnN0IERFRkFVTFRfV1JJVEVfQ09OQ1VSUkVOQ1kgPSAxNjtcblxuQFRyYWNlXG5AaW5qZWN0YWJsZSgpXG5leHBvcnQgY2xhc3MgRmlsZVdyaXRlclNlcnZpY2Uge1xuXHQjYXJ0aWZhY3RCeVBhdGggPSBuZXcgTWFwPHN0cmluZywgc3RyaW5nPigpO1xuXHQjd2FybXVwU2lnbmF0dXJlID0gXCJcIjtcblx0I3dhcm11cFByb21pc2U6IFByb21pc2U8dm9pZD4gfCB1bmRlZmluZWQ7XG5cdCNpbml0aWFsaXplZCA9IGZhbHNlO1xuXHQjcGVuZGluZ1dyaXRlczogVHJhbnNmb3JtUmVzcG9uc2VbXSA9IFtdO1xuXHQjYWN0aXZlV29ya2VycyA9IDA7XG5cdCNkcmFpblJlc29sdmVyczogQXJyYXk8KCkgPT4gdm9pZD4gPSBbXTtcblx0I2Vuc3VyZWREaXJzID0gbmV3IFNldDxzdHJpbmc+KCk7XG5cdCNlbnN1cmVEaXJQcm9taXNlcyA9IG5ldyBNYXA8c3RyaW5nLCBQcm9taXNlPHZvaWQ+PigpO1xuXHQjd29ya2VyRXJyb3I6IHVua25vd247XG5cblx0cHVibGljIGFzeW5jIGluaXRpYWxpemUoKTogUHJvbWlzZTx2b2lkPiB7XG5cdFx0aWYgKHRoaXMuI2luaXRpYWxpemVkKSB7XG5cdFx0XHRyZXR1cm47XG5cdFx0fVxuXHRcdHRoaXMuI2luaXRpYWxpemVkID0gdHJ1ZTtcblx0fVxuXG5cdHB1YmxpYyBhc3luYyB3YXJtdXAocHJvamVjdHM6IFByb2plY3RbXSk6IFByb21pc2U8dm9pZD4ge1xuXHRcdGNvbnN0IG91dHB1dERpcnMgPSB0aGlzLmdldE91dHB1dERpcnMocHJvamVjdHMpO1xuXHRcdGNvbnN0IHNpZ25hdHVyZSA9IG91dHB1dERpcnMuam9pbihcInxcIik7XG5cdFx0aWYgKHNpZ25hdHVyZSA9PT0gdGhpcy4jd2FybXVwU2lnbmF0dXJlICYmIHRoaXMuI3dhcm11cFByb21pc2UgIT0gbnVsbCkge1xuXHRcdFx0cmV0dXJuIHRoaXMuI3dhcm11cFByb21pc2U7XG5cdFx0fVxuXG5cdFx0dGhpcy4jd2FybXVwU2lnbmF0dXJlID0gc2lnbmF0dXJlO1xuXHRcdHRoaXMuI2Vuc3VyZWREaXJzLmNsZWFyKCk7XG5cdFx0dGhpcy4jZW5zdXJlRGlyUHJvbWlzZXMuY2xlYXIoKTtcblx0XHR0aGlzLiN3b3JrZXJFcnJvciA9IHVuZGVmaW5lZDtcblx0XHR0aGlzLiN3YXJtdXBQcm9taXNlID0gdGhpcy5sb2FkRXhpc3RpbmdBcnRpZmFjdHMob3V0cHV0RGlycyk7XG5cdFx0cmV0dXJuIHRoaXMuI3dhcm11cFByb21pc2U7XG5cdH1cblxuXHRwdWJsaWMgZW5xdWV1ZU91dHB1dChyZXNwb25zZTogVHJhbnNmb3JtUmVzcG9uc2UpOiB2b2lkIHtcblx0XHRpZiAodGhpcy4jd29ya2VyRXJyb3IgIT0gbnVsbCkge1xuXHRcdFx0cmV0dXJuO1xuXHRcdH1cblx0XHRpZiAocmVzcG9uc2Uub3V0Y29tZSAhPT0gXCJzdWNjZXNzXCIgfHwgcmVzcG9uc2Uub3V0cHV0UGF0aCA9PSBudWxsKSB7XG5cdFx0XHRyZXR1cm47XG5cdFx0fVxuXHRcdHRoaXMuI3BlbmRpbmdXcml0ZXMucHVzaChyZXNwb25zZSk7XG5cdFx0dGhpcy5zdGFydFdvcmtlcnMoKTtcblx0fVxuXG5cdHB1YmxpYyBlbnF1ZXVlT3V0cHV0cyhyZXNwb25zZXM6IFRyYW5zZm9ybVJlc3BvbnNlW10pOiB2b2lkIHtcblx0XHRmb3IgKGNvbnN0IHJlc3BvbnNlIG9mIHJlc3BvbnNlcykge1xuXHRcdFx0dGhpcy5lbnF1ZXVlT3V0cHV0KHJlc3BvbnNlKTtcblx0XHR9XG5cdH1cblxuXHRwdWJsaWMgYXN5bmMgZmx1c2goKTogUHJvbWlzZTx2b2lkPiB7XG5cdFx0aWYgKHRoaXMuI3dhcm11cFByb21pc2UgIT0gbnVsbCkge1xuXHRcdFx0YXdhaXQgdGhpcy4jd2FybXVwUHJvbWlzZTtcblx0XHR9XG5cdFx0aWYgKHRoaXMuI3BlbmRpbmdXcml0ZXMubGVuZ3RoID09PSAwICYmIHRoaXMuI2FjdGl2ZVdvcmtlcnMgPT09IDApIHtcblx0XHRcdHJldHVybjtcblx0XHR9XG5cdFx0YXdhaXQgbmV3IFByb21pc2U8dm9pZD4oKHJlc29sdmUpID0+IHtcblx0XHRcdHRoaXMuI2RyYWluUmVzb2x2ZXJzLnB1c2gocmVzb2x2ZSk7XG5cdFx0fSk7XG5cdFx0aWYgKHRoaXMuI3dvcmtlckVycm9yICE9IG51bGwpIHtcblx0XHRcdHRocm93IHRoaXMuI3dvcmtlckVycm9yO1xuXHRcdH1cblx0fVxuXG5cdHByaXZhdGUgZ2V0T3V0cHV0RGlycyhwcm9qZWN0czogUHJvamVjdFtdKTogc3RyaW5nW10ge1xuXHRcdGNvbnN0IGRpcnMgPSBuZXcgU2V0PHN0cmluZz4oKTtcblx0XHRmb3IgKGNvbnN0IHByb2plY3Qgb2YgcHJvamVjdHMpIHtcblx0XHRcdGZvciAoY29uc3QgdGFyZ2V0IG9mIHByb2plY3QuZ2V0Rm9yZ2VDb25maWd1cmF0aW9uKCkudGFyZ2V0cykge1xuXHRcdFx0XHRkaXJzLmFkZChwcm9qZWN0LmdldE91dERpcih0YXJnZXQgYXMgQnVpbGRUYXJnZXQpKTtcblx0XHRcdH1cblx0XHR9XG5cdFx0cmV0dXJuIFsuLi5kaXJzXS5zb3J0KCk7XG5cdH1cblxuXHRwcml2YXRlIGFzeW5jIGxvYWRFeGlzdGluZ0FydGlmYWN0cyhvdXRwdXREaXJzOiBzdHJpbmdbXSk6IFByb21pc2U8dm9pZD4ge1xuXHRcdHRoaXMuI2FydGlmYWN0QnlQYXRoLmNsZWFyKCk7XG5cblx0XHRjb25zdCBmaWxlczogc3RyaW5nW10gPSBbXTtcblx0XHRmb3IgKGNvbnN0IGRpciBvZiBvdXRwdXREaXJzKSB7XG5cdFx0XHRmaWxlcy5wdXNoKC4uLihhd2FpdCB0aGlzLmNvbGxlY3RGaWxlcyhkaXIpKSk7XG5cdFx0fVxuXG5cdFx0YXdhaXQgdGhpcy53aXRoQ29uY3VycmVuY3koZmlsZXMsIHRoaXMuZ2V0V3JpdGVDb25jdXJyZW5jeSgpLCBhc3luYyAoZmlsZVBhdGgpID0+IHtcblx0XHRcdGNvbnN0IGNvbnRlbnQgPSBhd2FpdCBmcy5yZWFkRmlsZShmaWxlUGF0aCwgXCJ1dGY4XCIpO1xuXHRcdFx0dGhpcy4jYXJ0aWZhY3RCeVBhdGguc2V0KGZpbGVQYXRoLCBjb250ZW50KTtcblx0XHR9KTtcblx0fVxuXG5cdHByaXZhdGUgYXN5bmMgY29sbGVjdEZpbGVzKHJvb3REaXI6IHN0cmluZyk6IFByb21pc2U8c3RyaW5nW10+IHtcblx0XHR0cnkge1xuXHRcdFx0Y29uc3QgZW50cmllcyA9IGF3YWl0IGZzLnJlYWRkaXIocm9vdERpciwgeyB3aXRoRmlsZVR5cGVzOiB0cnVlIH0pO1xuXHRcdFx0Y29uc3QgZmlsZXM6IHN0cmluZ1tdID0gW107XG5cdFx0XHRmb3IgKGNvbnN0IGVudHJ5IG9mIGVudHJpZXMpIHtcblx0XHRcdFx0Y29uc3QgZnVsbFBhdGggPSBgJHtyb290RGlyfS8ke2VudHJ5Lm5hbWV9YDtcblx0XHRcdFx0aWYgKGVudHJ5LmlzRGlyZWN0b3J5KCkpIHtcblx0XHRcdFx0XHRmaWxlcy5wdXNoKC4uLihhd2FpdCB0aGlzLmNvbGxlY3RGaWxlcyhmdWxsUGF0aCkpKTtcblx0XHRcdFx0fSBlbHNlIGlmIChlbnRyeS5pc0ZpbGUoKSkge1xuXHRcdFx0XHRcdGZpbGVzLnB1c2goZnVsbFBhdGgpO1xuXHRcdFx0XHR9XG5cdFx0XHR9XG5cdFx0XHRyZXR1cm4gZmlsZXM7XG5cdFx0fSBjYXRjaCB7XG5cdFx0XHRyZXR1cm4gW107XG5cdFx0fVxuXHR9XG5cblx0cHJpdmF0ZSBnZXRXcml0ZUNvbmN1cnJlbmN5KCk6IG51bWJlciB7XG5cdFx0Y29uc3QgcmVxdWVzdGVkID0gTnVtYmVyKHByb2Nlc3MuZW52LkZPUkdFX1dSSVRFX0NPTkNVUlJFTkNZKTtcblx0XHRpZiAoTnVtYmVyLmlzRmluaXRlKHJlcXVlc3RlZCkgJiYgcmVxdWVzdGVkID4gMCkge1xuXHRcdFx0cmV0dXJuIE1hdGguZmxvb3IocmVxdWVzdGVkKTtcblx0XHR9XG5cdFx0cmV0dXJuIERFRkFVTFRfV1JJVEVfQ09OQ1VSUkVOQ1k7XG5cdH1cblxuXHRwcml2YXRlIHN0YXJ0V29ya2VycygpOiB2b2lkIHtcblx0XHRpZiAodGhpcy4jd29ya2VyRXJyb3IgIT0gbnVsbCkge1xuXHRcdFx0cmV0dXJuO1xuXHRcdH1cblx0XHRjb25zdCBtYXhXb3JrZXJzID0gdGhpcy5nZXRXcml0ZUNvbmN1cnJlbmN5KCk7XG5cdFx0d2hpbGUgKHRoaXMuI2FjdGl2ZVdvcmtlcnMgPCBtYXhXb3JrZXJzICYmIHRoaXMuI3BlbmRpbmdXcml0ZXMubGVuZ3RoID4gMCkge1xuXHRcdFx0dGhpcy4jYWN0aXZlV29ya2VycyArPSAxO1xuXHRcdFx0dm9pZCB0aGlzLnJ1bldvcmtlcigpLmZpbmFsbHkoKCkgPT4ge1xuXHRcdFx0XHR0aGlzLiNhY3RpdmVXb3JrZXJzIC09IDE7XG5cdFx0XHRcdGlmICh0aGlzLiNwZW5kaW5nV3JpdGVzLmxlbmd0aCA+IDApIHtcblx0XHRcdFx0XHR0aGlzLnN0YXJ0V29ya2VycygpO1xuXHRcdFx0XHR9IGVsc2UgaWYgKHRoaXMuI2FjdGl2ZVdvcmtlcnMgPT09IDApIHtcblx0XHRcdFx0XHR0aGlzLnJlc29sdmVEcmFpbigpO1xuXHRcdFx0XHR9XG5cdFx0XHR9KTtcblx0XHR9XG5cdH1cblxuXHRwcml2YXRlIGFzeW5jIHJ1bldvcmtlcigpOiBQcm9taXNlPHZvaWQ+IHtcblx0XHR3aGlsZSAodHJ1ZSkge1xuXHRcdFx0Y29uc3QgcmVzcG9uc2UgPSB0aGlzLiNwZW5kaW5nV3JpdGVzLnNoaWZ0KCk7XG5cdFx0XHRpZiAocmVzcG9uc2UgPT0gbnVsbCkge1xuXHRcdFx0XHRyZXR1cm47XG5cdFx0XHR9XG5cblx0XHRcdHRyeSB7XG5cdFx0XHRcdGlmICh0aGlzLiN3YXJtdXBQcm9taXNlICE9IG51bGwpIHtcblx0XHRcdFx0XHRhd2FpdCB0aGlzLiN3YXJtdXBQcm9taXNlO1xuXHRcdFx0XHR9XG5cblx0XHRcdFx0Y29uc3Qgb3V0cHV0UGF0aCA9IHJlc3BvbnNlLm91dHB1dFBhdGg7XG5cdFx0XHRcdGlmIChvdXRwdXRQYXRoID09IG51bGwpIHtcblx0XHRcdFx0XHRjb250aW51ZTtcblx0XHRcdFx0fVxuXG5cdFx0XHRcdGNvbnN0IG91dHB1dERpciA9IHJlc3BvbnNlLm91dHB1dERpcjtcblx0XHRcdFx0aWYgKG91dHB1dERpciAhPSBudWxsKSB7XG5cdFx0XHRcdFx0YXdhaXQgdGhpcy5lbnN1cmVEaXJlY3Rvcnkob3V0cHV0RGlyKTtcblx0XHRcdFx0fVxuXG5cdFx0XHRcdGNvbnN0IGV4aXN0aW5nID0gdGhpcy4jYXJ0aWZhY3RCeVBhdGguZ2V0KG91dHB1dFBhdGgpO1xuXHRcdFx0XHRpZiAoZXhpc3RpbmcgPT09IHJlc3BvbnNlLmNvZGUpIHtcblx0XHRcdFx0XHRjb250aW51ZTtcblx0XHRcdFx0fVxuXG5cdFx0XHRcdGF3YWl0IGlvLndyaXRlRmlsZShvdXRwdXRQYXRoLCByZXNwb25zZS5jb2RlKTtcblx0XHRcdFx0dGhpcy4jYXJ0aWZhY3RCeVBhdGguc2V0KG91dHB1dFBhdGgsIHJlc3BvbnNlLmNvZGUpO1xuXHRcdFx0fSBjYXRjaCAoZXJyb3IpIHtcblx0XHRcdFx0dGhpcy4jd29ya2VyRXJyb3IgPSBlcnJvcjtcblx0XHRcdFx0dGhpcy4jcGVuZGluZ1dyaXRlcyA9IFtdO1xuXHRcdFx0XHRyZXR1cm47XG5cdFx0XHR9XG5cdFx0fVxuXHR9XG5cblx0cHJpdmF0ZSBlbnN1cmVEaXJlY3RvcnkoZGlyOiBzdHJpbmcpOiBQcm9taXNlPHZvaWQ+IHtcblx0XHRpZiAodGhpcy4jZW5zdXJlZERpcnMuaGFzKGRpcikpIHtcblx0XHRcdHJldHVybiBQcm9taXNlLnJlc29sdmUoKTtcblx0XHR9XG5cdFx0Y29uc3QgZXhpc3RpbmcgPSB0aGlzLiNlbnN1cmVEaXJQcm9taXNlcy5nZXQoZGlyKTtcblx0XHRpZiAoZXhpc3RpbmcgIT0gbnVsbCkge1xuXHRcdFx0cmV0dXJuIGV4aXN0aW5nO1xuXHRcdH1cblx0XHRjb25zdCBta2RpclByb21pc2UgPSBmcy5ta2RpcihkaXIsIHsgcmVjdXJzaXZlOiB0cnVlIH0pLnRoZW4oKCkgPT4ge1xuXHRcdFx0dGhpcy4jZW5zdXJlZERpcnMuYWRkKGRpcik7XG5cdFx0XHR0aGlzLiNlbnN1cmVEaXJQcm9taXNlcy5kZWxldGUoZGlyKTtcblx0XHR9KTtcblx0XHR0aGlzLiNlbnN1cmVEaXJQcm9taXNlcy5zZXQoZGlyLCBta2RpclByb21pc2UpO1xuXHRcdHJldHVybiBta2RpclByb21pc2U7XG5cdH1cblxuXHRwcml2YXRlIHJlc29sdmVEcmFpbigpOiB2b2lkIHtcblx0XHRpZiAodGhpcy4jcGVuZGluZ1dyaXRlcy5sZW5ndGggPiAwIHx8IHRoaXMuI2FjdGl2ZVdvcmtlcnMgPiAwKSB7XG5cdFx0XHRyZXR1cm47XG5cdFx0fVxuXHRcdGZvciAoY29uc3QgcmVzb2x2ZSBvZiB0aGlzLiNkcmFpblJlc29sdmVycykge1xuXHRcdFx0cmVzb2x2ZSgpO1xuXHRcdH1cblx0XHR0aGlzLiNkcmFpblJlc29sdmVycyA9IFtdO1xuXHR9XG5cblx0cHJpdmF0ZSBhc3luYyB3aXRoQ29uY3VycmVuY3k8VD4oXG5cdFx0aXRlbXM6IFRbXSxcblx0XHRjb25jdXJyZW5jeTogbnVtYmVyLFxuXHRcdHdvcmtlcjogKGl0ZW06IFQpID0+IFByb21pc2U8dm9pZD4sXG5cdCk6IFByb21pc2U8dm9pZD4ge1xuXHRcdGxldCBjdXJzb3IgPSAwO1xuXHRcdGNvbnN0IHdvcmtlckNvdW50ID0gTWF0aC5taW4oY29uY3VycmVuY3ksIGl0ZW1zLmxlbmd0aCk7XG5cdFx0Y29uc3Qgd29ya2VycyA9IEFycmF5LmZyb20oeyBsZW5ndGg6IHdvcmtlckNvdW50IH0sICgpID0+XG5cdFx0XHQoYXN5bmMgKCkgPT4ge1xuXHRcdFx0XHR3aGlsZSAodHJ1ZSkge1xuXHRcdFx0XHRcdGNvbnN0IGluZGV4ID0gY3Vyc29yO1xuXHRcdFx0XHRcdGN1cnNvciArPSAxO1xuXHRcdFx0XHRcdGlmIChpbmRleCA+PSBpdGVtcy5sZW5ndGgpIHtcblx0XHRcdFx0XHRcdHJldHVybjtcblx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0YXdhaXQgd29ya2VyKGl0ZW1zW2luZGV4XSk7XG5cdFx0XHRcdH1cblx0XHRcdH0pKCksXG5cdFx0KTtcblx0XHRhd2FpdCBQcm9taXNlLmFsbCh3b3JrZXJzKTtcblx0fVxufVxuIl0sIm5hbWVzIjpbImZzIiwiaW5qZWN0YWJsZSIsIlRyYWNlIiwiaW8iLCJERUZBVUxUX1dSSVRFX0NPTkNVUlJFTkNZIiwiRmlsZVdyaXRlclNlcnZpY2UiLCJNYXAiLCJTZXQiLCJpbml0aWFsaXplIiwid2FybXVwIiwicHJvamVjdHMiLCJvdXRwdXREaXJzIiwiZ2V0T3V0cHV0RGlycyIsInNpZ25hdHVyZSIsImpvaW4iLCJjbGVhciIsInVuZGVmaW5lZCIsImxvYWRFeGlzdGluZ0FydGlmYWN0cyIsImVucXVldWVPdXRwdXQiLCJyZXNwb25zZSIsIm91dGNvbWUiLCJvdXRwdXRQYXRoIiwicHVzaCIsInN0YXJ0V29ya2VycyIsImVucXVldWVPdXRwdXRzIiwicmVzcG9uc2VzIiwiZmx1c2giLCJsZW5ndGgiLCJQcm9taXNlIiwicmVzb2x2ZSIsImRpcnMiLCJwcm9qZWN0IiwidGFyZ2V0IiwiZ2V0Rm9yZ2VDb25maWd1cmF0aW9uIiwidGFyZ2V0cyIsImFkZCIsImdldE91dERpciIsInNvcnQiLCJmaWxlcyIsImRpciIsImNvbGxlY3RGaWxlcyIsIndpdGhDb25jdXJyZW5jeSIsImdldFdyaXRlQ29uY3VycmVuY3kiLCJmaWxlUGF0aCIsImNvbnRlbnQiLCJyZWFkRmlsZSIsInNldCIsInJvb3REaXIiLCJlbnRyaWVzIiwicmVhZGRpciIsIndpdGhGaWxlVHlwZXMiLCJlbnRyeSIsImZ1bGxQYXRoIiwibmFtZSIsImlzRGlyZWN0b3J5IiwiaXNGaWxlIiwicmVxdWVzdGVkIiwiTnVtYmVyIiwicHJvY2VzcyIsImVudiIsIkZPUkdFX1dSSVRFX0NPTkNVUlJFTkNZIiwiaXNGaW5pdGUiLCJNYXRoIiwiZmxvb3IiLCJtYXhXb3JrZXJzIiwicnVuV29ya2VyIiwiZmluYWxseSIsInJlc29sdmVEcmFpbiIsInNoaWZ0Iiwib3V0cHV0RGlyIiwiZW5zdXJlRGlyZWN0b3J5IiwiZXhpc3RpbmciLCJnZXQiLCJjb2RlIiwid3JpdGVGaWxlIiwiZXJyb3IiLCJoYXMiLCJta2RpclByb21pc2UiLCJta2RpciIsInJlY3Vyc2l2ZSIsInRoZW4iLCJkZWxldGUiLCJpdGVtcyIsImNvbmN1cnJlbmN5Iiwid29ya2VyIiwiY3Vyc29yIiwid29ya2VyQ291bnQiLCJtaW4iLCJ3b3JrZXJzIiwiQXJyYXkiLCJmcm9tIiwiaW5kZXgiLCJhbGwiXSwibWFwcGluZ3MiOiI7Ozs7OztBQUFBLE9BQU9BLFFBQVEsbUJBQW1CO0FBQ2xDLFNBQVNDLFVBQVUsUUFBUSxnQ0FBZ0M7QUFFM0QsU0FBU0MsS0FBSyxRQUFRLDhCQUE4QjtB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
@@ -0,0 +1,18 @@
1
+ import { Subject } from "rxjs";
2
+ /**
3
+ * Runs a transformer's handler for every workspace file change and emits what it built. The
4
+ * handler invalidates the transformer's own caches, rebuilds, and returns the responses (empty
5
+ * for a deletion or when nothing was built).
6
+ */ export class IncrementalWatch {
7
+ #results = new Subject();
8
+ get results$() {
9
+ return this.#results.asObservable();
10
+ }
11
+ watch(workspace, handler) {
12
+ workspace.projectFileChanged$.subscribe((evt)=>{
13
+ void handler(evt).then((responses)=>{
14
+ this.#results.next(responses);
15
+ });
16
+ });
17
+ }
18
+ }
@@ -0,0 +1,29 @@
1
+ import { io } from "@decohere/core/io";
2
+ /** The outputs each source file last built to, so watch mode can delete them when it goes. */ export class OutputCache {
3
+ #bySource = new Map();
4
+ get(sourcePath) {
5
+ return this.#bySource.get(sourcePath);
6
+ }
7
+ /** Records the successful outputs, replacing what each of their source files had before. */ record(responses) {
8
+ const bySource = new Map();
9
+ for (const response of responses){
10
+ if (response.outcome !== "success") continue;
11
+ const group = bySource.get(response.file.fullPath) ?? [];
12
+ group.push(response);
13
+ bySource.set(response.file.fullPath, group);
14
+ }
15
+ for (const [sourcePath, group] of bySource){
16
+ this.#bySource.set(sourcePath, group);
17
+ }
18
+ }
19
+ /** Deletes the files a source built to and forgets them. */ delete(sourcePath) {
20
+ const outputs = this.#bySource.get(sourcePath);
21
+ if (outputs == null) return;
22
+ for (const response of outputs){
23
+ if (response.outputPath != null) {
24
+ void io.deleteFile(response.outputPath);
25
+ }
26
+ }
27
+ this.#bySource.delete(sourcePath);
28
+ }
29
+ }
@@ -7,31 +7,46 @@ function _ts_decorate(decorators, target, key, desc) {
7
7
  function _ts_metadata(k, v) {
8
8
  if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
9
9
  }
10
- import fs from "node:fs";
11
10
  import path from "node:path";
12
- import { cache, invalidateCache } from "@decohere/nexus/caching";
13
- import { Trace } from "@decohere/nexus/diagnostics";
14
- import { mixwith } from "@decohere/nexus/extensibility";
15
- import { io } from "@decohere/nexus/io";
11
+ import { sourceExtensions } from "@decohere/workspace";
12
+ import { cache, invalidateCache } from "@decohere/core/caching";
13
+ import { Trace } from "@decohere/devkit/diagnostics";
14
+ import { WatchEvents } from "@decohere/devkit/io";
16
15
  import { transform, transformSync } from "@swc/core";
17
16
  import { BuildTargets } from "../types/build-target.type.js";
18
17
  import "../extensions/project.extensions.js";
19
18
  import { SwcConfigFactory } from "../factories/swc-config.factory.js";
20
- import { CachesOutputs } from "../mixins/caches-outputs.mixin.js";
21
- import { IncrementalTransform } from "../mixins/incremental-transform.mixin.js";
22
19
  import { TransformResponse } from "../types/transform-response.model.js";
23
- export class SwcTranspiler extends mixwith(CachesOutputs, IncrementalTransform) {
20
+ import { IncrementalWatch } from "./incremental-watch.js";
21
+ import { OutputCache } from "./output-cache.js";
22
+ export class SwcTranspiler {
24
23
  buildTargets = [
25
24
  BuildTargets.es6,
26
25
  BuildTargets.commonjs
27
26
  ];
28
27
  #swcConfigFactory = new SwcConfigFactory();
28
+ #workspace;
29
+ #outputs = new OutputCache();
30
+ #incremental = new IncrementalWatch();
31
+ get incrementalTransform$() {
32
+ return this.#incremental.results$;
33
+ }
34
+ watch(workspace) {
35
+ this.#workspace = workspace;
36
+ this.#incremental.watch(workspace, (evt)=>this.onIncrementalFileEvent(evt));
37
+ }
38
+ withAliasContext(options = {}) {
39
+ return {
40
+ ...options,
41
+ workspace: options.workspace ?? this.#workspace
42
+ };
43
+ }
29
44
  async transformProject(projectArrayLike, fileFilter, onOutput) {
30
45
  const projects = Array.isArray(projectArrayLike) ? projectArrayLike : [
31
46
  projectArrayLike
32
47
  ];
33
48
  const responses = await Promise.all(projects.map(async (project)=>{
34
- const { targets, aliasPaths } = project.getForgeConfiguration();
49
+ const { targets, aliasPaths, sourceMaps } = project.getForgeConfiguration();
35
50
  const transpileTargets = targets.filter((bt)=>bt !== BuildTargets.types);
36
51
  if (transpileTargets.length === 0) {
37
52
  return [];
@@ -43,64 +58,34 @@ export class SwcTranspiler extends mixwith(CachesOutputs, IncrementalTransform)
43
58
  return this.transformTarget(sourceFiles, target, {
44
59
  tsConfig,
45
60
  userConfig,
46
- aliasPaths
61
+ aliasPaths,
62
+ sourceMaps,
63
+ workspace: this.#workspace,
64
+ projects
47
65
  }, project, onOutput);
48
66
  }));
49
67
  return responses.flat();
50
68
  }));
51
69
  const flat = responses.flat();
52
- this.cacheOutputs(flat);
70
+ this.#outputs.record(flat);
53
71
  return flat;
54
72
  }
55
- async transformFile(fileArrayLike, buildTarget, options = {}) {
56
- const files = Array.isArray(fileArrayLike) ? fileArrayLike : [
57
- fileArrayLike
58
- ];
59
- const responses = this.transformTarget(files, buildTarget, options);
60
- return responses;
61
- }
62
73
  /**
63
- * Synchronous, single-file variant of `transformFile`.
64
- * Reads the file with `fs.readFileSync` and transpiles via `swc.transformSync`.
65
- * Intended for callers that cannot await (e.g. Node.js `registerHooks` load hook).
66
- */ transformFileSync(file, buildTarget, options = {}) {
67
- const baseConfig = this.#swcConfigFactory.createBaseConfig(buildTarget, options);
74
+ * The SWC options for one project and target, without a filename. Building them reads the
75
+ * workspace's aliases and merges configs, so a caller that transpiles many files builds them
76
+ * once and passes them to {@link transformCode}.
77
+ */ createBaseConfig(buildTarget, options = {}) {
78
+ return this.#swcConfigFactory.createBaseConfig(buildTarget, this.withAliasContext(options));
79
+ }
80
+ /** Sync variant of {@link transformCode}, for the load hook, which cannot await. */ transformCodeSync(content, file, buildTarget, baseConfig) {
68
81
  const swcOptions = this.#swcConfigFactory.createFileConfig(file, baseConfig);
69
- let content;
70
- try {
71
- content = fs.readFileSync(file.fullPath, "utf8");
72
- } catch (error) {
73
- return TransformResponse.Error({
74
- file,
75
- messages: [
76
- String(error)
77
- ],
78
- config: swcOptions
79
- });
80
- }
81
- if (content === "") {
82
- return TransformResponse.Skipped({
83
- file,
84
- messages: "File is empty",
85
- config: swcOptions
86
- });
87
- }
82
+ if (content === "") return SwcTranspiler.skippedEmpty(file, swcOptions);
88
83
  try {
89
84
  const transformed = transformSync(content, swcOptions);
90
85
  if (transformed == null) {
91
86
  throw new Error("swc.transformSync returned no result");
92
87
  }
93
- const filePath = file.relativePath;
94
- const extName = path.extname(filePath);
95
- const fileName = filePath.replace(new RegExp(`${extName}$`), ".js");
96
- return TransformResponse.Success({
97
- file,
98
- code: transformed.code,
99
- sourceContent: content,
100
- target: buildTarget,
101
- fileName,
102
- config: swcOptions
103
- });
88
+ return SwcTranspiler.succeeded(file, buildTarget, swcOptions, content, transformed.code);
104
89
  } catch (error) {
105
90
  return TransformResponse.Error({
106
91
  file,
@@ -111,51 +96,23 @@ export class SwcTranspiler extends mixwith(CachesOutputs, IncrementalTransform)
111
96
  });
112
97
  }
113
98
  }
114
- async transformTarget(files, buildTarget, options, project, onOutput) {
115
- const baseConfig = this.#swcConfigFactory.createBaseConfig(buildTarget, options ?? {});
116
- return await Promise.all(files.map((file)=>{
117
- const swcOptions = this.#swcConfigFactory.createFileConfig(file, baseConfig);
118
- return this.runTransform(file, buildTarget, swcOptions, project, onOutput);
119
- }));
120
- }
121
- async runTransform(file, target, swcOptions, project, onOutput) {
122
- const content = await this.getFileContent(file);
123
- if (content === "") {
124
- const skipped = TransformResponse.Skipped({
125
- file,
126
- messages: "File is empty",
127
- config: swcOptions,
128
- project
129
- });
130
- onOutput?.(skipped);
131
- return skipped;
132
- }
99
+ /**
100
+ * Compiles `content` as the source of `file`, without reading the file: for callers that
101
+ * already hold the code, such as the Vitest plugin, which must compile what Vite passes it
102
+ * rather than an earlier read of the disk. Async SWC, on the thread pool, so many
103
+ * calls in flight compile in parallel. With a `project`, the response carries where
104
+ * the build writes the output.
105
+ */ async transformCode(content, file, buildTarget, baseConfig, project) {
106
+ const swcOptions = this.#swcConfigFactory.createFileConfig(file, baseConfig);
107
+ if (content === "") return SwcTranspiler.skippedEmpty(file, swcOptions, project);
133
108
  try {
134
- const filePath = file.relativePath;
135
- const extName = path.extname(filePath);
136
- const fileName = filePath.replace(new RegExp(`${extName}$`), ".js");
137
- const outBaseDir = project?.getOutDir(target);
138
- const outputPath = outBaseDir ? path.join(outBaseDir, fileName) : undefined;
139
- const outputDir = outputPath ? path.dirname(outputPath) : undefined;
140
109
  const transformed = await transform(content, swcOptions);
141
110
  if (transformed == null) {
142
111
  throw new Error("swc.transform returned no result");
143
112
  }
144
- const success = TransformResponse.Success({
145
- file,
146
- code: transformed.code,
147
- sourceContent: content,
148
- target,
149
- fileName,
150
- outputDir,
151
- outputPath,
152
- config: swcOptions,
153
- project
154
- });
155
- onOutput?.(success);
156
- return success;
113
+ return SwcTranspiler.succeeded(file, buildTarget, swcOptions, content, transformed.code, project);
157
114
  } catch (error) {
158
- const failure = TransformResponse.Error({
115
+ return TransformResponse.Error({
159
116
  file,
160
117
  messages: [
161
118
  String(error)
@@ -163,21 +120,52 @@ export class SwcTranspiler extends mixwith(CachesOutputs, IncrementalTransform)
163
120
  config: swcOptions,
164
121
  project
165
122
  });
166
- onOutput?.(failure);
167
- return failure;
168
123
  }
169
124
  }
125
+ static skippedEmpty(file, swcOptions, project) {
126
+ return TransformResponse.Skipped({
127
+ file,
128
+ messages: "File is empty",
129
+ config: swcOptions,
130
+ project
131
+ });
132
+ }
133
+ static succeeded(file, buildTarget, swcOptions, content, code, project) {
134
+ const fileName = sourceExtensions.outputPath(file.relativePath);
135
+ const outBaseDir = project?.getOutDir(buildTarget);
136
+ const outputPath = outBaseDir ? path.join(outBaseDir, fileName) : undefined;
137
+ return TransformResponse.Success({
138
+ file,
139
+ code,
140
+ sourceContent: content,
141
+ target: buildTarget,
142
+ fileName,
143
+ outputDir: outputPath ? path.dirname(outputPath) : undefined,
144
+ outputPath,
145
+ config: swcOptions,
146
+ project
147
+ });
148
+ }
149
+ async transformTarget(files, buildTarget, options, project, onOutput) {
150
+ const baseConfig = this.createBaseConfig(buildTarget, options);
151
+ return await Promise.all(files.map(async (file)=>{
152
+ const content = await this.getFileContent(file);
153
+ const response = await this.transformCode(content, file, buildTarget, baseConfig, project);
154
+ onOutput?.(response);
155
+ return response;
156
+ }));
157
+ }
170
158
  async onIncrementalFileEvent(evt) {
171
159
  const { file, project } = evt;
172
- if (evt.eventName === io.WatchEvents.unlink) {
173
- this.deleteCachedOutputs(file.fullPath);
160
+ if (evt.eventName === WatchEvents.unlink) {
161
+ this.#outputs.delete(file.fullPath);
174
162
  return [];
175
163
  }
176
164
  if (!project.isSourceFile(file)) {
177
165
  return [];
178
166
  }
179
167
  const freshContent = await file.getContent();
180
- const cached = this.outputCache.get(file.fullPath);
168
+ const cached = this.#outputs.get(file.fullPath);
181
169
  if (cached != null && cached[0]?.sourceContent === freshContent) {
182
170
  return [];
183
171
  }
@@ -216,5 +204,3 @@ _ts_decorate([
216
204
  SwcTranspiler = _ts_decorate([
217
205
  Trace
218
206
  ], SwcTranspiler);
219
-
220
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi9ob21lL3J1bm5lci93b3JrL2RlY29oZXJlL2RlY29oZXJlL3Byb2plY3RzL2ZvcmdlL3NyYy9zZXJ2aWNlcy9zd2MtdHJhbnNwaWxlci50cyJdLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgZnMgZnJvbSBcIm5vZGU6ZnNcIjtcbmltcG9ydCBwYXRoIGZyb20gXCJub2RlOnBhdGhcIjtcbmltcG9ydCB0eXBlIHsgUHJvamVjdCB9IGZyb20gXCJAZGVjb2hlcmUvbWVzaFwiO1xuaW1wb3J0IHsgY2FjaGUsIGludmFsaWRhdGVDYWNoZSB9IGZyb20gXCJAZGVjb2hlcmUvbmV4dXMvY2FjaGluZ1wiO1xuaW1wb3J0IHsgVHJhY2UgfSBmcm9tIFwiQGRlY29oZXJlL25leHVzL2RpYWdub3N0aWNzXCI7XG5pbXBvcnQgeyBtaXh3aXRoIH0gZnJvbSBcIkBkZWNvaGVyZS9uZXh1cy9leHRlbnNpYmlsaXR5XCI7XG5pbXBvcnQgdHlwZSB7IEZpbGVFeCB9IGZyb20gXCJAZGVjb2hlcmUvbmV4dXMvaW9cIjtcbmltcG9ydCB7IGlvIH0gZnJvbSBcIkBkZWNvaGVyZS9uZXh1cy9pb1wiO1xuaW1wb3J0IHsgdHlwZSBPcHRpb25zLCB0cmFuc2Zvcm0sIHRyYW5zZm9ybVN5bmMgfSBmcm9tIFwiQHN3Yy9jb3JlXCI7XG5pbXBvcnQge1xuXHR0eXBlIEJ1aWxkVGFyZ2V0LFxuXHRCdWlsZFRhcmdldHMsXG5cdHR5cGUgVHJhbnNwaWxlVGFyZ2V0LFxufSBmcm9tIFwiLi4vdHlwZXMvYnVpbGQtdGFyZ2V0LnR5cGUuanNcIjtcbmltcG9ydCBcIi4uL2V4dGVuc2lvbnMvcHJvamVjdC5leHRlbnNpb25zLmpzXCI7XG5pbXBvcnQgdHlwZSB7IFByb2plY3RGaWxlRXZlbnQsIFRzY29uZmlnIH0gZnJvbSBcIkBkZWNvaGVyZS9tZXNoXCI7XG5pbXBvcnQgeyBTd2NDb25maWdGYWN0b3J5IH0gZnJvbSBcIi4uL2ZhY3Rvcmllcy9zd2MtY29uZmlnLmZhY3RvcnkuanNcIjtcbmltcG9ydCB7IENhY2hlc091dHB1dHMgfSBmcm9tIFwiLi4vbWl4aW5zL2NhY2hlcy1vdXRwdXRzLm1peGluLmpzXCI7XG5pbXBvcnQgeyBJbmNyZW1lbnRhbFRyYW5zZm9ybSB9IGZyb20gXCIuLi9taXhpbnMvaW5jcmVtZW50YWwtdHJhbnNmb3JtLm1peGluLmpzXCI7XG5pbXBvcnQgdHlwZSB7IFN3Y0NvbmZpZyB9IGZyb20gXCIuLi90eXBlcy9zd2MtY29uZmlnLnR5cGUuanNcIjtcbmltcG9ydCB7IFRyYW5zZm9ybVJlc3BvbnNlIH0gZnJvbSBcIi4uL3R5cGVzL3RyYW5zZm9ybS1yZXNwb25zZS5tb2RlbC5qc1wiO1xuaW1wb3J0IHR5cGUgeyBUcmFuc2Zvcm1lciB9IGZyb20gXCIuLi90eXBlcy90cmFuc2Zvcm1lci50eXBlLmpzXCI7XG5cbmV4cG9ydCB0eXBlIFRyYW5zcGlsZU9wdGlvbnMgPSB7XG5cdGFsaWFzUGF0aHM/OiBib29sZWFuO1xuXHR0c0NvbmZpZz86IFRzY29uZmlnO1xuXHR1c2VyQ29uZmlnPzogU3djQ29uZmlnO1xufTtcblxuQFRyYWNlXG5leHBvcnQgY2xhc3MgU3djVHJhbnNwaWxlclxuXHRleHRlbmRzIG1peHdpdGgoQ2FjaGVzT3V0cHV0cywgSW5jcmVtZW50YWxUcmFuc2Zvcm0pXG5cdGltcGxlbWVudHMgVHJhbnNmb3JtZXJcbntcblx0cHVibGljIGJ1aWxkVGFyZ2V0czogQnVpbGRUYXJnZXRbXSA9IFtCdWlsZFRhcmdldHMuZXM2LCBCdWlsZFRhcmdldHMuY29tbW9uanNdO1xuXHQjc3djQ29uZmlnRmFjdG9yeSA9IG5ldyBTd2NDb25maWdGYWN0b3J5KCk7XG5cblx0cHVibGljIGFzeW5jIHRyYW5zZm9ybVByb2plY3QoXG5cdFx0cHJvamVjdEFycmF5TGlrZTogUHJvamVjdCB8IFByb2plY3RbXSxcblx0XHRmaWxlRmlsdGVyPzogKHByb2plY3Q6IFByb2plY3QpID0+IFByb21pc2U8RmlsZUV4W10+LFxuXHRcdG9uT3V0cHV0PzogKHJlc3BvbnNlOiBUcmFuc2Zvcm1SZXNwb25zZSkgPT4gdm9pZCxcblx0KTogUHJvbWlzZTxUcmFuc2Zvcm1SZXNwb25zZVtdPiB7XG5cdFx0Y29uc3QgcHJvamVjdHMgPSBBcnJheS5pc0FycmF5KHByb2plY3RBcnJheUxpa2UpID8gcHJvamVjdEFycmF5TGlrZSA6IFtwcm9qZWN0QXJyYXlMaWtlXTtcblx0XHRjb25zdCByZXNwb25zZXMgPSBhd2FpdCBQcm9taXNlLmFsbChcblx0XHRcdHByb2plY3RzLm1hcChhc3luYyAocHJvamVjdCkgPT4ge1xuXHRcdFx0XHRjb25zdCB7IHRhcmdldHMsIGFsaWFzUGF0aHMgfSA9IHByb2plY3QuZ2V0Rm9yZ2VDb25maWd1cmF0aW9uKCk7XG5cdFx0XHRcdGNvbnN0IHRyYW5zcGlsZVRhcmdldHMgPSB0YXJnZXRzLmZpbHRlcigoYnQpID0+IGJ0ICE9PSBCdWlsZFRhcmdldHMudHlwZXMpO1xuXHRcdFx0XHRpZiAodHJhbnNwaWxlVGFyZ2V0cy5sZW5ndGggPT09IDApIHtcblx0XHRcdFx0XHRyZXR1cm4gW107XG5cdFx0XHRcdH1cblxuXHRcdFx0XHRjb25zdCBzb3VyY2VGaWxlcyA9IGF3YWl0IChmaWxlRmlsdGVyPy4ocHJvamVjdCkgPz8gcHJvamVjdC5nZXRBbGxGaWxlcygpKTtcblx0XHRcdFx0Y29uc3QgdHNDb25maWcgPSBhd2FpdCBwcm9qZWN0LmdldFRzQ29uZmlnKCk7XG5cdFx0XHRcdGNvbnN0IHVzZXJDb25maWcgPSBhd2FpdCBwcm9qZWN0LmdldFN3Y0NvbmZpZygpO1xuXHRcdFx0XHRjb25zdCByZXNwb25zZXMgPSBhd2FpdCBQcm9taXNlLmFsbChcblx0XHRcdFx0XHR0cmFuc3BpbGVUYXJnZXRzLm1hcCgodGFyZ2V0KSA9PiB7XG5cdFx0XHRcdFx0XHRyZXR1cm4gdGhpcy50cmFuc2Zvcm1UYXJnZXQoXG5cdFx0XHRcdFx0XHRcdHNvdXJjZUZpbGVzLFxuXHRcdFx0XHRcdFx0XHR0YXJnZXQsXG5cdFx0XHRcdFx0XHRcdHtcblx0XHRcdFx0XHRcdFx0XHR0c0NvbmZpZyxcblx0XHRcdFx0XHRcdFx0XHR1c2VyQ29uZmlnLFxuXHRcdFx0XHRcdFx0XHRcdGFsaWFzUGF0aHMsXG5cdFx0XHRcdFx0XHRcdH0sXG5cdFx0XHRcdFx0XHRcdHByb2plY3QsXG5cdFx0XHRcdFx0XHRcdG9uT3V0cHV0LFxuXHRcdFx0XHRcdFx0KTtcblx0XHRcdFx0XHR9KSxcblx0XHRcdFx0KTtcblx0XHRcdFx0cmV0dXJuIHJlc3BvbnNlcy5mbGF0KCk7XG5cdFx0XHR9KSxcblx0XHQpO1xuXG5cdFx0Y29uc3QgZmxhdCA9IHJlc3BvbnNlcy5mbGF0KCk7XG5cdFx0dGhpcy5jYWNoZU91dHB1dHMoZmxhdCk7XG5cdFx0cmV0dXJuIGZsYXQ7XG5cdH1cblxuXHRwdWJsaWMgYXN5bmMgdHJhbnNmb3JtRmlsZShcblx0XHRmaWxlQXJyYXlMaWtlOiBGaWxlRXhbXSB8IEZpbGVFeCxcblx0XHRidWlsZFRhcmdldDogVHJhbnNwaWxlVGFyZ2V0LFxuXHRcdG9wdGlvbnM6IFRyYW5zcGlsZU9wdGlvbnMgPSB7fSxcblx0KSB7XG5cdFx0Y29uc3QgZmlsZXMgPSBBcnJheS5pc0FycmF5KGZpbGVBcnJheUxpa2UpID8gZmlsZUFycmF5TGlrZSA6IFtmaWxlQXJyYXlMaWtlXTtcblx0XHRjb25zdCByZXNwb25zZXMgPSB0aGlzLnRyYW5zZm9ybVRhcmdldChmaWxlcywgYnVpbGRUYXJnZXQsIG9wdGlvbnMpO1xuXHRcdHJldHVybiByZXNwb25zZXM7XG5cdH1cblxuXHQvKipcblx0ICogU3luY2hyb25vdXMsIHNpbmdsZS1maWxlIHZhcmlhbnQgb2YgYHRyYW5zZm9ybUZpbGVgLlxuXHQgKiBSZWFkcyB0aGUgZmlsZSB3aXRoIGBmcy5yZWFkRmlsZVN5bmNgIGFuZCB0cmFuc3BpbGVzIHZpYSBgc3djLnRyYW5zZm9ybVN5bmNgLlxuXHQgKiBJbnRlbmRlZCBmb3IgY2FsbGVycyB0aGF0IGNhbm5vdCBhd2FpdCAoZS5nLiBOb2RlLmpzIGByZWdpc3Rlckhvb2tzYCBsb2FkIGhvb2spLlxuXHQgKi9cblx0cHVibGljIHRyYW5zZm9ybUZpbGVTeW5jKFxuXHRcdGZpbGU6IEZpbGVFeCxcblx0XHRidWlsZFRhcmdldDogVHJhbnNwaWxlVGFyZ2V0LFxuXHRcdG9wdGlvbnM6IFRyYW5zcGlsZU9wdGlvbnMgPSB7fSxcblx0KTogVHJhbnNmb3JtUmVzcG9uc2Uge1xuXHRcdGNvbnN0IGJhc2VDb25maWcgPSB0aGlzLiNzd2NDb25maWdGYWN0b3J5LmNyZWF0ZUJhc2VDb25maWcoYnVpbGRUYXJnZXQsIG9wdGlvbnMpO1xuXHRcdGNvbnN0IHN3Y09wdGlvbnMgPSB0aGlzLiNzd2NDb25maWdGYWN0b3J5LmNyZWF0ZUZpbGVDb25maWcoZmlsZSwgYmFzZUNvbmZpZyk7XG5cblx0XHRsZXQgY29udGVudDogc3RyaW5nO1xuXHRcdHRyeSB7XG5cdFx0XHRjb250ZW50ID0gZnMucmVhZEZpbGVTeW5jKGZpbGUuZnVsbFBhdGgsIFwidXRmOFwiKTtcblx0XHR9IGNhdGNoIChlcnJvcikge1xuXHRcdFx0cmV0dXJuIFRyYW5zZm9ybVJlc3BvbnNlLkVycm9yKHtcblx0XHRcdFx0ZmlsZSxcblx0XHRcdFx0bWVzc2FnZXM6IFtTdHJpbmcoZXJyb3IpXSxcblx0XHRcdFx0Y29uZmlnOiBzd2NPcHRpb25zLFxuXHRcdFx0fSk7XG5cdFx0fVxuXG5cdFx0aWYgKGNvbnRlbnQgPT09IFwiXCIpIHtcblx0XHRcdHJldHVybiBUcmFuc2Zvcm1SZXNwb25zZS5Ta2lwcGVkKHtcblx0XHRcdFx0ZmlsZSxcblx0XHRcdFx0bWVzc2FnZXM6IFwiRmlsZSBpcyBlbXB0eVwiLFxuXHRcdFx0XHRjb25maWc6IHN3Y09wdGlvbnMsXG5cdFx0XHR9KTtcblx0XHR9XG5cblx0XHR0cnkge1xuXHRcdFx0Y29uc3QgdHJhbnNmb3JtZWQgPSB0cmFuc2Zvcm1TeW5jKGNvbnRlbnQsIHN3Y09wdGlvbnMpO1xuXHRcdFx0aWYgKHRyYW5zZm9ybWVkID09IG51bGwpIHtcblx0XHRcdFx0dGhyb3cgbmV3IEVycm9yKFwic3djLnRyYW5zZm9ybVN5bmMgcmV0dXJuZWQgbm8gcmVzdWx0XCIpO1xuXHRcdFx0fVxuXHRcdFx0Y29uc3QgZmlsZVBhdGggPSBmaWxlLnJlbGF0aXZlUGF0aDtcblx0XHRcdGNvbnN0IGV4dE5hbWUgPSBwYXRoLmV4dG5hbWUoZmlsZVBhdGgpO1xuXHRcdFx0Y29uc3QgZmlsZU5hbWUgPSBmaWxlUGF0aC5yZXBsYWNlKG5ldyBSZWdFeHAoYCR7ZXh0TmFtZX0kYCksIFwiLmpzXCIpO1xuXHRcdFx0cmV0dXJuIFRyYW5zZm9ybVJlc3BvbnNlLlN1Y2Nlc3Moe1xuXHRcdFx0XHRmaWxlLFxuXHRcdFx0XHRjb2RlOiB0cmFuc2Zvcm1lZC5jb2RlLFxuXHRcdFx0XHRzb3VyY2VDb250ZW50OiBjb250ZW50LFxuXHRcdFx0XHR0YXJnZXQ6IGJ1aWxkVGFyZ2V0LFxuXHRcdFx0XHRmaWxlTmFtZSxcblx0XHRcdFx0Y29uZmlnOiBzd2NPcHRpb25zLFxuXHRcdFx0fSk7XG5cdFx0fSBjYXRjaCAoZXJyb3IpIHtcblx0XHRcdHJldHVybiBUcmFuc2Zvcm1SZXNwb25zZS5FcnJvcih7XG5cdFx0XHRcdGZpbGUsXG5cdFx0XHRcdG1lc3NhZ2VzOiBbU3RyaW5nKGVycm9yKV0sXG5cdFx0XHRcdGNvbmZpZzogc3djT3B0aW9ucyxcblx0XHRcdH0pO1xuXHRcdH1cblx0fVxuXG5cdHByaXZhdGUgYXN5bmMgdHJhbnNmb3JtVGFyZ2V0KFxuXHRcdGZpbGVzOiBGaWxlRXhbXSxcblx0XHRidWlsZFRhcmdldDogVHJhbnNwaWxlVGFyZ2V0LFxuXHRcdG9wdGlvbnM/OiBUcmFuc3BpbGVPcHRpb25zLFxuXHRcdHByb2plY3Q/OiBQcm9qZWN0LFxuXHRcdG9uT3V0cHV0PzogKHJlc3BvbnNlOiBUcmFuc2Zvcm1SZXNwb25zZSkgPT4gdm9pZCxcblx0KSB7XG5cdFx0Y29uc3QgYmFzZUNvbmZpZyA9IHRoaXMuI3N3Y0NvbmZpZ0ZhY3RvcnkuY3JlYXRlQmFzZUNvbmZpZyhidWlsZFRhcmdldCwgb3B0aW9ucyA/PyB7fSk7XG5cdFx0cmV0dXJuIGF3YWl0IFByb21pc2UuYWxsKFxuXHRcdFx0ZmlsZXMubWFwKChmaWxlKSA9PiB7XG5cdFx0XHRcdGNvbnN0IHN3Y09wdGlvbnMgPSB0aGlzLiNzd2NDb25maWdGYWN0b3J5LmNyZWF0ZUZpbGVDb25maWcoZmlsZSwgYmFzZUNvbmZpZyk7XG5cdFx0XHRcdHJldHVybiB0aGlzLnJ1blRyYW5zZm9ybShmaWxlLCBidWlsZFRhcmdldCwgc3djT3B0aW9ucywgcHJvamVjdCwgb25PdXRwdXQpO1xuXHRcdFx0fSksXG5cdFx0KTtcblx0fVxuXG5cdHByaXZhdGUgYXN5bmMgcnVuVHJhbnNmb3JtKFxuXHRcdGZpbGU6IEZpbGVFeCxcblx0XHR0YXJnZXQ6IEJ1aWxkVGFyZ2V0LFxuXHRcdHN3Y09wdGlvbnM6IE9wdGlvbnMsXG5cdFx0cHJvamVjdD86IFByb2plY3QsXG5cdFx0b25PdXRwdXQ/OiAocmVzcG9uc2U6IFRyYW5zZm9ybVJlc3BvbnNlKSA9PiB2b2lkLFxuXHQpOiBQcm9taXNlPFRyYW5zZm9ybVJlc3BvbnNlPiB7XG5cdFx0Y29uc3QgY29udGVudCA9IGF3YWl0IHRoaXMuZ2V0RmlsZUNvbnRlbnQoZmlsZSk7XG5cdFx0aWYgKGNvbnRlbnQgPT09IFwiXCIpIHtcblx0XHRcdGNvbnN0IHNraXBwZWQgPSBUcmFuc2Zvcm1SZXNwb25zZS5Ta2lwcGVkKHtcblx0XHRcdFx0ZmlsZSxcblx0XHRcdFx0bWVzc2FnZXM6IFwiRmlsZSBpcyBlbXB0eVwiLFxuXHRcdFx0XHRjb25maWc6IHN3Y09wdGlvbnMsXG5cdFx0XHRcdHByb2plY3QsXG5cdFx0XHR9KTtcblx0XHRcdG9uT3V0cHV0Py4oc2tpcHBlZCk7XG5cdFx0XHRyZXR1cm4gc2tpcHBlZDtcblx0XHR9XG5cblx0XHR0cnkge1xuXHRcdFx0Y29uc3QgZmlsZVBhdGggPSBmaWxlLnJlbGF0aXZlUGF0aDtcblx0XHRcdGNvbnN0IGV4dE5hbWUgPSBwYXRoLmV4dG5hbWUoZmlsZVBhdGgpO1xuXHRcdFx0Y29uc3QgZmlsZU5hbWUgPSBmaWxlUGF0aC5yZXBsYWNlKG5ldyBSZWdFeHAoYCR7ZXh0TmFtZX0kYCksIFwiLmpzXCIpO1xuXHRcdFx0Y29uc3Qgb3V0QmFzZURpciA9IHByb2plY3Q/LmdldE91dERpcih0YXJnZXQpO1xuXHRcdFx0Y29uc3Qgb3V0cHV0UGF0aCA9IG91dEJhc2VEaXIgPyBwYXRoLmpvaW4ob3V0QmFzZURpciwgZmlsZU5hbWUpIDogdW5kZWZpbmVkO1xuXHRcdFx0Y29uc3Qgb3V0cHV0RGlyID0gb3V0cHV0UGF0aCA/IHBhdGguZGlybmFtZShvdXRwdXRQYXRoKSA6IHVuZGVmaW5lZDtcblx0XHRcdGNvbnN0IHRyYW5zZm9ybWVkID0gYXdhaXQgdHJhbnNmb3JtKGNvbnRlbnQsIHN3Y09wdGlvbnMpO1xuXHRcdFx0aWYgKHRyYW5zZm9ybWVkID09IG51bGwpIHtcblx0XHRcdFx0dGhyb3cgbmV3IEVycm9yKFwic3djLnRyYW5zZm9ybSByZXR1cm5lZCBubyByZXN1bHRcIik7XG5cdFx0XHR9XG5cblx0XHRcdGNvbnN0IHN1Y2Nlc3MgPSBUcmFuc2Zvcm1SZXNwb25zZS5TdWNjZXNzKHtcblx0XHRcdFx0ZmlsZSxcblx0XHRcdFx0Y29kZTogdHJhbnNmb3JtZWQuY29kZSxcblx0XHRcdFx0c291cmNlQ29udGVudDogY29udGVudCxcblx0XHRcdFx0dGFyZ2V0LFxuXHRcdFx0XHRmaWxlTmFtZSxcblx0XHRcdFx0b3V0cHV0RGlyLFxuXHRcdFx0XHRvdXRwdXRQYXRoLFxuXHRcdFx0XHRjb25maWc6IHN3Y09wdGlvbnMsXG5cdFx0XHRcdHByb2plY3QsXG5cdFx0XHR9KTtcblx0XHRcdG9uT3V0cHV0Py4oc3VjY2Vzcyk7XG5cdFx0XHRyZXR1cm4gc3VjY2Vzcztcblx0XHR9IGNhdGNoIChlcnJvcikge1xuXHRcdFx0Y29uc3QgZmFpbHVyZSA9IFRyYW5zZm9ybVJlc3BvbnNlLkVycm9yKHtcblx0XHRcdFx0ZmlsZSxcblx0XHRcdFx0bWVzc2FnZXM6IFtTdHJpbmcoZXJyb3IpXSxcblx0XHRcdFx0Y29uZmlnOiBzd2NPcHRpb25zLFxuXHRcdFx0XHRwcm9qZWN0LFxuXHRcdFx0fSk7XG5cdFx0XHRvbk91dHB1dD8uKGZhaWx1cmUpO1xuXHRcdFx0cmV0dXJuIGZhaWx1cmU7XG5cdFx0fVxuXHR9XG5cblx0cHJvdGVjdGVkIGFzeW5jIG9uSW5jcmVtZW50YWxGaWxlRXZlbnQoZXZ0OiBQcm9qZWN0RmlsZUV2ZW50KTogUHJvbWlzZTxUcmFuc2Zvcm1SZXNwb25zZVtdPiB7XG5cdFx0Y29uc3QgeyBmaWxlLCBwcm9qZWN0IH0gPSBldnQ7XG5cdFx0aWYgKGV2dC5ldmVudE5hbWUgPT09IGlvLldhdGNoRXZlbnRzLnVubGluaykge1xuXHRcdFx0dGhpcy5kZWxldGVDYWNoZWRPdXRwdXRzKGZpbGUuZnVsbFBhdGgpO1xuXHRcdFx0cmV0dXJuIFtdO1xuXHRcdH1cblx0XHRpZiAoIXByb2plY3QuaXNTb3VyY2VGaWxlKGZpbGUpKSB7XG5cdFx0XHRyZXR1cm4gW107XG5cdFx0fVxuXHRcdGNvbnN0IGZyZXNoQ29udGVudCA9IGF3YWl0IGZpbGUuZ2V0Q29udGVudCgpO1xuXHRcdGNvbnN0IGNhY2hlZCA9IHRoaXMub3V0cHV0Q2FjaGUuZ2V0KGZpbGUuZnVsbFBhdGgpO1xuXHRcdGlmIChjYWNoZWQgIT0gbnVsbCAmJiBjYWNoZWRbMF0/LnNvdXJjZUNvbnRlbnQgPT09IGZyZXNoQ29udGVudCkge1xuXHRcdFx0cmV0dXJuIFtdO1xuXHRcdH1cblx0XHR0aGlzLmludmFsaWRhdGVDb250ZW50Q2FjaGUoZmlsZSk7XG5cdFx0cmV0dXJuIHRoaXMudHJhbnNmb3JtUHJvamVjdChwcm9qZWN0LCAoKSA9PiBQcm9taXNlLnJlc29sdmUoW2ZpbGVdKSk7XG5cdH1cblxuXHRAaW52YWxpZGF0ZUNhY2hlKFN3Y1RyYW5zcGlsZXIucHJvdG90eXBlLmdldEZpbGVDb250ZW50LCB7XG5cdFx0bmFtZTogXCJGSUxFX0NPTlRFTlRcIixcblx0XHRrZXlGbjogKC4uLmFyZ3MpID0+IChhcmdzWzBdIGFzIEZpbGVFeCkuZnVsbFBhdGgsXG5cdH0pXG5cdHB1YmxpYyBpbnZhbGlkYXRlQ29udGVudENhY2hlKF9maWxlOiBGaWxlRXgpOiB2b2lkIHt9XG5cblx0QGNhY2hlKHsgbmFtZTogXCJGSUxFX0NPTlRFTlRcIiwga2V5Rm46ICguLi5hcmdzKSA9PiAoYXJnc1swXSBhcyBGaWxlRXgpLmZ1bGxQYXRoIH0pXG5cdHByaXZhdGUgYXN5bmMgZ2V0RmlsZUNvbnRlbnQoZmlsZTogRmlsZUV4KTogUHJvbWlzZTxzdHJpbmc+IHtcblx0XHRyZXR1cm4gYXdhaXQgZmlsZS5nZXRDb250ZW50KCk7XG5cdH1cbn1cbiJdLCJuYW1lcyI6WyJmcyIsInBhdGgiLCJjYWNoZSIsImludmFsaWRhdGVDYWNoZSIsIlRyYWNlIiwibWl4d2l0aCIsImlvIiwidHJhbnNmb3JtIiwidHJhbnNmb3JtU3luYyIsIkJ1aWxkVGFyZ2V0cyIsIlN3Y0NvbmZpZ0ZhY3RvcnkiLCJDYWNoZXNPdXRwdXRzIiwiSW5jcmVtZW50YWxUcmFuc2Zvcm0iLCJUcmFuc2Zvcm1SZXNwb25zZSIsIlN3Y1RyYW5zcGlsZXIiLCJidWlsZFRhcmdldHMiLCJlczYiLCJjb21tb25qcyIsInRyYW5zZm9ybVByb2plY3QiLCJwcm9qZWN0QXJyYXlMaWtlIiwiZmlsZUZpbHRlciIsIm9uT3V0cHV0IiwicHJvamVjdHMiLCJBcnJheSIsImlzQXJyYXkiLCJyZXNwb25zZXMiLCJQcm9taXNlIiwiYWxsIiwibWFwIiwicHJvamVjdCIsInRhcmdldHMiLCJhbGlhc1BhdGhzIiwiZ2V0Rm9yZ2VDb25maWd1cmF0aW9uIiwidHJhbnNwaWxlVGFyZ2V0cyIsImZpbHRlciIsImJ0IiwidHlwZXMiLCJsZW5ndGgiLCJzb3VyY2VGaWxlcyIsImdldEFsbEZpbGVzIiwidHNDb25maWciLCJnZXRUc0NvbmZpZyIsInVzZXJDb25maWciLCJnZXRTd2NDb25maWciLCJ0YXJnZXQiLCJ0cmFuc2Zvcm1UYXJnZXQiLCJmbGF0IiwiY2FjaGVPdXRwdXRzIiwidHJhbnNmb3JtRmlsZSIsImZpbGVBcnJheUxpa2UiLCJidWlsZFRhcmdldCIsIm9wdGlvbnMiLCJmaWxlcyIsInRyYW5zZm9ybUZpbGVTeW5jIiwiZmlsZSIsImJhc2VDb25maWciLCJjcmVhdGVCYXNlQ29uZmlnIiwic3djT3B0aW9ucyIsImNyZWF0ZUZpbGVDb25maWciLCJjb250ZW50IiwicmVhZEZpbGVTeW5jIiwiZnVsbFBhdGgiLCJlcnJvciIsIkVycm9yIiwibWVzc2FnZXMiLCJTdHJpbmciLCJjb25maWciLCJTa2lwcGVkIiwidHJhbnNmb3JtZWQiLCJmaWxlUGF0aCIsInJlbGF0aXZlUGF0aCIsImV4dE5hbWUiLCJleHRuYW1lIiwiZmlsZU5hbWUiLCJyZXBsYWNlIiwiUmVnRXhwIiwiU3VjY2VzcyIsImNvZGUiLCJzb3VyY2VDb250ZW50IiwicnVuVHJhbnNmb3JtIiwiZ2V0RmlsZUNvbnRlbnQiLCJza2lwcGVkIiwib3V0QmFzZURpciIsImdldE91dERpciIsIm91dHB1dFBhdGgiLCJqb2luIiwidW5kZWZpbmVkIiwib3V0cHV0RGlyIiwiZGlybmFtZSIsInN1Y2Nlc3MiLCJmYWlsdXJlIiwib25JbmNyZW1lbnRhbEZpbGVFdmVudCIsImV2dCIsImV2ZW50TmFtZSIsIldhdGNoRXZlbnRzIiwidW5saW5rIiwiZGVsZXRlQ2FjaGVkT3V0cHV0cyIsImlzU291cmNlRmlsZSIsImZyZXNoQ29udGVudCIsImdldENvbnRlbnQiLCJjYWNoZWQiLCJvdXRwdXRDYWNoZSIsImdldCIsImludmFsaWRhdGVDb250ZW50Q2FjaGUiLCJyZXNvbHZlIiwiX2ZpbGUiLCJwcm90b3R5cGUiLCJuYW1lIiwia2V5Rm4iLCJhcmdzIl0sIm1hcHBpbmdzIjoiOzs7Ozs7Ozs7QUFBQSxPQUFPQSxRQUFRLFVBQVU7QUFDekIsT0FBT0MsVUFBVSxZQUFZO0FBRTdCLFNBQVNDLEtBQUssRUFBRUMsZUFBZSxRQUFRLDBCQUEwQjtBQUNqRSxTQUFTQyxLQUFLLFFBQVEsOEJBQThCO0FBQ3BELFNBQVNDLE9BQU8sUUFBUSxnQ0FBZ0M7QUFFeEQsU0FBU0MsRUFBRSxRQUFRLHFCQUFx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
@@ -0,0 +1,29 @@
1
+ import { existsSync } from "node:fs";
2
+ import os from "node:os";
3
+ import path from "node:path";
4
+ import { version as swcVersion } from "@swc/core";
5
+ /**
6
+ * Where compiled code is cached on disk, or null when caching is off:
7
+ *
8
+ * - `DECOHERE_CACHE=0` turns it off.
9
+ * - `DECOHERE_CACHE_DIR` puts it in that directory.
10
+ * - Otherwise `<root>/node_modules/.cache/decohere`, where tools keep caches, or when the
11
+ * workspace has no `node_modules`, `$XDG_CACHE_HOME/decohere`, then the OS temp directory.
12
+ *
13
+ * Flux keeps its entries in the `flux` folder inside it; `forge clean` removes the folder.
14
+ */ function directory(rootDir, env = process.env) {
15
+ if (env.DECOHERE_CACHE === "0") return null;
16
+ if (env.DECOHERE_CACHE_DIR != null && env.DECOHERE_CACHE_DIR !== "") {
17
+ return path.resolve(env.DECOHERE_CACHE_DIR);
18
+ }
19
+ const nodeModules = path.join(rootDir, "node_modules");
20
+ if (existsSync(nodeModules)) return path.join(nodeModules, ".cache", "decohere");
21
+ if (env.XDG_CACHE_HOME != null && env.XDG_CACHE_HOME !== "") {
22
+ return path.join(env.XDG_CACHE_HOME, "decohere");
23
+ }
24
+ return path.join(os.tmpdir(), "decohere");
25
+ }
26
+ /** The SWC version compiling: part of every cache key, so upgrading SWC misses. */ export const transpileCache = {
27
+ directory,
28
+ swcVersion
29
+ };