@hanseltime/esm-interop-tools 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (64) hide show
  1. package/README.md +115 -0
  2. package/dist/bin/get-esm-packages.js +17 -0
  3. package/dist/bin/get-esm-packages.js.map +1 -0
  4. package/dist/cjs/bin/get-esm-packages.js +73 -0
  5. package/dist/cjs/bin/get-esm-packages.js.map +1 -0
  6. package/dist/cjs/index.js +21 -0
  7. package/dist/cjs/index.js.map +1 -0
  8. package/dist/cjs/operations/getESMPackages.js +105 -0
  9. package/dist/cjs/operations/getESMPackages.js.map +1 -0
  10. package/dist/cjs/operations/index.js +21 -0
  11. package/dist/cjs/operations/index.js.map +1 -0
  12. package/dist/cjs/operations/jest.js +52 -0
  13. package/dist/cjs/operations/jest.js.map +1 -0
  14. package/dist/cjs/packageGraphs/Graph.js +130 -0
  15. package/dist/cjs/packageGraphs/Graph.js.map +1 -0
  16. package/dist/cjs/packageGraphs/PackageGraph.js +42 -0
  17. package/dist/cjs/packageGraphs/PackageGraph.js.map +1 -0
  18. package/dist/cjs/packageGraphs/getYarnInfoPackageGraph.js +128 -0
  19. package/dist/cjs/packageGraphs/getYarnInfoPackageGraph.js.map +1 -0
  20. package/dist/cjs/packageGraphs/index.js +23 -0
  21. package/dist/cjs/packageGraphs/index.js.map +1 -0
  22. package/dist/cjs/packageGraphs/types.js +6 -0
  23. package/dist/cjs/packageGraphs/types.js.map +1 -0
  24. package/dist/esm/bin/get-esm-packages.mjs +86 -0
  25. package/dist/esm/bin/get-esm-packages.mjs.map +1 -0
  26. package/dist/esm/index.mjs +4 -0
  27. package/dist/esm/index.mjs.map +1 -0
  28. package/dist/esm/operations/getESMPackages.mjs +118 -0
  29. package/dist/esm/operations/getESMPackages.mjs.map +1 -0
  30. package/dist/esm/operations/index.mjs +4 -0
  31. package/dist/esm/operations/index.mjs.map +1 -0
  32. package/dist/esm/operations/jest.mjs +45 -0
  33. package/dist/esm/operations/jest.mjs.map +1 -0
  34. package/dist/esm/packageGraphs/Graph.mjs +173 -0
  35. package/dist/esm/packageGraphs/Graph.mjs.map +1 -0
  36. package/dist/esm/packageGraphs/PackageGraph.mjs +28 -0
  37. package/dist/esm/packageGraphs/PackageGraph.mjs.map +1 -0
  38. package/dist/esm/packageGraphs/getYarnInfoPackageGraph.mjs +142 -0
  39. package/dist/esm/packageGraphs/getYarnInfoPackageGraph.mjs.map +1 -0
  40. package/dist/esm/packageGraphs/index.mjs +6 -0
  41. package/dist/esm/packageGraphs/index.mjs.map +1 -0
  42. package/dist/esm/packageGraphs/types.mjs +8 -0
  43. package/dist/esm/packageGraphs/types.mjs.map +1 -0
  44. package/dist/types/bin/get-esm-packages.d.ts +2 -0
  45. package/dist/types/bin/get-esm-packages.d.ts.map +1 -0
  46. package/dist/types/index.d.ts +3 -0
  47. package/dist/types/index.d.ts.map +1 -0
  48. package/dist/types/operations/getESMPackages.d.ts +8 -0
  49. package/dist/types/operations/getESMPackages.d.ts.map +1 -0
  50. package/dist/types/operations/index.d.ts +3 -0
  51. package/dist/types/operations/index.d.ts.map +1 -0
  52. package/dist/types/operations/jest.d.ts +40 -0
  53. package/dist/types/operations/jest.d.ts.map +1 -0
  54. package/dist/types/packageGraphs/Graph.d.ts +72 -0
  55. package/dist/types/packageGraphs/Graph.d.ts.map +1 -0
  56. package/dist/types/packageGraphs/PackageGraph.d.ts +19 -0
  57. package/dist/types/packageGraphs/PackageGraph.d.ts.map +1 -0
  58. package/dist/types/packageGraphs/getYarnInfoPackageGraph.d.ts +9 -0
  59. package/dist/types/packageGraphs/getYarnInfoPackageGraph.d.ts.map +1 -0
  60. package/dist/types/packageGraphs/index.d.ts +5 -0
  61. package/dist/types/packageGraphs/index.d.ts.map +1 -0
  62. package/dist/types/packageGraphs/types.d.ts +9 -0
  63. package/dist/types/packageGraphs/types.d.ts.map +1 -0
  64. package/package.json +64 -0
@@ -0,0 +1,73 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", {
3
+ value: true
4
+ });
5
+ Object.defineProperty(exports, "writeESMModuleOutput", {
6
+ enumerable: true,
7
+ get: function() {
8
+ return writeESMModuleOutput;
9
+ }
10
+ });
11
+ function _commander() {
12
+ const data = require("commander");
13
+ _commander = function() {
14
+ return data;
15
+ };
16
+ return data;
17
+ }
18
+ const _operations = require("../operations");
19
+ const _packageGraphs = require("../packageGraphs");
20
+ function _fs() {
21
+ const data = require("fs");
22
+ _fs = function() {
23
+ return data;
24
+ };
25
+ return data;
26
+ }
27
+ _commander().program.addOption(new (_commander()).Option("-p, --pkgManager <pkgManager>", "The package manager that you are running under - will be used to resolve modules").choices([
28
+ "yarnv2+"
29
+ ]).makeOptionMandatory()).addOption(new (_commander()).Option("-o, --output <output>", "How to output the package info").choices([
30
+ "json",
31
+ "console",
32
+ "none"
33
+ ]).default("console", "writes each package to the a line")).option("--cwd <cwd>").option("-r, --recurse", "get all dependencies and not just direct ones", false).option("-f, --file <file>", "the file to output json to").option("-q, --quiet", "if we should not output any values", false);
34
+ const options = _commander().program.parse(process.argv).opts();
35
+ async function main(options) {
36
+ const { pkgManager, cwd = process.cwd(), recurse, output, file, quiet } = options;
37
+ let packageGraph;
38
+ switch(pkgManager){
39
+ case "yarnv2+":
40
+ packageGraph = await (0, _packageGraphs.getYarnInfoPackageGraph)(cwd, recurse);
41
+ break;
42
+ default:
43
+ throw new Error("Unimplemented package manager GetPackagesGraphFn mapping!");
44
+ }
45
+ packageGraph.validate();
46
+ const packages = (await (0, _operations.getESMPackages)(packageGraph)).sort();
47
+ if (!quiet) {
48
+ switch(output){
49
+ case "json":
50
+ console.log(JSON.stringify(packages));
51
+ break;
52
+ case "console":
53
+ console.log(packages.join("\n"));
54
+ }
55
+ }
56
+ if (file) {
57
+ writeESMModuleOutput(packages, file);
58
+ }
59
+ }
60
+ function writeESMModuleOutput(packages, file) {
61
+ (0, _fs().writeFileSync)(file, JSON.stringify({
62
+ description: `This is a programmatically created file via ${process.argv.join(" ")}`,
63
+ packages: packages
64
+ }, null, 4));
65
+ }
66
+ void main(options).then(()=>{
67
+ process.exit();
68
+ }).catch((err)=>{
69
+ console.error(err);
70
+ process.exit(5);
71
+ });
72
+
73
+ //# sourceMappingURL=get-esm-packages.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../src/bin/get-esm-packages.ts"],"sourcesContent":["import { program, Option } from \"commander\";\nimport { EsmPackagesFile, getESMPackages } from \"../operations\";\nimport { getYarnInfoPackageGraph, PackageGraph } from \"../packageGraphs\";\nimport { writeFileSync } from \"fs\";\n\nprogram\n\t.addOption(\n\t\tnew Option(\n\t\t\t\"-p, --pkgManager <pkgManager>\",\n\t\t\t\"The package manager that you are running under - will be used to resolve modules\",\n\t\t)\n\t\t\t.choices([\"yarnv2+\"])\n\t\t\t.makeOptionMandatory(),\n\t)\n\t.addOption(\n\t\tnew Option(\"-o, --output <output>\", \"How to output the package info\")\n\t\t\t.choices([\"json\", \"console\", \"none\"])\n\t\t\t.default(\"console\", \"writes each package to the a line\"),\n\t)\n\t.option(\"--cwd <cwd>\")\n\t.option(\n\t\t\"-r, --recurse\",\n\t\t\"get all dependencies and not just direct ones\",\n\t\tfalse,\n\t)\n\t.option(\"-f, --file <file>\", \"the file to output json to\")\n\t.option(\"-q, --quiet\", \"if we should not output any values\", false);\n\nconst options = program.parse(process.argv).opts<CliOpts>();\n\ninterface CliOpts {\n\tpkgManager: \"yarnv2+\" | \"npm\";\n\tcwd?: string;\n\trecurse: boolean;\n\toutput: \"console\" | \"json\";\n\tfile?: string;\n\tquiet: boolean;\n}\n\nasync function main(options: CliOpts) {\n\tconst {\n\t\tpkgManager,\n\t\tcwd = process.cwd(),\n\t\trecurse,\n\t\toutput,\n\t\tfile,\n\t\tquiet,\n\t} = options;\n\tlet packageGraph: PackageGraph;\n\tswitch (pkgManager) {\n\t\tcase \"yarnv2+\":\n\t\t\tpackageGraph = await getYarnInfoPackageGraph(cwd, recurse);\n\t\t\tbreak;\n\t\tdefault:\n\t\t\tthrow new Error(\n\t\t\t\t\"Unimplemented package manager GetPackagesGraphFn mapping!\",\n\t\t\t);\n\t}\n\tpackageGraph.validate();\n\n\tconst packages = (await getESMPackages(packageGraph)).sort();\n\n\tif (!quiet) {\n\t\tswitch (output) {\n\t\t\tcase \"json\":\n\t\t\t\tconsole.log(JSON.stringify(packages));\n\t\t\t\tbreak;\n\t\t\tcase \"console\":\n\t\t\t\tconsole.log(packages.join(\"\\n\"));\n\t\t}\n\t}\n\n\tif (file) {\n\t\twriteESMModuleOutput(packages, file);\n\t}\n}\n\nexport function writeESMModuleOutput(packages: string[], file: string) {\n\twriteFileSync(\n\t\tfile,\n\t\tJSON.stringify(\n\t\t\t{\n\t\t\t\tdescription: `This is a programmatically created file via ${process.argv.join(\" \")}`,\n\t\t\t\tpackages: packages,\n\t\t\t} as EsmPackagesFile,\n\t\t\tnull,\n\t\t\t4,\n\t\t),\n\t);\n}\n\nvoid main(options)\n\t.then(() => {\n\t\tprocess.exit();\n\t})\n\t.catch((err) => {\n\t\tconsole.error(err);\n\t\tprocess.exit(5);\n\t});\n"],"names":["writeESMModuleOutput","program","addOption","Option","choices","makeOptionMandatory","default","option","options","parse","process","argv","opts","main","pkgManager","cwd","recurse","output","file","quiet","packageGraph","getYarnInfoPackageGraph","Error","validate","packages","getESMPackages","sort","console","log","JSON","stringify","join","writeFileSync","description","then","exit","catch","err","error"],"mappings":";;;;+BA6EgBA;;;eAAAA;;;;yBA7EgB;;;;;;4BACgB;+BACM;;yBACxB;;;;;;AAE9BC,oBAAO,CACLC,SAAS,CACT,IAAIC,CAAAA,YAAK,QAAC,CACT,iCACA,oFAECC,OAAO,CAAC;IAAC;CAAU,EACnBC,mBAAmB,IAErBH,SAAS,CACT,IAAIC,CAAAA,YAAK,QAAC,CAAC,yBAAyB,kCAClCC,OAAO,CAAC;IAAC;IAAQ;IAAW;CAAO,EACnCE,OAAO,CAAC,WAAW,sCAErBC,MAAM,CAAC,eACPA,MAAM,CACN,iBACA,iDACA,OAEAA,MAAM,CAAC,qBAAqB,8BAC5BA,MAAM,CAAC,eAAe,sCAAsC;AAE9D,MAAMC,UAAUP,oBAAO,CAACQ,KAAK,CAACC,QAAQC,IAAI,EAAEC,IAAI;AAWhD,eAAeC,KAAKL,OAAgB;IACnC,MAAM,EACLM,UAAU,EACVC,MAAML,QAAQK,GAAG,EAAE,EACnBC,OAAO,EACPC,MAAM,EACNC,IAAI,EACJC,KAAK,EACL,GAAGX;IACJ,IAAIY;IACJ,OAAQN;QACP,KAAK;YACJM,eAAe,MAAMC,IAAAA,sCAAuB,EAACN,KAAKC;YAClD;QACD;YACC,MAAM,IAAIM,MACT;IAEH;IACAF,aAAaG,QAAQ;IAErB,MAAMC,WAAW,AAAC,CAAA,MAAMC,IAAAA,0BAAc,EAACL,aAAY,EAAGM,IAAI;IAE1D,IAAI,CAACP,OAAO;QACX,OAAQF;YACP,KAAK;gBACJU,QAAQC,GAAG,CAACC,KAAKC,SAAS,CAACN;gBAC3B;YACD,KAAK;gBACJG,QAAQC,GAAG,CAACJ,SAASO,IAAI,CAAC;QAC5B;IACD;IAEA,IAAIb,MAAM;QACTlB,qBAAqBwB,UAAUN;IAChC;AACD;AAEO,SAASlB,qBAAqBwB,QAAkB,EAAEN,IAAY;IACpEc,IAAAA,mBAAa,EACZd,MACAW,KAAKC,SAAS,CACb;QACCG,aAAa,CAAC,4CAA4C,EAAEvB,QAAQC,IAAI,CAACoB,IAAI,CAAC,MAAM;QACpFP,UAAUA;IACX,GACA,MACA;AAGH;AAEA,KAAKX,KAAKL,SACR0B,IAAI,CAAC;IACLxB,QAAQyB,IAAI;AACb,GACCC,KAAK,CAAC,CAACC;IACPV,QAAQW,KAAK,CAACD;IACd3B,QAAQyB,IAAI,CAAC;AACd"}
@@ -0,0 +1,21 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", {
3
+ value: true
4
+ });
5
+ _export_star(require("./operations"), exports);
6
+ _export_star(require("./packageGraphs"), exports);
7
+ function _export_star(from, to) {
8
+ Object.keys(from).forEach(function(k) {
9
+ if (k !== "default" && !Object.prototype.hasOwnProperty.call(to, k)) {
10
+ Object.defineProperty(to, k, {
11
+ enumerable: true,
12
+ get: function() {
13
+ return from[k];
14
+ }
15
+ });
16
+ }
17
+ });
18
+ return from;
19
+ }
20
+
21
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/index.ts"],"sourcesContent":["export * from \"./operations\";\nexport * from \"./packageGraphs\";\n"],"names":[],"mappings":";;;;qBAAc;qBACA"}
@@ -0,0 +1,105 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", {
3
+ value: true
4
+ });
5
+ Object.defineProperty(exports, "getESMPackages", {
6
+ enumerable: true,
7
+ get: function() {
8
+ return getESMPackages;
9
+ }
10
+ });
11
+ function _promises() {
12
+ const data = require("fs/promises");
13
+ _promises = function() {
14
+ return data;
15
+ };
16
+ return data;
17
+ }
18
+ function _resolvepackagepath() {
19
+ const data = /*#__PURE__*/ _interop_require_default(require("resolve-package-path"));
20
+ _resolvepackagepath = function() {
21
+ return data;
22
+ };
23
+ return data;
24
+ }
25
+ function _path() {
26
+ const data = require("path");
27
+ _path = function() {
28
+ return data;
29
+ };
30
+ return data;
31
+ }
32
+ function _interop_require_default(obj) {
33
+ return obj && obj.__esModule ? obj : {
34
+ default: obj
35
+ };
36
+ }
37
+ function resolvePkgPath(pkgDir, pkgName, options) {
38
+ const { optionalDepsFromParent, isPatch, isRoot } = options;
39
+ const path = (0, _resolvepackagepath().default)(pkgName, pkgDir);
40
+ if (!path && !optionalDepsFromParent?.[pkgName] && !isPatch) {
41
+ if (isRoot) {
42
+ // Accounts for an unresolvable root project since we're in it
43
+ return (0, _path().join)(pkgDir, "package.json");
44
+ }
45
+ throw new Error(`Non-optional dependency could not be found: ${pkgName} when looking from ${pkgDir}`);
46
+ }
47
+ return path;
48
+ }
49
+ async function getESMPackages(pkgGraph) {
50
+ const packagePathsMap = {};
51
+ // We need to resolve the packageJsons and are fine with optional dependencies missing since we can't tell if we need them
52
+ async function resolvePackageJsons(currentNode, previousOptions) {
53
+ // Look up the package.json
54
+ const jsonPath = resolvePkgPath(previousOptions?.parentPkgPath ?? pkgGraph.pkgDir, currentNode.value.name, {
55
+ optionalDepsFromParent: previousOptions?.optionalDependencies,
56
+ isPatch: currentNode.value.isPatch,
57
+ isRoot: currentNode.value.isRoot
58
+ });
59
+ // If we didn't throw any resolution errors, then we can assume this was optional - we shouldn't resolve down that path
60
+ if (!jsonPath) {
61
+ return [
62
+ {},
63
+ true
64
+ ];
65
+ }
66
+ let pkgInfos = packagePathsMap[currentNode.value.name];
67
+ if (pkgInfos) {
68
+ if (pkgInfos.some((info)=>info.packageJsonPath === jsonPath)) {
69
+ return [
70
+ {},
71
+ false
72
+ ];
73
+ }
74
+ } else {
75
+ pkgInfos = [];
76
+ packagePathsMap[currentNode.value.name] = pkgInfos;
77
+ }
78
+ const contents = await (0, _promises().readFile)(jsonPath);
79
+ const json = JSON.parse(contents.toString());
80
+ pkgInfos.push({
81
+ packageJsonPath: jsonPath,
82
+ isModule: json.type === "module"
83
+ });
84
+ return [
85
+ {
86
+ optionalDependencies: json.optionalDependencies,
87
+ parentPkgPath: jsonPath
88
+ },
89
+ false
90
+ ];
91
+ }
92
+ // Iterate the packages and resolve all non-optional packages and existing optionals
93
+ await pkgGraph.topDownVisitAsync(resolvePackageJsons);
94
+ return Array.from(Object.keys(packagePathsMap).reduce((mods, p)=>{
95
+ const infos = packagePathsMap[p];
96
+ infos.forEach((info)=>{
97
+ if (info.isModule) {
98
+ mods.add(p);
99
+ }
100
+ });
101
+ return mods;
102
+ }, new Set()));
103
+ }
104
+
105
+ //# sourceMappingURL=getESMPackages.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../src/operations/getESMPackages.ts"],"sourcesContent":["import { readFile } from \"fs/promises\";\nimport resolvePackagePath from \"resolve-package-path\";\nimport {\n\tPackageGraph,\n\tPackageInfo,\n\tNode,\n\tPackageInfoKey,\n} from \"../packageGraphs\";\nimport { join } from \"path\";\n\nfunction resolvePkgPath(\n\tpkgDir: string,\n\tpkgName: string,\n\toptions: {\n\t\toptionalDepsFromParent?: {\n\t\t\t[dep: string]: string;\n\t\t};\n\t\t// If this was a patch, we probably can't find a package.json (or at least, I didn't solve this)\n\t\tisPatch: boolean;\n\t\tisRoot: boolean;\n\t},\n) {\n\tconst { optionalDepsFromParent, isPatch, isRoot } = options;\n\tconst path = resolvePackagePath(pkgName, pkgDir);\n\tif (!path && !optionalDepsFromParent?.[pkgName] && !isPatch) {\n\t\tif (isRoot) {\n\t\t\t// Accounts for an unresolvable root project since we're in it\n\t\t\treturn join(pkgDir, \"package.json\");\n\t\t}\n\t\tthrow new Error(\n\t\t\t`Non-optional dependency could not be found: ${pkgName} when looking from ${pkgDir}`,\n\t\t);\n\t}\n\treturn path;\n}\n// options: {\n// /**\n// * Depending on the integrity of your packages, you may get failures due to some packages saying\n// */\n// ignorePackages: string[]\n// }\ninterface VisitReturn {\n\t/**\n\t * The resolved path of the package.json that's requesting this. This is specifically for multi-version resolutions\n\t */\n\tparentPkgPath?: string;\n\toptionalDependencies?: {\n\t\t[dep: string]: string;\n\t};\n}\n\ninterface PkgInfo {\n\tpackageJsonPath: string;\n\tisModule: boolean;\n}\n\n/**\n * Returns the esm packages from a PackageGraph - Assumes we can read package.json (may not work with yarn plug'n'play)\n * @param pkgGraph\n * @returns\n */\nexport async function getESMPackages(pkgGraph: PackageGraph) {\n\tconst packagePathsMap: {\n\t\t// Since packages can be multiply referenced via nested modules, we can have multiple of these\n\t\t[pkgName: string]: PkgInfo[];\n\t} = {};\n\t// We need to resolve the packageJsons and are fine with optional dependencies missing since we can't tell if we need them\n\tasync function resolvePackageJsons(\n\t\tcurrentNode: Node<PackageInfo, PackageInfoKey>,\n\t\tpreviousOptions?: VisitReturn,\n\t): Promise<[VisitReturn, boolean]> {\n\t\t// Look up the package.json\n\t\tconst jsonPath = resolvePkgPath(\n\t\t\tpreviousOptions?.parentPkgPath ?? pkgGraph.pkgDir,\n\t\t\tcurrentNode.value.name,\n\t\t\t{\n\t\t\t\toptionalDepsFromParent: previousOptions?.optionalDependencies,\n\t\t\t\tisPatch: currentNode.value.isPatch,\n\t\t\t\tisRoot: currentNode.value.isRoot,\n\t\t\t},\n\t\t);\n\t\t// If we didn't throw any resolution errors, then we can assume this was optional - we shouldn't resolve down that path\n\t\tif (!jsonPath) {\n\t\t\treturn [{}, true];\n\t\t}\n\t\tlet pkgInfos: PkgInfo[] | undefined =\n\t\t\tpackagePathsMap[currentNode.value.name];\n\t\tif (pkgInfos) {\n\t\t\tif (pkgInfos.some((info) => info.packageJsonPath === jsonPath)) {\n\t\t\t\treturn [{}, false];\n\t\t\t}\n\t\t} else {\n\t\t\tpkgInfos = [] as PkgInfo[];\n\t\t\tpackagePathsMap[currentNode.value.name] = pkgInfos;\n\t\t}\n\n\t\tconst contents = await readFile(jsonPath);\n\t\tconst json = JSON.parse(contents.toString());\n\t\tpkgInfos.push({\n\t\t\tpackageJsonPath: jsonPath,\n\t\t\tisModule: json.type === \"module\",\n\t\t});\n\t\treturn [\n\t\t\t{\n\t\t\t\toptionalDependencies: json.optionalDependencies,\n\t\t\t\tparentPkgPath: jsonPath,\n\t\t\t},\n\t\t\tfalse,\n\t\t];\n\t}\n\n\t// Iterate the packages and resolve all non-optional packages and existing optionals\n\tawait pkgGraph.topDownVisitAsync(resolvePackageJsons);\n\n\treturn Array.from(\n\t\tObject.keys(packagePathsMap).reduce((mods, p) => {\n\t\t\tconst infos = packagePathsMap[p];\n\t\t\tinfos.forEach((info) => {\n\t\t\t\tif (info.isModule) {\n\t\t\t\t\tmods.add(p);\n\t\t\t\t}\n\t\t\t});\n\t\t\treturn mods;\n\t\t}, new Set<string>()),\n\t);\n}\n"],"names":["getESMPackages","resolvePkgPath","pkgDir","pkgName","options","optionalDepsFromParent","isPatch","isRoot","path","resolvePackagePath","join","Error","pkgGraph","packagePathsMap","resolvePackageJsons","currentNode","previousOptions","jsonPath","parentPkgPath","value","name","optionalDependencies","pkgInfos","some","info","packageJsonPath","contents","readFile","json","JSON","parse","toString","push","isModule","type","topDownVisitAsync","Array","from","Object","keys","reduce","mods","p","infos","forEach","add","Set"],"mappings":";;;;+BA6DsBA;;;eAAAA;;;;yBA7DG;;;;;;;gEACM;;;;;;;yBAOV;;;;;;;;;;;AAErB,SAASC,eACRC,MAAc,EACdC,OAAe,EACfC,OAOC;IAED,MAAM,EAAEC,sBAAsB,EAAEC,OAAO,EAAEC,MAAM,EAAE,GAAGH;IACpD,MAAMI,OAAOC,IAAAA,6BAAkB,EAACN,SAASD;IACzC,IAAI,CAACM,QAAQ,CAACH,wBAAwB,CAACF,QAAQ,IAAI,CAACG,SAAS;QAC5D,IAAIC,QAAQ;YACX,8DAA8D;YAC9D,OAAOG,IAAAA,YAAI,EAACR,QAAQ;QACrB;QACA,MAAM,IAAIS,MACT,CAAC,4CAA4C,EAAER,QAAQ,mBAAmB,EAAED,QAAQ;IAEtF;IACA,OAAOM;AACR;AA2BO,eAAeR,eAAeY,QAAsB;IAC1D,MAAMC,kBAGF,CAAC;IACL,0HAA0H;IAC1H,eAAeC,oBACdC,WAA8C,EAC9CC,eAA6B;QAE7B,2BAA2B;QAC3B,MAAMC,WAAWhB,eAChBe,iBAAiBE,iBAAiBN,SAASV,MAAM,EACjDa,YAAYI,KAAK,CAACC,IAAI,EACtB;YACCf,wBAAwBW,iBAAiBK;YACzCf,SAASS,YAAYI,KAAK,CAACb,OAAO;YAClCC,QAAQQ,YAAYI,KAAK,CAACZ,MAAM;QACjC;QAED,uHAAuH;QACvH,IAAI,CAACU,UAAU;YACd,OAAO;gBAAC,CAAC;gBAAG;aAAK;QAClB;QACA,IAAIK,WACHT,eAAe,CAACE,YAAYI,KAAK,CAACC,IAAI,CAAC;QACxC,IAAIE,UAAU;YACb,IAAIA,SAASC,IAAI,CAAC,CAACC,OAASA,KAAKC,eAAe,KAAKR,WAAW;gBAC/D,OAAO;oBAAC,CAAC;oBAAG;iBAAM;YACnB;QACD,OAAO;YACNK,WAAW,EAAE;YACbT,eAAe,CAACE,YAAYI,KAAK,CAACC,IAAI,CAAC,GAAGE;QAC3C;QAEA,MAAMI,WAAW,MAAMC,IAAAA,oBAAQ,EAACV;QAChC,MAAMW,OAAOC,KAAKC,KAAK,CAACJ,SAASK,QAAQ;QACzCT,SAASU,IAAI,CAAC;YACbP,iBAAiBR;YACjBgB,UAAUL,KAAKM,IAAI,KAAK;QACzB;QACA,OAAO;YACN;gBACCb,sBAAsBO,KAAKP,oBAAoB;gBAC/CH,eAAeD;YAChB;YACA;SACA;IACF;IAEA,oFAAoF;IACpF,MAAML,SAASuB,iBAAiB,CAACrB;IAEjC,OAAOsB,MAAMC,IAAI,CAChBC,OAAOC,IAAI,CAAC1B,iBAAiB2B,MAAM,CAAC,CAACC,MAAMC;QAC1C,MAAMC,QAAQ9B,eAAe,CAAC6B,EAAE;QAChCC,MAAMC,OAAO,CAAC,CAACpB;YACd,IAAIA,KAAKS,QAAQ,EAAE;gBAClBQ,KAAKI,GAAG,CAACH;YACV;QACD;QACA,OAAOD;IACR,GAAG,IAAIK;AAET"}
@@ -0,0 +1,21 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", {
3
+ value: true
4
+ });
5
+ _export_star(require("./getESMPackages"), exports);
6
+ _export_star(require("./jest"), exports);
7
+ function _export_star(from, to) {
8
+ Object.keys(from).forEach(function(k) {
9
+ if (k !== "default" && !Object.prototype.hasOwnProperty.call(to, k)) {
10
+ Object.defineProperty(to, k, {
11
+ enumerable: true,
12
+ get: function() {
13
+ return from[k];
14
+ }
15
+ });
16
+ }
17
+ });
18
+ return from;
19
+ }
20
+
21
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../src/operations/index.ts"],"sourcesContent":["export * from \"./getESMPackages\";\nexport * from \"./jest\";\n"],"names":[],"mappings":";;;;qBAAc;qBACA"}
@@ -0,0 +1,52 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", {
3
+ value: true
4
+ });
5
+ function _export(target, all) {
6
+ for(var name in all)Object.defineProperty(target, name, {
7
+ enumerable: true,
8
+ get: all[name]
9
+ });
10
+ }
11
+ _export(exports, {
12
+ createNodeModulesTransformIgnore: function() {
13
+ return createNodeModulesTransformIgnore;
14
+ },
15
+ getJestNodeModulesTransformIgnore: function() {
16
+ return getJestNodeModulesTransformIgnore;
17
+ }
18
+ });
19
+ function _fs() {
20
+ const data = require("fs");
21
+ _fs = function() {
22
+ return data;
23
+ };
24
+ return data;
25
+ }
26
+ function getJestNodeModulesTransformIgnore(options) {
27
+ const { file, extraExceptions = [] } = options;
28
+ const modules = getModulesFromFile(file);
29
+ // Dedup
30
+ const modSet = new Set([
31
+ ...modules,
32
+ ...extraExceptions
33
+ ]);
34
+ return createNodeModulesTransformIgnore(Array.from(modSet));
35
+ }
36
+ function getModulesFromFile(file) {
37
+ try {
38
+ const esmModules = JSON.parse((0, _fs().readFileSync)(file).toString());
39
+ if (!esmModules.packages || !Array.isArray(esmModules.packages)) {
40
+ throw new Error("Esm packages file object is missing the expected packages field!");
41
+ }
42
+ return esmModules.packages;
43
+ } catch (err) {
44
+ console.error(`Malformed esm modules file: ${file}`);
45
+ throw err;
46
+ }
47
+ }
48
+ function createNodeModulesTransformIgnore(packageExceptions) {
49
+ return `node_modules/(?!${packageExceptions.map((p)=>`${p}/`).join("|")})`;
50
+ }
51
+
52
+ //# sourceMappingURL=jest.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../src/operations/jest.ts"],"sourcesContent":["import { readFileSync } from \"fs\";\n\nexport interface EsmPackagesFile {\n\tdescription: string;\n\t/**\n\t * Package names that are esm modules\n\t */\n\tpackages: string[];\n}\n\n/**\n * You can use this function to get get a transformIgnore pattern for jest that excludes node_modules\n * from a file where we have written all esm files that were detected.\n *\n * This is specifically designed for a \"post-install\" script that scans on install and overwrites the file\n * if there are new esm module types - thereby reducing the cost of tests to just a file read instead of a\n * tree scan.\n *\n * @param options\n * @returns\n */\nexport function getJestNodeModulesTransformIgnore(options: {\n\t/**\n\t * The file location where we have written the esm module info to\n\t *\n\t * default (esm-modules.json)\n\t */\n\tfile: string;\n\t/**\n\t * Extra packages for an exception for node modules\n\t */\n\textraExceptions?: string[];\n}) {\n\tconst { file, extraExceptions = [] } = options;\n\tconst modules = getModulesFromFile(file);\n\t// Dedup\n\tconst modSet = new Set<string>([...modules, ...extraExceptions]);\n\treturn createNodeModulesTransformIgnore(Array.from(modSet));\n}\n\nfunction getModulesFromFile(file: string) {\n\ttry {\n\t\tconst esmModules = JSON.parse(\n\t\t\treadFileSync(file).toString(),\n\t\t) as EsmPackagesFile;\n\t\tif (!esmModules.packages || !Array.isArray(esmModules.packages)) {\n\t\t\tthrow new Error(\n\t\t\t\t\"Esm packages file object is missing the expected packages field!\",\n\t\t\t);\n\t\t}\n\t\treturn esmModules.packages;\n\t} catch (err) {\n\t\tconsole.error(`Malformed esm modules file: ${file}`);\n\t\tthrow err;\n\t}\n}\n\n/**\n * Given a set of package names, this constructs a node_modules ignore string that exempts the\n * targeted modules from jest transform.\n *\n * It should be used with the transformIgnore configuration.\n * @param packageExceptions\n * @returns\n */\nexport function createNodeModulesTransformIgnore(packageExceptions: string[]) {\n\treturn `node_modules/(?!${packageExceptions.map((p) => `${p}/`).join(\"|\")})`;\n}\n"],"names":["createNodeModulesTransformIgnore","getJestNodeModulesTransformIgnore","options","file","extraExceptions","modules","getModulesFromFile","modSet","Set","Array","from","esmModules","JSON","parse","readFileSync","toString","packages","isArray","Error","err","console","error","packageExceptions","map","p","join"],"mappings":";;;;;;;;;;;IAiEgBA,gCAAgC;eAAhCA;;IA5CAC,iCAAiC;eAAjCA;;;;yBArBa;;;;;;AAqBtB,SAASA,kCAAkCC,OAWjD;IACA,MAAM,EAAEC,IAAI,EAAEC,kBAAkB,EAAE,EAAE,GAAGF;IACvC,MAAMG,UAAUC,mBAAmBH;IACnC,QAAQ;IACR,MAAMI,SAAS,IAAIC,IAAY;WAAIH;WAAYD;KAAgB;IAC/D,OAAOJ,iCAAiCS,MAAMC,IAAI,CAACH;AACpD;AAEA,SAASD,mBAAmBH,IAAY;IACvC,IAAI;QACH,MAAMQ,aAAaC,KAAKC,KAAK,CAC5BC,IAAAA,kBAAY,EAACX,MAAMY,QAAQ;QAE5B,IAAI,CAACJ,WAAWK,QAAQ,IAAI,CAACP,MAAMQ,OAAO,CAACN,WAAWK,QAAQ,GAAG;YAChE,MAAM,IAAIE,MACT;QAEF;QACA,OAAOP,WAAWK,QAAQ;IAC3B,EAAE,OAAOG,KAAK;QACbC,QAAQC,KAAK,CAAC,CAAC,4BAA4B,EAAElB,MAAM;QACnD,MAAMgB;IACP;AACD;AAUO,SAASnB,iCAAiCsB,iBAA2B;IAC3E,OAAO,CAAC,gBAAgB,EAAEA,kBAAkBC,GAAG,CAAC,CAACC,IAAM,GAAGA,EAAE,CAAC,CAAC,EAAEC,IAAI,CAAC,KAAK,CAAC,CAAC;AAC7E"}
@@ -0,0 +1,130 @@
1
+ // TODO: it would be nice to split this into a package for reuse
2
+ /**
3
+ * Describes a node in a graph that has a value of a specific type
4
+ * and then points to values of others nodes
5
+ */ "use strict";
6
+ Object.defineProperty(exports, "__esModule", {
7
+ value: true
8
+ });
9
+ Object.defineProperty(exports, "Graph", {
10
+ enumerable: true,
11
+ get: function() {
12
+ return Graph;
13
+ }
14
+ });
15
+ function _define_property(obj, key, value) {
16
+ if (key in obj) {
17
+ Object.defineProperty(obj, key, {
18
+ value: value,
19
+ enumerable: true,
20
+ configurable: true,
21
+ writable: true
22
+ });
23
+ } else {
24
+ obj[key] = value;
25
+ }
26
+ return obj;
27
+ }
28
+ let Graph = class Graph {
29
+ getNodeKeyStr(nodeKey) {
30
+ return this.keySerializer ? this.keySerializer(nodeKey) : nodeKey;
31
+ }
32
+ addDownstreamNode(node) {
33
+ const nodeKeyStr = this.getNodeKeyStr(node.self);
34
+ // If a previous node prestubbed in the next node, we add it here
35
+ if (this.map.has(nodeKeyStr)) {
36
+ const preStubbedNode = this.map.get(nodeKeyStr);
37
+ if (preStubbedNode.value !== undefined) {
38
+ throw new Error(`Already added a downstream node of same key: ${nodeKeyStr} - Can't add ${JSON.stringify(node)}`);
39
+ }
40
+ preStubbedNode.to.push(...node.to);
41
+ preStubbedNode.value = node.value;
42
+ } else {
43
+ this.map.set(nodeKeyStr, {
44
+ from: [],
45
+ ...node
46
+ });
47
+ this.noFrom.add(nodeKeyStr);
48
+ }
49
+ // Add to or pre-stub some nodes
50
+ node.to.forEach((n)=>{
51
+ const nkStr = this.getNodeKeyStr(n);
52
+ if (this.map.has(nkStr)) {
53
+ const existingNode = this.map.get(nkStr);
54
+ existingNode.from.push(node.self);
55
+ if (existingNode.from.length === 1) {
56
+ // We were wrong about this package
57
+ this.noFrom.delete(nkStr);
58
+ }
59
+ } else {
60
+ this.map.set(nkStr, {
61
+ self: n,
62
+ from: [
63
+ node.self
64
+ ],
65
+ to: [],
66
+ value: undefined
67
+ });
68
+ }
69
+ });
70
+ }
71
+ validate() {
72
+ const errors = [];
73
+ for (let [k, node] of this.map.entries()){
74
+ if (!node.value) {
75
+ errors.push(`Unregistered node: ${k}! Node was pointed to by: ${JSON.stringify(node.from)}`);
76
+ }
77
+ }
78
+ if (errors.length > 0) {
79
+ throw new Error(errors.join("\n"));
80
+ }
81
+ }
82
+ /**
83
+ *
84
+ * @param visit
85
+ * @param firstArrivalOnly - if set to true, we are saying that we do not care about from where we get to the node, just the first arrival matters
86
+ * This will depend on your visit function, since the visit function can pass parent -> child info that may change based on the node
87
+ * it is coming from
88
+ */ async topDownVisitAsync(visit, firstArrivalOnly) {
89
+ const guestBook = firstArrivalOnly ? new Set() : undefined;
90
+ for (const noFrom of this.noFrom){
91
+ const node = this.map.get(noFrom);
92
+ await this.visitDownNodeAsync(node, visit, guestBook);
93
+ }
94
+ }
95
+ /**
96
+ *
97
+ * @param nodeKey - the key that we used to retrieve this node
98
+ * @param node - the node itself
99
+ * @param visit - the visit function
100
+ * @param guestBook - This is used to track if we have already visited the node - note this means we don't expect the visit function to change results
101
+ * regardless of the node that we come from
102
+ * @param prevResult - the result of the last node that got here
103
+ * @returns
104
+ */ async visitDownNodeAsync(node, visit, guestBook, prevResult) {
105
+ if (guestBook?.has(this.getNodeKeyStr(node.self))) {
106
+ // We already visited this node
107
+ return;
108
+ }
109
+ const [result, stop] = await visit(node, prevResult);
110
+ if (stop) {
111
+ // We let the visitor control travel
112
+ return;
113
+ }
114
+ await Promise.all(node.to.map((n)=>{
115
+ return this.visitDownNodeAsync(this.map.get(this.getNodeKeyStr(n)), visit, guestBook, result);
116
+ }));
117
+ }
118
+ /**
119
+ *
120
+ * @param keySerializer - if the graph has a compound key, then you must supply a function that converts a compound key to a string
121
+ */ constructor(keySerializer){
122
+ // This map is partially filled so we allow undefined values internally
123
+ _define_property(this, "map", new Map());
124
+ _define_property(this, "noFrom", new Set());
125
+ _define_property(this, "keySerializer", void 0);
126
+ this.keySerializer = keySerializer;
127
+ }
128
+ };
129
+
130
+ //# sourceMappingURL=Graph.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../src/packageGraphs/Graph.ts"],"sourcesContent":["// TODO: it would be nice to split this into a package for reuse\n\n/**\n * Describes a node in a graph that has a value of a specific type\n * and then points to values of others nodes\n */\nexport interface Node<T, NodeKey> {\n\tself: NodeKey;\n\tfrom: NodeKey[];\n\tto: NodeKey[];\n\tvalue: T;\n}\n\n/**\n * A node that we only know where it goes to at the moment\n */\nexport interface DownstreamNode<T, NodeKey> {\n\tself: NodeKey;\n\tvalue: T;\n\tto: NodeKey[];\n}\n\n/**\n * If using a compound node key, then we require a node key serializer to get a base string out of it\n */\ntype NodeKeySerializer<T> = T extends string ? undefined : (t: T) => string;\n\n/**\n * Mnimal \"graph\" class that takes in a bunch of nodes and then allows you to visit them in a particular order.\n *\n * The value of the node <T> is used as the unique node key for referencing other nodes.\n */\nexport class Graph<\n\tT,\n\tNodeKey,\n\tNKSerializer extends NodeKeySerializer<NodeKey> = NodeKeySerializer<NodeKey>,\n> {\n\t// This map is partially filled so we allow undefined values internally\n\treadonly map = new Map<string, Node<T | undefined, NodeKey>>();\n\tprivate readonly noFrom = new Set<string>();\n\treadonly keySerializer: NKSerializer;\n\n\t/**\n\t *\n\t * @param keySerializer - if the graph has a compound key, then you must supply a function that converts a compound key to a string\n\t */\n\tconstructor(keySerializer: NKSerializer) {\n\t\tthis.keySerializer = keySerializer;\n\t}\n\n\tprivate getNodeKeyStr(nodeKey: NodeKey): string {\n\t\treturn this.keySerializer\n\t\t\t? this.keySerializer(nodeKey)\n\t\t\t: (nodeKey as string);\n\t}\n\n\taddDownstreamNode(node: DownstreamNode<T, NodeKey>) {\n\t\tconst nodeKeyStr = this.getNodeKeyStr(node.self);\n\n\t\t// If a previous node prestubbed in the next node, we add it here\n\t\tif (this.map.has(nodeKeyStr)) {\n\t\t\tconst preStubbedNode = this.map.get(nodeKeyStr)!;\n\t\t\tif (preStubbedNode.value !== undefined) {\n\t\t\t\tthrow new Error(\n\t\t\t\t\t`Already added a downstream node of same key: ${nodeKeyStr} - Can't add ${JSON.stringify(node)}`,\n\t\t\t\t);\n\t\t\t}\n\t\t\tpreStubbedNode.to.push(...node.to);\n\t\t\tpreStubbedNode.value = node.value;\n\t\t} else {\n\t\t\tthis.map.set(nodeKeyStr, {\n\t\t\t\tfrom: [],\n\t\t\t\t...node,\n\t\t\t});\n\t\t\tthis.noFrom.add(nodeKeyStr);\n\t\t}\n\n\t\t// Add to or pre-stub some nodes\n\t\tnode.to.forEach((n) => {\n\t\t\tconst nkStr = this.getNodeKeyStr(n);\n\t\t\tif (this.map.has(nkStr)) {\n\t\t\t\tconst existingNode = this.map.get(nkStr)!;\n\t\t\t\texistingNode.from.push(node.self);\n\t\t\t\tif (existingNode.from.length === 1) {\n\t\t\t\t\t// We were wrong about this package\n\t\t\t\t\tthis.noFrom.delete(nkStr);\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tthis.map.set(nkStr, {\n\t\t\t\t\tself: n,\n\t\t\t\t\tfrom: [node.self],\n\t\t\t\t\tto: [],\n\t\t\t\t\tvalue: undefined,\n\t\t\t\t} as Node<T | undefined, NodeKey>);\n\t\t\t}\n\t\t});\n\t}\n\n\tvalidate() {\n\t\tconst errors = [];\n\t\tfor (let [k, node] of this.map.entries()) {\n\t\t\tif (!node.value) {\n\t\t\t\terrors.push(\n\t\t\t\t\t`Unregistered node: ${k}! Node was pointed to by: ${JSON.stringify(node.from)}`,\n\t\t\t\t);\n\t\t\t}\n\t\t}\n\t\tif (errors.length > 0) {\n\t\t\tthrow new Error(errors.join(\"\\n\"));\n\t\t}\n\t}\n\n\t/**\n\t *\n\t * @param visit\n\t * @param firstArrivalOnly - if set to true, we are saying that we do not care about from where we get to the node, just the first arrival matters\n\t * This will depend on your visit function, since the visit function can pass parent -> child info that may change based on the node\n\t * it is coming from\n\t */\n\tasync topDownVisitAsync<R>(\n\t\tvisit: VisitFunction<Node<T, NodeKey>, R>,\n\t\tfirstArrivalOnly?: boolean,\n\t) {\n\t\tconst guestBook = firstArrivalOnly ? new Set<string>() : undefined;\n\t\tfor (const noFrom of this.noFrom) {\n\t\t\tconst node = this.map.get(noFrom)!;\n\t\t\tawait this.visitDownNodeAsync(node as Node<T, NodeKey>, visit, guestBook);\n\t\t}\n\t}\n\n\t/**\n\t *\n\t * @param nodeKey - the key that we used to retrieve this node\n\t * @param node - the node itself\n\t * @param visit - the visit function\n\t * @param guestBook - This is used to track if we have already visited the node - note this means we don't expect the visit function to change results\n\t * regardless of the node that we come from\n\t * @param prevResult - the result of the last node that got here\n\t * @returns\n\t */\n\tasync visitDownNodeAsync<R>(\n\t\tnode: Node<T, NodeKey>,\n\t\tvisit: VisitFunction<Node<T, NodeKey>, R>,\n\t\tguestBook?: Set<string>,\n\t\tprevResult?: R,\n\t) {\n\t\tif (guestBook?.has(this.getNodeKeyStr(node.self))) {\n\t\t\t// We already visited this node\n\t\t\treturn;\n\t\t}\n\t\tconst [result, stop] = await visit(node, prevResult);\n\t\tif (stop) {\n\t\t\t// We let the visitor control travel\n\t\t\treturn;\n\t\t}\n\t\tawait Promise.all(\n\t\t\tnode.to.map((n) => {\n\t\t\t\treturn this.visitDownNodeAsync(\n\t\t\t\t\tthis.map.get(this.getNodeKeyStr(n))! as Node<T, NodeKey>,\n\t\t\t\t\tvisit,\n\t\t\t\t\tguestBook,\n\t\t\t\t\tresult,\n\t\t\t\t);\n\t\t\t}),\n\t\t);\n\t}\n}\n\ntype StopVisiting = boolean;\n\n/**\n * This function will be called for each visit while traversing along the \"to\" nodes. You can return\n * a result from the visit function that will be provided to any of the \"to\" visitors as the previous result.\n *\n * Additionally, if you return a boolean value in the second tuple, it can stop any further downstream visits from this\n * particular visitor function. (Keep in mind that a visitor can only stop further travel from itself, so if there are\n * multiple visits from multiple nodes each visitor will need to stop further travel. If you do use a guestbook, in a\n * visiting function, that would stop travel fromm the visitor function that first calls stop.)\n */\ntype VisitFunction<Node, R> = (\n\tcurrentNode: Node,\n\tpreviousResult?: R,\n) => Promise<[R, StopVisiting]>;\n"],"names":["Graph","getNodeKeyStr","nodeKey","keySerializer","addDownstreamNode","node","nodeKeyStr","self","map","has","preStubbedNode","get","value","undefined","Error","JSON","stringify","to","push","set","from","noFrom","add","forEach","n","nkStr","existingNode","length","delete","validate","errors","k","entries","join","topDownVisitAsync","visit","firstArrivalOnly","guestBook","Set","visitDownNodeAsync","prevResult","result","stop","Promise","all","constructor","Map"],"mappings":"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"}
@@ -0,0 +1,42 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", {
3
+ value: true
4
+ });
5
+ Object.defineProperty(exports, "PackageGraph", {
6
+ enumerable: true,
7
+ get: function() {
8
+ return PackageGraph;
9
+ }
10
+ });
11
+ function _path() {
12
+ const data = require("path");
13
+ _path = function() {
14
+ return data;
15
+ };
16
+ return data;
17
+ }
18
+ const _Graph = require("./Graph");
19
+ function _define_property(obj, key, value) {
20
+ if (key in obj) {
21
+ Object.defineProperty(obj, key, {
22
+ value: value,
23
+ enumerable: true,
24
+ configurable: true,
25
+ writable: true
26
+ });
27
+ } else {
28
+ obj[key] = value;
29
+ }
30
+ return obj;
31
+ }
32
+ let PackageGraph = class PackageGraph extends _Graph.Graph {
33
+ constructor(pkgDir){
34
+ super((node)=>`${node.name}@${node.version}`), _define_property(this, "pkgDir", void 0);
35
+ if (!pkgDir) {
36
+ throw new Error("Must supply a pkgDir!");
37
+ }
38
+ this.pkgDir = (0, _path().resolve)(pkgDir);
39
+ }
40
+ };
41
+
42
+ //# sourceMappingURL=PackageGraph.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../src/packageGraphs/PackageGraph.ts"],"sourcesContent":["import { resolve } from \"path\";\nimport { Graph } from \"./Graph\";\n\nexport interface PackageInfo {\n\tname: string;\n\tversion: string;\n\t// We need this because some patches will register as dependencies but won't be able to resolve things\n\tisPatch: boolean;\n\t// We need this because some trees will contain the base package which won't self-resolve\n\tisRoot: boolean;\n}\n\nexport interface PackageInfoKey {\n\tname: string;\n\tversion: string;\n}\n\n/**\n * A graph of package names and their dependencies\n */\nexport class PackageGraph extends Graph<PackageInfo, PackageInfoKey> {\n\treadonly pkgDir: string;\n\tconstructor(pkgDir: string) {\n\t\tsuper((node: PackageInfoKey) => `${node.name}@${node.version}`);\n\n\t\tif (!pkgDir) {\n\t\t\tthrow new Error(\"Must supply a pkgDir!\");\n\t\t}\n\t\tthis.pkgDir = resolve(pkgDir);\n\t}\n}\n"],"names":["PackageGraph","Graph","constructor","pkgDir","node","name","version","Error","resolve"],"mappings":";;;;+BAoBaA;;;eAAAA;;;;yBApBW;;;;;;uBACF;;;;;;;;;;;;;;AAmBf,IAAA,AAAMA,eAAN,MAAMA,qBAAqBC,YAAK;IAEtCC,YAAYC,MAAc,CAAE;QAC3B,KAAK,CAAC,CAACC,OAAyB,GAAGA,KAAKC,IAAI,CAAC,CAAC,EAAED,KAAKE,OAAO,EAAE,GAF/D,uBAASH,UAAT,KAAA;QAIC,IAAI,CAACA,QAAQ;YACZ,MAAM,IAAII,MAAM;QACjB;QACA,IAAI,CAACJ,MAAM,GAAGK,IAAAA,eAAO,EAACL;IACvB;AACD"}
@@ -0,0 +1,128 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", {
3
+ value: true
4
+ });
5
+ Object.defineProperty(exports, "getYarnInfoPackageGraph", {
6
+ enumerable: true,
7
+ get: function() {
8
+ return getYarnInfoPackageGraph;
9
+ }
10
+ });
11
+ function _child_process() {
12
+ const data = require("child_process");
13
+ _child_process = function() {
14
+ return data;
15
+ };
16
+ return data;
17
+ }
18
+ const _PackageGraph = require("./PackageGraph");
19
+ function _fs() {
20
+ const data = require("fs");
21
+ _fs = function() {
22
+ return data;
23
+ };
24
+ return data;
25
+ }
26
+ function _path() {
27
+ const data = require("path");
28
+ _path = function() {
29
+ return data;
30
+ };
31
+ return data;
32
+ }
33
+ /**
34
+ * Gets the first package.json that can be found
35
+ */ function getRootPackageJson(start, curDir) {
36
+ const dir = curDir ?? start;
37
+ const testPath = (0, _path().join)(dir, "package.json");
38
+ if ((0, _fs().existsSync)(testPath)) {
39
+ return testPath;
40
+ }
41
+ const oneUp = (0, _path().dirname)(dir);
42
+ if (!oneUp) {
43
+ throw new Error(`Could not find package.json traveling up from start dir at ${start}`);
44
+ }
45
+ return getRootPackageJson(start, oneUp);
46
+ }
47
+ async function getYarnInfoPackageGraph(pkgDir, recurse) {
48
+ const query = (0, _child_process().execSync)(`yarn info ${recurse ? "-R" : ""} --json`, {
49
+ cwd: pkgDir,
50
+ stdio: "pipe"
51
+ });
52
+ // Get the current package name so we can determine the root
53
+ const rootPkgJsonPath = getRootPackageJson(pkgDir);
54
+ let rootPkgName = "";
55
+ try {
56
+ rootPkgName = JSON.parse((0, _fs().readFileSync)(rootPkgJsonPath).toString()).name;
57
+ } catch (e) {
58
+ console.error("Error retrieving root package name!");
59
+ throw e;
60
+ }
61
+ const packageGraph = new _PackageGraph.PackageGraph(pkgDir);
62
+ // Since the info shows multiple versions we keep a dedup set of the serialized key to avoid longer times
63
+ const dedupSet = new Set();
64
+ return query.toString().split("\n").reduce((pkgGraph, q)=>{
65
+ // Make sure we have an actual value
66
+ if (q.trim()) {
67
+ const pkgInfo = JSON.parse(q);
68
+ const { name, version, isPatch } = parsePackage(pkgInfo.value);
69
+ const nameKey = packageGraph.keySerializer({
70
+ name,
71
+ version
72
+ });
73
+ if (!dedupSet.has(nameKey)) {
74
+ dedupSet.add(nameKey);
75
+ // List of package names as dependencies
76
+ let deps;
77
+ if (recurse) {
78
+ deps = pkgInfo.children?.Dependencies?.map((deps)=>{
79
+ const info = parsePackage(deps.locator);
80
+ return {
81
+ name: info.name,
82
+ version: info.version
83
+ };
84
+ }) ?? [];
85
+ } else {
86
+ // We don't actually set up the dependencies because that would make the graph incomplete
87
+ deps = [];
88
+ }
89
+ packageGraph.addDownstreamNode({
90
+ self: {
91
+ name,
92
+ version
93
+ },
94
+ value: {
95
+ name,
96
+ version,
97
+ isPatch,
98
+ isRoot: name === rootPkgName
99
+ },
100
+ to: deps ?? []
101
+ });
102
+ }
103
+ }
104
+ return pkgGraph;
105
+ }, packageGraph);
106
+ }
107
+ function parsePackage(pkgAndVersion) {
108
+ const versionIdx = pkgAndVersion.indexOf("@", 1);
109
+ if (versionIdx < 0) {
110
+ throw new Error(`could not find version from name: ${pkgAndVersion}`);
111
+ }
112
+ let version = pkgAndVersion.substring(versionIdx + 1);
113
+ // Parse out virtual versions since those are just file directors used by yarn
114
+ if (version.startsWith("virtual:")) {
115
+ const hashIdx = version.lastIndexOf("#");
116
+ if (hashIdx < 1) {
117
+ throw new Error(`could not find the expected # for virtual locator information`);
118
+ }
119
+ version = version.substring(hashIdx + 1);
120
+ }
121
+ return {
122
+ name: pkgAndVersion.substring(0, versionIdx),
123
+ version,
124
+ isPatch: version.includes("patch")
125
+ };
126
+ }
127
+
128
+ //# sourceMappingURL=getYarnInfoPackageGraph.js.map