@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 @@
1
+ {"version":3,"sources":["../../../src/packageGraphs/getYarnInfoPackageGraph.ts"],"sourcesContent":["import { execSync } from \"child_process\";\nimport { PackageGraph, PackageInfoKey } from \"./PackageGraph\";\nimport { existsSync, readFileSync } from \"fs\";\nimport { dirname, join } from \"path\";\n\n/**\n * Gets the first package.json that can be found\n */\nfunction getRootPackageJson(start: string, curDir?: string) {\n\tconst dir = curDir ?? start;\n\tconst testPath = join(dir, \"package.json\");\n\tif (existsSync(testPath)) {\n\t\treturn testPath;\n\t}\n\tconst oneUp = dirname(dir);\n\n\tif (!oneUp) {\n\t\tthrow new Error(\n\t\t\t`Could not find package.json traveling up from start dir at ${start}`,\n\t\t);\n\t}\n\treturn getRootPackageJson(start, oneUp);\n}\n\n/**\n * Retrieves the dependencies for a package in a PackageGraph\n * @param pkgDir - the directory where the top-level package is\n * @param recurse - get all the packages through all immediate dependencies\n * @returns\n */\nexport async function getYarnInfoPackageGraph(\n\tpkgDir: string,\n\trecurse: boolean,\n): Promise<PackageGraph> {\n\tconst query = execSync(`yarn info ${recurse ? \"-R\" : \"\"} --json`, {\n\t\tcwd: pkgDir,\n\t\tstdio: \"pipe\",\n\t});\n\n\t// Get the current package name so we can determine the root\n\tconst rootPkgJsonPath = getRootPackageJson(pkgDir);\n\tlet rootPkgName = \"\";\n\ttry {\n\t\trootPkgName = JSON.parse(readFileSync(rootPkgJsonPath).toString()).name;\n\t} catch (e) {\n\t\tconsole.error(\"Error retrieving root package name!\");\n\t\tthrow e;\n\t}\n\n\tconst packageGraph = new PackageGraph(pkgDir);\n\t// Since the info shows multiple versions we keep a dedup set of the serialized key to avoid longer times\n\tconst dedupSet = new Set<string>();\n\n\treturn query\n\t\t.toString()\n\t\t.split(\"\\n\")\n\t\t.reduce((pkgGraph, q) => {\n\t\t\t// Make sure we have an actual value\n\t\t\tif (q.trim()) {\n\t\t\t\tconst pkgInfo = JSON.parse(q) as YamlInfoDeps;\n\t\t\t\tconst { name, version, isPatch } = parsePackage(pkgInfo.value);\n\t\t\t\tconst nameKey = packageGraph.keySerializer({\n\t\t\t\t\tname,\n\t\t\t\t\tversion,\n\t\t\t\t});\n\t\t\t\tif (!dedupSet.has(nameKey)) {\n\t\t\t\t\tdedupSet.add(nameKey);\n\t\t\t\t\t// List of package names as dependencies\n\t\t\t\t\tlet deps: PackageInfoKey[];\n\t\t\t\t\tif (recurse) {\n\t\t\t\t\t\tdeps =\n\t\t\t\t\t\t\tpkgInfo.children?.Dependencies?.map((deps) => {\n\t\t\t\t\t\t\t\tconst info = parsePackage(deps.locator);\n\t\t\t\t\t\t\t\treturn {\n\t\t\t\t\t\t\t\t\tname: info.name,\n\t\t\t\t\t\t\t\t\tversion: info.version,\n\t\t\t\t\t\t\t\t};\n\t\t\t\t\t\t\t}) ?? [];\n\t\t\t\t\t} else {\n\t\t\t\t\t\t// We don't actually set up the dependencies because that would make the graph incomplete\n\t\t\t\t\t\tdeps = [];\n\t\t\t\t\t}\n\t\t\t\t\tpackageGraph.addDownstreamNode({\n\t\t\t\t\t\tself: {\n\t\t\t\t\t\t\tname,\n\t\t\t\t\t\t\tversion,\n\t\t\t\t\t\t},\n\t\t\t\t\t\tvalue: {\n\t\t\t\t\t\t\tname,\n\t\t\t\t\t\t\tversion,\n\t\t\t\t\t\t\tisPatch,\n\t\t\t\t\t\t\tisRoot: name === rootPkgName,\n\t\t\t\t\t\t},\n\t\t\t\t\t\tto: deps ?? [],\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn pkgGraph;\n\t\t}, packageGraph);\n}\n\nfunction parsePackage(pkgAndVersion: string): {\n\tname: string;\n\tversion: string;\n\tisPatch: boolean;\n} {\n\tconst versionIdx = pkgAndVersion.indexOf(\"@\", 1);\n\tif (versionIdx < 0) {\n\t\tthrow new Error(`could not find version from name: ${pkgAndVersion}`);\n\t}\n\tlet version = pkgAndVersion.substring(versionIdx + 1);\n\t// Parse out virtual versions since those are just file directors used by yarn\n\tif (version.startsWith(\"virtual:\")) {\n\t\tconst hashIdx = version.lastIndexOf(\"#\");\n\t\tif (hashIdx < 1) {\n\t\t\tthrow new Error(\n\t\t\t\t`could not find the expected # for virtual locator information`,\n\t\t\t);\n\t\t}\n\t\tversion = version.substring(hashIdx + 1);\n\t}\n\treturn {\n\t\tname: pkgAndVersion.substring(0, versionIdx),\n\t\tversion,\n\t\tisPatch: version.includes(\"patch\"),\n\t};\n}\n\ninterface YamlInfoDeps {\n\tvalue: string;\n\tchildren?: {\n\t\tInstances: number;\n\t\tVersion: string;\n\t\tDependencies?: {\n\t\t\tdescriptor: string;\n\t\t\tlocator: string;\n\t\t}[];\n\t};\n}\n"],"names":["getYarnInfoPackageGraph","getRootPackageJson","start","curDir","dir","testPath","join","existsSync","oneUp","dirname","Error","pkgDir","recurse","query","execSync","cwd","stdio","rootPkgJsonPath","rootPkgName","JSON","parse","readFileSync","toString","name","e","console","error","packageGraph","PackageGraph","dedupSet","Set","split","reduce","pkgGraph","q","trim","pkgInfo","version","isPatch","parsePackage","value","nameKey","keySerializer","has","add","deps","children","Dependencies","map","info","locator","addDownstreamNode","self","isRoot","to","pkgAndVersion","versionIdx","indexOf","substring","startsWith","hashIdx","lastIndexOf","includes"],"mappings":"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"}
@@ -0,0 +1,23 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", {
3
+ value: true
4
+ });
5
+ _export_star(require("./types"), exports);
6
+ _export_star(require("./Graph"), exports);
7
+ _export_star(require("./PackageGraph"), exports);
8
+ _export_star(require("./getYarnInfoPackageGraph"), exports);
9
+ function _export_star(from, to) {
10
+ Object.keys(from).forEach(function(k) {
11
+ if (k !== "default" && !Object.prototype.hasOwnProperty.call(to, k)) {
12
+ Object.defineProperty(to, k, {
13
+ enumerable: true,
14
+ get: function() {
15
+ return from[k];
16
+ }
17
+ });
18
+ }
19
+ });
20
+ return from;
21
+ }
22
+
23
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../src/packageGraphs/index.ts"],"sourcesContent":["export * from \"./types\";\nexport * from \"./Graph\";\nexport * from \"./PackageGraph\";\nexport * from \"./getYarnInfoPackageGraph\";\n"],"names":[],"mappings":";;;;qBAAc;qBACA;qBACA;qBACA"}
@@ -0,0 +1,6 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", {
3
+ value: true
4
+ });
5
+
6
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../src/packageGraphs/types.ts"],"names":[],"mappings":""}
@@ -0,0 +1,86 @@
1
+ function asyncGeneratorStep(gen, resolve, reject, _next, _throw, key, arg) {
2
+ try {
3
+ var info = gen[key](arg);
4
+ var value = info.value;
5
+ } catch (error) {
6
+ reject(error);
7
+ return;
8
+ }
9
+ if (info.done) {
10
+ resolve(value);
11
+ } else {
12
+ Promise.resolve(value).then(_next, _throw);
13
+ }
14
+ }
15
+ function _async_to_generator(fn) {
16
+ return function() {
17
+ var self = this, args = arguments;
18
+ return new Promise(function(resolve, reject) {
19
+ var gen = fn.apply(self, args);
20
+ function _next(value) {
21
+ asyncGeneratorStep(gen, resolve, reject, _next, _throw, "next", value);
22
+ }
23
+ function _throw(err) {
24
+ asyncGeneratorStep(gen, resolve, reject, _next, _throw, "throw", err);
25
+ }
26
+ _next(undefined);
27
+ });
28
+ };
29
+ }
30
+ import { program, Option } from "commander";
31
+ import { getESMPackages } from "../operations";
32
+ import { getYarnInfoPackageGraph } from "../packageGraphs";
33
+ import { writeFileSync } from "fs";
34
+ program.addOption(new Option("-p, --pkgManager <pkgManager>", "The package manager that you are running under - will be used to resolve modules").choices([
35
+ "yarnv2+"
36
+ ]).makeOptionMandatory()).addOption(new Option("-o, --output <output>", "How to output the package info").choices([
37
+ "json",
38
+ "console",
39
+ "none"
40
+ ]).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);
41
+ const options = program.parse(process.argv).opts();
42
+ function main(options) {
43
+ return _main.apply(this, arguments);
44
+ }
45
+ function _main() {
46
+ _main = _async_to_generator(function*(options) {
47
+ const { pkgManager, cwd = process.cwd(), recurse, output, file, quiet } = options;
48
+ let packageGraph;
49
+ switch(pkgManager){
50
+ case "yarnv2+":
51
+ packageGraph = yield getYarnInfoPackageGraph(cwd, recurse);
52
+ break;
53
+ default:
54
+ throw new Error("Unimplemented package manager GetPackagesGraphFn mapping!");
55
+ }
56
+ packageGraph.validate();
57
+ const packages = (yield getESMPackages(packageGraph)).sort();
58
+ if (!quiet) {
59
+ switch(output){
60
+ case "json":
61
+ console.log(JSON.stringify(packages));
62
+ break;
63
+ case "console":
64
+ console.log(packages.join("\n"));
65
+ }
66
+ }
67
+ if (file) {
68
+ writeESMModuleOutput(packages, file);
69
+ }
70
+ });
71
+ return _main.apply(this, arguments);
72
+ }
73
+ export function writeESMModuleOutput(packages, file) {
74
+ writeFileSync(file, JSON.stringify({
75
+ description: `This is a programmatically created file via ${process.argv.join(" ")}`,
76
+ packages: packages
77
+ }, null, 4));
78
+ }
79
+ void main(options).then(()=>{
80
+ process.exit();
81
+ }).catch((err)=>{
82
+ console.error(err);
83
+ process.exit(5);
84
+ });
85
+
86
+ //# sourceMappingURL=get-esm-packages.mjs.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":["program","Option","getESMPackages","getYarnInfoPackageGraph","writeFileSync","addOption","choices","makeOptionMandatory","default","option","options","parse","process","argv","opts","main","pkgManager","cwd","recurse","output","file","quiet","packageGraph","Error","validate","packages","sort","console","log","JSON","stringify","join","writeESMModuleOutput","description","then","exit","catch","err","error"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,SAASA,OAAO,EAAEC,MAAM,QAAQ,YAAY;AAC5C,SAA0BC,cAAc,QAAQ,gBAAgB;AAChE,SAASC,uBAAuB,QAAsB,mBAAmB;AACzE,SAASC,aAAa,QAAQ,KAAK;AAEnCJ,QACEK,SAAS,CACT,IAAIJ,OACH,iCACA,oFAECK,OAAO,CAAC;IAAC;CAAU,EACnBC,mBAAmB,IAErBF,SAAS,CACT,IAAIJ,OAAO,yBAAyB,kCAClCK,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,UAAUV,QAAQW,KAAK,CAACC,QAAQC,IAAI,EAAEC,IAAI;SAWjCC,KAAKL,OAAgB;WAArBK;;SAAAA;IAAAA,QAAf,oBAAA,UAAoBL,OAAgB;QACnC,MAAM,EACLM,UAAU,EACVC,MAAML,QAAQK,GAAG,EAAE,EACnBC,OAAO,EACPC,MAAM,EACNC,IAAI,EACJC,KAAK,EACL,GAAGX;QACJ,IAAIY;QACJ,OAAQN;YACP,KAAK;gBACJM,eAAe,MAAMnB,wBAAwBc,KAAKC;gBAClD;YACD;gBACC,MAAM,IAAIK,MACT;QAEH;QACAD,aAAaE,QAAQ;QAErB,MAAMC,WAAW,AAAC,CAAA,MAAMvB,eAAeoB,aAAY,EAAGI,IAAI;QAE1D,IAAI,CAACL,OAAO;YACX,OAAQF;gBACP,KAAK;oBACJQ,QAAQC,GAAG,CAACC,KAAKC,SAAS,CAACL;oBAC3B;gBACD,KAAK;oBACJE,QAAQC,GAAG,CAACH,SAASM,IAAI,CAAC;YAC5B;QACD;QAEA,IAAIX,MAAM;YACTY,qBAAqBP,UAAUL;QAChC;IACD;WApCeL;;AAsCf,OAAO,SAASiB,qBAAqBP,QAAkB,EAAEL,IAAY;IACpEhB,cACCgB,MACAS,KAAKC,SAAS,CACb;QACCG,aAAa,CAAC,4CAA4C,EAAErB,QAAQC,IAAI,CAACkB,IAAI,CAAC,MAAM;QACpFN,UAAUA;IACX,GACA,MACA;AAGH;AAEA,KAAKV,KAAKL,SACRwB,IAAI,CAAC;IACLtB,QAAQuB,IAAI;AACb,GACCC,KAAK,CAAC,CAACC;IACPV,QAAQW,KAAK,CAACD;IACdzB,QAAQuB,IAAI,CAAC;AACd"}
@@ -0,0 +1,4 @@
1
+ export * from "./operations";
2
+ export * from "./packageGraphs";
3
+
4
+ //# sourceMappingURL=index.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/index.ts"],"sourcesContent":["export * from \"./operations\";\nexport * from \"./packageGraphs\";\n"],"names":[],"mappings":"AAAA,cAAc,eAAe;AAC7B,cAAc,kBAAkB"}
@@ -0,0 +1,118 @@
1
+ function asyncGeneratorStep(gen, resolve, reject, _next, _throw, key, arg) {
2
+ try {
3
+ var info = gen[key](arg);
4
+ var value = info.value;
5
+ } catch (error) {
6
+ reject(error);
7
+ return;
8
+ }
9
+ if (info.done) {
10
+ resolve(value);
11
+ } else {
12
+ Promise.resolve(value).then(_next, _throw);
13
+ }
14
+ }
15
+ function _async_to_generator(fn) {
16
+ return function() {
17
+ var self = this, args = arguments;
18
+ return new Promise(function(resolve, reject) {
19
+ var gen = fn.apply(self, args);
20
+ function _next(value) {
21
+ asyncGeneratorStep(gen, resolve, reject, _next, _throw, "next", value);
22
+ }
23
+ function _throw(err) {
24
+ asyncGeneratorStep(gen, resolve, reject, _next, _throw, "throw", err);
25
+ }
26
+ _next(undefined);
27
+ });
28
+ };
29
+ }
30
+ import { readFile } from "fs/promises";
31
+ import resolvePackagePath from "resolve-package-path";
32
+ import { join } from "path";
33
+ function resolvePkgPath(pkgDir, pkgName, options) {
34
+ const { optionalDepsFromParent, isPatch, isRoot } = options;
35
+ const path = resolvePackagePath(pkgName, pkgDir);
36
+ if (!path && !(optionalDepsFromParent === null || optionalDepsFromParent === void 0 ? void 0 : optionalDepsFromParent[pkgName]) && !isPatch) {
37
+ if (isRoot) {
38
+ // Accounts for an unresolvable root project since we're in it
39
+ return join(pkgDir, "package.json");
40
+ }
41
+ throw new Error(`Non-optional dependency could not be found: ${pkgName} when looking from ${pkgDir}`);
42
+ }
43
+ return path;
44
+ }
45
+ /**
46
+ * Returns the esm packages from a PackageGraph - Assumes we can read package.json (may not work with yarn plug'n'play)
47
+ * @param pkgGraph
48
+ * @returns
49
+ */ export function getESMPackages(pkgGraph) {
50
+ return _getESMPackages.apply(this, arguments);
51
+ }
52
+ function _getESMPackages() {
53
+ _getESMPackages = _async_to_generator(function*(pkgGraph) {
54
+ const packagePathsMap = {};
55
+ function resolvePackageJsons(currentNode, previousOptions) {
56
+ return _resolvePackageJsons.apply(this, arguments);
57
+ }
58
+ function _resolvePackageJsons() {
59
+ _resolvePackageJsons = // We need to resolve the packageJsons and are fine with optional dependencies missing since we can't tell if we need them
60
+ _async_to_generator(function*(currentNode, previousOptions) {
61
+ var _previousOptions_parentPkgPath;
62
+ // Look up the package.json
63
+ const jsonPath = resolvePkgPath((_previousOptions_parentPkgPath = previousOptions === null || previousOptions === void 0 ? void 0 : previousOptions.parentPkgPath) !== null && _previousOptions_parentPkgPath !== void 0 ? _previousOptions_parentPkgPath : pkgGraph.pkgDir, currentNode.value.name, {
64
+ optionalDepsFromParent: previousOptions === null || previousOptions === void 0 ? void 0 : previousOptions.optionalDependencies,
65
+ isPatch: currentNode.value.isPatch,
66
+ isRoot: currentNode.value.isRoot
67
+ });
68
+ // If we didn't throw any resolution errors, then we can assume this was optional - we shouldn't resolve down that path
69
+ if (!jsonPath) {
70
+ return [
71
+ {},
72
+ true
73
+ ];
74
+ }
75
+ let pkgInfos = packagePathsMap[currentNode.value.name];
76
+ if (pkgInfos) {
77
+ if (pkgInfos.some((info)=>info.packageJsonPath === jsonPath)) {
78
+ return [
79
+ {},
80
+ false
81
+ ];
82
+ }
83
+ } else {
84
+ pkgInfos = [];
85
+ packagePathsMap[currentNode.value.name] = pkgInfos;
86
+ }
87
+ const contents = yield readFile(jsonPath);
88
+ const json = JSON.parse(contents.toString());
89
+ pkgInfos.push({
90
+ packageJsonPath: jsonPath,
91
+ isModule: json.type === "module"
92
+ });
93
+ return [
94
+ {
95
+ optionalDependencies: json.optionalDependencies,
96
+ parentPkgPath: jsonPath
97
+ },
98
+ false
99
+ ];
100
+ });
101
+ return _resolvePackageJsons.apply(this, arguments);
102
+ }
103
+ // Iterate the packages and resolve all non-optional packages and existing optionals
104
+ yield pkgGraph.topDownVisitAsync(resolvePackageJsons);
105
+ return Array.from(Object.keys(packagePathsMap).reduce((mods, p)=>{
106
+ const infos = packagePathsMap[p];
107
+ infos.forEach((info)=>{
108
+ if (info.isModule) {
109
+ mods.add(p);
110
+ }
111
+ });
112
+ return mods;
113
+ }, new Set()));
114
+ });
115
+ return _getESMPackages.apply(this, arguments);
116
+ }
117
+
118
+ //# sourceMappingURL=getESMPackages.mjs.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":["readFile","resolvePackagePath","join","resolvePkgPath","pkgDir","pkgName","options","optionalDepsFromParent","isPatch","isRoot","path","Error","getESMPackages","pkgGraph","packagePathsMap","resolvePackageJsons","currentNode","previousOptions","jsonPath","parentPkgPath","value","name","optionalDependencies","pkgInfos","some","info","packageJsonPath","contents","json","JSON","parse","toString","push","isModule","type","topDownVisitAsync","Array","from","Object","keys","reduce","mods","p","infos","forEach","add","Set"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,SAASA,QAAQ,QAAQ,cAAc;AACvC,OAAOC,wBAAwB,uBAAuB;AAOtD,SAASC,IAAI,QAAQ,OAAO;AAE5B,SAASC,eACRC,MAAc,EACdC,OAAe,EACfC,OAOC;IAED,MAAM,EAAEC,sBAAsB,EAAEC,OAAO,EAAEC,MAAM,EAAE,GAAGH;IACpD,MAAMI,OAAOT,mBAAmBI,SAASD;IACzC,IAAI,CAACM,QAAQ,EAACH,mCAAAA,6CAAAA,sBAAwB,CAACF,QAAQ,KAAI,CAACG,SAAS;QAC5D,IAAIC,QAAQ;YACX,8DAA8D;YAC9D,OAAOP,KAAKE,QAAQ;QACrB;QACA,MAAM,IAAIO,MACT,CAAC,4CAA4C,EAAEN,QAAQ,mBAAmB,EAAED,QAAQ;IAEtF;IACA,OAAOM;AACR;AAsBA;;;;CAIC,GACD,gBAAsBE,eAAeC,QAAsB;WAArCD;;SAAAA;IAAAA,kBAAf,oBAAA,UAA8BC,QAAsB;QAC1D,MAAMC,kBAGF,CAAC;iBAEUC,oBACdC,WAA8C,EAC9CC,eAA6B;mBAFfF;;iBAAAA;YAAAA,uBADf,0HAA0H;YAC1H,oBAAA,UACCC,WAA8C,EAC9CC,eAA6B;oBAI5BA;gBAFD,2BAA2B;gBAC3B,MAAMC,WAAWf,eAChBc,CAAAA,iCAAAA,4BAAAA,sCAAAA,gBAAiBE,aAAa,cAA9BF,4CAAAA,iCAAkCJ,SAAST,MAAM,EACjDY,YAAYI,KAAK,CAACC,IAAI,EACtB;oBACCd,sBAAsB,EAAEU,4BAAAA,sCAAAA,gBAAiBK,oBAAoB;oBAC7Dd,SAASQ,YAAYI,KAAK,CAACZ,OAAO;oBAClCC,QAAQO,YAAYI,KAAK,CAACX,MAAM;gBACjC;gBAED,uHAAuH;gBACvH,IAAI,CAACS,UAAU;oBACd,OAAO;wBAAC,CAAC;wBAAG;qBAAK;gBAClB;gBACA,IAAIK,WACHT,eAAe,CAACE,YAAYI,KAAK,CAACC,IAAI,CAAC;gBACxC,IAAIE,UAAU;oBACb,IAAIA,SAASC,IAAI,CAAC,CAACC,OAASA,KAAKC,eAAe,KAAKR,WAAW;wBAC/D,OAAO;4BAAC,CAAC;4BAAG;yBAAM;oBACnB;gBACD,OAAO;oBACNK,WAAW,EAAE;oBACbT,eAAe,CAACE,YAAYI,KAAK,CAACC,IAAI,CAAC,GAAGE;gBAC3C;gBAEA,MAAMI,WAAW,MAAM3B,SAASkB;gBAChC,MAAMU,OAAOC,KAAKC,KAAK,CAACH,SAASI,QAAQ;gBACzCR,SAASS,IAAI,CAAC;oBACbN,iBAAiBR;oBACjBe,UAAUL,KAAKM,IAAI,KAAK;gBACzB;gBACA,OAAO;oBACN;wBACCZ,sBAAsBM,KAAKN,oBAAoB;wBAC/CH,eAAeD;oBAChB;oBACA;iBACA;YACF;mBA1CeH;;QA4Cf,oFAAoF;QACpF,MAAMF,SAASsB,iBAAiB,CAACpB;QAEjC,OAAOqB,MAAMC,IAAI,CAChBC,OAAOC,IAAI,CAACzB,iBAAiB0B,MAAM,CAAC,CAACC,MAAMC;YAC1C,MAAMC,QAAQ7B,eAAe,CAAC4B,EAAE;YAChCC,MAAMC,OAAO,CAAC,CAACnB;gBACd,IAAIA,KAAKQ,QAAQ,EAAE;oBAClBQ,KAAKI,GAAG,CAACH;gBACV;YACD;YACA,OAAOD;QACR,GAAG,IAAIK;IAET;WAhEsBlC"}
@@ -0,0 +1,4 @@
1
+ export * from "./getESMPackages";
2
+ export * from "./jest";
3
+
4
+ //# sourceMappingURL=index.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../src/operations/index.ts"],"sourcesContent":["export * from \"./getESMPackages\";\nexport * from \"./jest\";\n"],"names":[],"mappings":"AAAA,cAAc,mBAAmB;AACjC,cAAc,SAAS"}
@@ -0,0 +1,45 @@
1
+ import { readFileSync } from "fs";
2
+ /**
3
+ * You can use this function to get get a transformIgnore pattern for jest that excludes node_modules
4
+ * from a file where we have written all esm files that were detected.
5
+ *
6
+ * This is specifically designed for a "post-install" script that scans on install and overwrites the file
7
+ * if there are new esm module types - thereby reducing the cost of tests to just a file read instead of a
8
+ * tree scan.
9
+ *
10
+ * @param options
11
+ * @returns
12
+ */ export function getJestNodeModulesTransformIgnore(options) {
13
+ const { file, extraExceptions = [] } = options;
14
+ const modules = getModulesFromFile(file);
15
+ // Dedup
16
+ const modSet = new Set([
17
+ ...modules,
18
+ ...extraExceptions
19
+ ]);
20
+ return createNodeModulesTransformIgnore(Array.from(modSet));
21
+ }
22
+ function getModulesFromFile(file) {
23
+ try {
24
+ const esmModules = JSON.parse(readFileSync(file).toString());
25
+ if (!esmModules.packages || !Array.isArray(esmModules.packages)) {
26
+ throw new Error("Esm packages file object is missing the expected packages field!");
27
+ }
28
+ return esmModules.packages;
29
+ } catch (err) {
30
+ console.error(`Malformed esm modules file: ${file}`);
31
+ throw err;
32
+ }
33
+ }
34
+ /**
35
+ * Given a set of package names, this constructs a node_modules ignore string that exempts the
36
+ * targeted modules from jest transform.
37
+ *
38
+ * It should be used with the transformIgnore configuration.
39
+ * @param packageExceptions
40
+ * @returns
41
+ */ export function createNodeModulesTransformIgnore(packageExceptions) {
42
+ return `node_modules/(?!${packageExceptions.map((p)=>`${p}/`).join("|")})`;
43
+ }
44
+
45
+ //# sourceMappingURL=jest.mjs.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":["readFileSync","getJestNodeModulesTransformIgnore","options","file","extraExceptions","modules","getModulesFromFile","modSet","Set","createNodeModulesTransformIgnore","Array","from","esmModules","JSON","parse","toString","packages","isArray","Error","err","console","error","packageExceptions","map","p","join"],"mappings":"AAAA,SAASA,YAAY,QAAQ,KAAK;AAUlC;;;;;;;;;;CAUC,GACD,OAAO,SAASC,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,OAAOK,iCAAiCC,MAAMC,IAAI,CAACJ;AACpD;AAEA,SAASD,mBAAmBH,IAAY;IACvC,IAAI;QACH,MAAMS,aAAaC,KAAKC,KAAK,CAC5Bd,aAAaG,MAAMY,QAAQ;QAE5B,IAAI,CAACH,WAAWI,QAAQ,IAAI,CAACN,MAAMO,OAAO,CAACL,WAAWI,QAAQ,GAAG;YAChE,MAAM,IAAIE,MACT;QAEF;QACA,OAAON,WAAWI,QAAQ;IAC3B,EAAE,OAAOG,KAAK;QACbC,QAAQC,KAAK,CAAC,CAAC,4BAA4B,EAAElB,MAAM;QACnD,MAAMgB;IACP;AACD;AAEA;;;;;;;CAOC,GACD,OAAO,SAASV,iCAAiCa,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,173 @@
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
+ */ function asyncGeneratorStep(gen, resolve, reject, _next, _throw, key, arg) {
6
+ try {
7
+ var info = gen[key](arg);
8
+ var value = info.value;
9
+ } catch (error) {
10
+ reject(error);
11
+ return;
12
+ }
13
+ if (info.done) {
14
+ resolve(value);
15
+ } else {
16
+ Promise.resolve(value).then(_next, _throw);
17
+ }
18
+ }
19
+ function _async_to_generator(fn) {
20
+ return function() {
21
+ var self = this, args = arguments;
22
+ return new Promise(function(resolve, reject) {
23
+ var gen = fn.apply(self, args);
24
+ function _next(value) {
25
+ asyncGeneratorStep(gen, resolve, reject, _next, _throw, "next", value);
26
+ }
27
+ function _throw(err) {
28
+ asyncGeneratorStep(gen, resolve, reject, _next, _throw, "throw", err);
29
+ }
30
+ _next(undefined);
31
+ });
32
+ };
33
+ }
34
+ function _define_property(obj, key, value) {
35
+ if (key in obj) {
36
+ Object.defineProperty(obj, key, {
37
+ value: value,
38
+ enumerable: true,
39
+ configurable: true,
40
+ writable: true
41
+ });
42
+ } else {
43
+ obj[key] = value;
44
+ }
45
+ return obj;
46
+ }
47
+ function _object_spread(target) {
48
+ for(var i = 1; i < arguments.length; i++){
49
+ var source = arguments[i] != null ? arguments[i] : {};
50
+ var ownKeys = Object.keys(source);
51
+ if (typeof Object.getOwnPropertySymbols === "function") {
52
+ ownKeys = ownKeys.concat(Object.getOwnPropertySymbols(source).filter(function(sym) {
53
+ return Object.getOwnPropertyDescriptor(source, sym).enumerable;
54
+ }));
55
+ }
56
+ ownKeys.forEach(function(key) {
57
+ _define_property(target, key, source[key]);
58
+ });
59
+ }
60
+ return target;
61
+ }
62
+ /**
63
+ * Mnimal "graph" class that takes in a bunch of nodes and then allows you to visit them in a particular order.
64
+ *
65
+ * The value of the node <T> is used as the unique node key for referencing other nodes.
66
+ */ export class Graph {
67
+ getNodeKeyStr(nodeKey) {
68
+ return this.keySerializer ? this.keySerializer(nodeKey) : nodeKey;
69
+ }
70
+ addDownstreamNode(node) {
71
+ const nodeKeyStr = this.getNodeKeyStr(node.self);
72
+ // If a previous node prestubbed in the next node, we add it here
73
+ if (this.map.has(nodeKeyStr)) {
74
+ const preStubbedNode = this.map.get(nodeKeyStr);
75
+ if (preStubbedNode.value !== undefined) {
76
+ throw new Error(`Already added a downstream node of same key: ${nodeKeyStr} - Can't add ${JSON.stringify(node)}`);
77
+ }
78
+ preStubbedNode.to.push(...node.to);
79
+ preStubbedNode.value = node.value;
80
+ } else {
81
+ this.map.set(nodeKeyStr, _object_spread({
82
+ from: []
83
+ }, node));
84
+ this.noFrom.add(nodeKeyStr);
85
+ }
86
+ // Add to or pre-stub some nodes
87
+ node.to.forEach((n)=>{
88
+ const nkStr = this.getNodeKeyStr(n);
89
+ if (this.map.has(nkStr)) {
90
+ const existingNode = this.map.get(nkStr);
91
+ existingNode.from.push(node.self);
92
+ if (existingNode.from.length === 1) {
93
+ // We were wrong about this package
94
+ this.noFrom.delete(nkStr);
95
+ }
96
+ } else {
97
+ this.map.set(nkStr, {
98
+ self: n,
99
+ from: [
100
+ node.self
101
+ ],
102
+ to: [],
103
+ value: undefined
104
+ });
105
+ }
106
+ });
107
+ }
108
+ validate() {
109
+ const errors = [];
110
+ for (let [k, node] of this.map.entries()){
111
+ if (!node.value) {
112
+ errors.push(`Unregistered node: ${k}! Node was pointed to by: ${JSON.stringify(node.from)}`);
113
+ }
114
+ }
115
+ if (errors.length > 0) {
116
+ throw new Error(errors.join("\n"));
117
+ }
118
+ }
119
+ /**
120
+ *
121
+ * @param visit
122
+ * @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
123
+ * This will depend on your visit function, since the visit function can pass parent -> child info that may change based on the node
124
+ * it is coming from
125
+ */ topDownVisitAsync(visit, firstArrivalOnly) {
126
+ var _this = this;
127
+ return _async_to_generator(function*() {
128
+ const guestBook = firstArrivalOnly ? new Set() : undefined;
129
+ for (const noFrom of _this.noFrom){
130
+ const node = _this.map.get(noFrom);
131
+ yield _this.visitDownNodeAsync(node, visit, guestBook);
132
+ }
133
+ })();
134
+ }
135
+ /**
136
+ *
137
+ * @param nodeKey - the key that we used to retrieve this node
138
+ * @param node - the node itself
139
+ * @param visit - the visit function
140
+ * @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
141
+ * regardless of the node that we come from
142
+ * @param prevResult - the result of the last node that got here
143
+ * @returns
144
+ */ visitDownNodeAsync(node, visit, guestBook, prevResult) {
145
+ var _this = this;
146
+ return _async_to_generator(function*() {
147
+ if (guestBook === null || guestBook === void 0 ? void 0 : guestBook.has(_this.getNodeKeyStr(node.self))) {
148
+ // We already visited this node
149
+ return;
150
+ }
151
+ const [result, stop] = yield visit(node, prevResult);
152
+ if (stop) {
153
+ // We let the visitor control travel
154
+ return;
155
+ }
156
+ yield Promise.all(node.to.map((n)=>{
157
+ return _this.visitDownNodeAsync(_this.map.get(_this.getNodeKeyStr(n)), visit, guestBook, result);
158
+ }));
159
+ })();
160
+ }
161
+ /**
162
+ *
163
+ * @param keySerializer - if the graph has a compound key, then you must supply a function that converts a compound key to a string
164
+ */ constructor(keySerializer){
165
+ // This map is partially filled so we allow undefined values internally
166
+ _define_property(this, "map", new Map());
167
+ _define_property(this, "noFrom", new Set());
168
+ _define_property(this, "keySerializer", void 0);
169
+ this.keySerializer = keySerializer;
170
+ }
171
+ }
172
+
173
+ //# sourceMappingURL=Graph.mjs.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,28 @@
1
+ function _define_property(obj, key, value) {
2
+ if (key in obj) {
3
+ Object.defineProperty(obj, key, {
4
+ value: value,
5
+ enumerable: true,
6
+ configurable: true,
7
+ writable: true
8
+ });
9
+ } else {
10
+ obj[key] = value;
11
+ }
12
+ return obj;
13
+ }
14
+ import { resolve } from "path";
15
+ import { Graph } from "./Graph";
16
+ /**
17
+ * A graph of package names and their dependencies
18
+ */ export class PackageGraph extends Graph {
19
+ constructor(pkgDir){
20
+ super((node)=>`${node.name}@${node.version}`), _define_property(this, "pkgDir", void 0);
21
+ if (!pkgDir) {
22
+ throw new Error("Must supply a pkgDir!");
23
+ }
24
+ this.pkgDir = resolve(pkgDir);
25
+ }
26
+ }
27
+
28
+ //# sourceMappingURL=PackageGraph.mjs.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":["resolve","Graph","PackageGraph","constructor","pkgDir","node","name","version","Error"],"mappings":";;;;;;;;;;;;;AAAA,SAASA,OAAO,QAAQ,OAAO;AAC/B,SAASC,KAAK,QAAQ,UAAU;AAgBhC;;CAEC,GACD,OAAO,MAAMC,qBAAqBD;IAEjCE,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,GAAGJ,QAAQI;IACvB;AACD"}