syncpack 8.0.0 → 8.2.4

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.
package/README.md CHANGED
@@ -16,7 +16,10 @@ npm install --global syncpack
16
16
 
17
17
  ## 🤖 GitHub Action
18
18
 
19
- As of May 2022 there is now a [Syncpack GitHub Action](https://github.com/marketplace/actions/syncpack-synchronise-monorepo-dependency-versions). It is new and less stable than syncpack itself, but please give it a try and [give your feedback](https://github.com/JamieMason/syncpack-github-action/issues/new).
19
+ As of May 2022 there is now a
20
+ [Syncpack GitHub Action](https://github.com/marketplace/actions/syncpack-synchronise-monorepo-dependency-versions).
21
+ It is new and less stable than syncpack itself, but please give it a try and
22
+ [give your feedback](https://github.com/JamieMason/syncpack-github-action/issues/new).
20
23
 
21
24
  ## 📝 Commands
22
25
 
@@ -457,6 +460,49 @@ to apply to an entire package:
457
460
 
458
461
  See [`semverGroups`](#semverGroups) for more examples, they work the same way.
459
462
 
463
+ #### `versionGroup.dependencies`
464
+
465
+ Required. An array of minimatch glob patterns which should match the key of
466
+ dependencies defined in your package.json files.
467
+
468
+ | Pattern | Matches |
469
+ | ------------------------ | ---------------------------------------- |
470
+ | `["**"]` | Any dependency |
471
+ | `["@aws-sdk/**"]` | Any dependency with the scope `@aws-sdk` |
472
+ | `["react", "react-dom"]` | Specific dependencies by name |
473
+
474
+ #### `versionGroup.packages`
475
+
476
+ Required. An array of minimatch glob patterns which should match the `name`
477
+ property of packages developed within your monorepo.
478
+
479
+ | Pattern | Matches |
480
+ | ---------------------------- | ------------------------------------- |
481
+ | `["**"]` | Any package |
482
+ | `["@my-repo/**"]` | Any package with the scope `@my-repo` |
483
+ | `["my-server", "my-client"]` | Specific packages by name |
484
+
485
+ #### `versionGroup.dependencyTypes`
486
+
487
+ Optional. If set, will result in only the dependency types included in that
488
+ array being considered a match for this version group.
489
+
490
+ In this example we define that all dependencies within `peerDependencies` in the
491
+ repo must match, regardless of what versions of the same dependencies might be
492
+ used in `dependencies` or `devDependencies`.
493
+
494
+ ```json
495
+ {
496
+ "versionGroups": [
497
+ {
498
+ "dependencies": ["**"],
499
+ "dependencyTypes": ["peer"],
500
+ "packages": ["**"]
501
+ }
502
+ ]
503
+ }
504
+ ```
505
+
460
506
  #### `versionGroup.isBanned`
461
507
 
462
508
  Remove dependencies which you've decided should never be allowed.
@@ -465,8 +511,8 @@ Remove dependencies which you've decided should never be allowed.
465
511
  {
466
512
  "versionGroups": [
467
513
  {
468
- "isBanned": true,
469
514
  "dependencies": ["never-gonna"],
515
+ "isBanned": true,
470
516
  "packages": ["**"]
471
517
  }
472
518
  ]
@@ -482,9 +528,9 @@ you've defined.
482
528
  {
483
529
  "versionGroups": [
484
530
  {
485
- "pinVersion": "3.55.0",
486
531
  "dependencies": ["@aws-sdk/**"],
487
- "packages": ["**"]
532
+ "packages": ["**"],
533
+ "pinVersion": "3.55.0"
488
534
  }
489
535
  ]
490
536
  }
@@ -544,6 +590,56 @@ semver range of `~`, regardless of what the rest of the monorepo uses:
544
590
  }
545
591
  ```
546
592
 
593
+ 3: Production dependencies should have fixed version numbers, but development
594
+ and peer dependencies can be broader.
595
+
596
+ ```json
597
+ {
598
+ "semverGroups": [
599
+ {
600
+ "range": "",
601
+ "dependencyTypes": [
602
+ "prod",
603
+ "resolutions",
604
+ "overrides",
605
+ "pnpmOverrides",
606
+ "workspace"
607
+ ],
608
+ "dependencies": ["**"],
609
+ "packages": ["**"]
610
+ },
611
+ {
612
+ "range": "~",
613
+ "dependencyTypes": ["dev"],
614
+ "dependencies": ["**"],
615
+ "packages": ["**"]
616
+ },
617
+ {
618
+ "range": "^",
619
+ "dependencyTypes": ["peer"],
620
+ "dependencies": ["**"],
621
+ "packages": ["**"]
622
+ }
623
+ ]
624
+ }
625
+ ```
626
+
627
+ #### `semverGroup.range`
628
+
629
+ Which of the [Supported Ranges](#supported-ranges) this group should use.
630
+
631
+ #### `semverGroup.dependencies`
632
+
633
+ Works the same as [`semverGroup.dependencies`](#semvergroupdependencies).
634
+
635
+ #### `semverGroup.packages`
636
+
637
+ Works the same as [`semverGroup.packages`](#semvergrouppackages).
638
+
639
+ #### `semverGroup.dependencyTypes`
640
+
641
+ Works the same as [`semverGroup.dependencyTypes`](#semvergroupdependencytypes).
642
+
547
643
  ## 🕵🏾‍♀️ Resolving Packages
548
644
 
549
645
  package.json files are resolved in this order of precendence:
@@ -9,6 +9,8 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
9
9
  exports.__esModule = true;
10
10
  exports.list = void 0;
11
11
  var chalk_1 = __importDefault(require("chalk"));
12
+ var get_expected_version_1 = require("../bin-fix-mismatches/get-expected-version");
13
+ var constants_1 = require("../constants");
12
14
  var list_version_groups_1 = require("./list-version-groups");
13
15
  function list(input, disk) {
14
16
  var isInvalid = false;
@@ -25,10 +27,17 @@ function list(input, disk) {
25
27
  }
26
28
  groups.forEach(function (_a) {
27
29
  var hasMismatches = _a.hasMismatches, isBanned = _a.isBanned, name = _a.name, uniques = _a.uniques;
28
- var versionList = uniques.sort().join(', ');
30
+ var versionList = uniques.sort();
31
+ var expected = (0, get_expected_version_1.getExpectedVersion)(name, versionGroup, input);
29
32
  console.log(isBanned
30
- ? (0, chalk_1["default"])(templateObject_2 || (templateObject_2 = __makeTemplateObject(["{red \u2715 ", "} {dim.red remove this dependency}"], ["{red \u2715 ", "} {dim.red remove this dependency}"])), name) : hasMismatches
31
- ? (0, chalk_1["default"])(templateObject_3 || (templateObject_3 = __makeTemplateObject(["{red \u2715 ", "} {dim.red ", "}"], ["{red \u2715 ", "} {dim.red ", "}"])), name, versionList) : (0, chalk_1["default"])(templateObject_4 || (templateObject_4 = __makeTemplateObject(["{dim -} {white ", "} {dim ", "}"], ["{dim -} {white ", "} {dim ", "}"])), name, versionList));
33
+ ? (0, chalk_1["default"])(templateObject_2 || (templateObject_2 = __makeTemplateObject(["{red ", " ", "} {dim.red is defined in this version group as banned from use}"], ["{red ", " ", "} {dim.red is defined in this version group as banned from use}"])), constants_1.ICON.cross, name) : hasMismatches
34
+ ? (0, chalk_1["default"])(templateObject_3 || (templateObject_3 = __makeTemplateObject(["{red ", " ", "} ", ""], ["{red ", " ", "} ", ""])), constants_1.ICON.cross, name, versionList
35
+ .map(function (version) {
36
+ return version === expected
37
+ ? chalk_1["default"].green(version)
38
+ : chalk_1["default"].red(version);
39
+ })
40
+ .join(chalk_1["default"].dim(', '))) : (0, chalk_1["default"])(templateObject_4 || (templateObject_4 = __makeTemplateObject(["{dim -} {white ", "} {dim ", "}"], ["{dim -} {white ", "} {dim ", "}"])), name, versionList));
32
41
  });
33
42
  if (groups.some(function (_a) {
34
43
  var hasMismatches = _a.hasMismatches;
@@ -3,6 +3,17 @@ var __makeTemplateObject = (this && this.__makeTemplateObject) || function (cook
3
3
  if (Object.defineProperty) { Object.defineProperty(cooked, "raw", { value: raw }); } else { cooked.raw = raw; }
4
4
  return cooked;
5
5
  };
6
+ var __values = (this && this.__values) || function(o) {
7
+ var s = typeof Symbol === "function" && Symbol.iterator, m = s && o[s], i = 0;
8
+ if (m) return m.call(o);
9
+ if (o && typeof o.length === "number") return {
10
+ next: function () {
11
+ if (o && i >= o.length) o = void 0;
12
+ return { value: o && o[i++], done: !o };
13
+ }
14
+ };
15
+ throw new TypeError(s ? "Object is not iterable." : "Symbol.iterator is not defined.");
16
+ };
6
17
  var __importDefault = (this && this.__importDefault) || function (mod) {
7
18
  return (mod && mod.__esModule) ? mod : { "default": mod };
8
19
  };
@@ -33,18 +44,50 @@ function listMismatches(input, disk) {
33
44
  }
34
45
  }
35
46
  groups.forEach(function (_a) {
47
+ var e_1, _b;
36
48
  var instances = _a.instances, isBanned = _a.isBanned, name = _a.name;
37
- var expectedVersion = (0, get_expected_version_1.getExpectedVersion)(name, versionGroup, input);
38
- console.log(isBanned
39
- ? (0, chalk_1["default"])(templateObject_2 || (templateObject_2 = __makeTemplateObject(["{red \u2715 ", "} {dim.red remove this dependency}"], ["{red \u2715 ", "} {dim.red remove this dependency}"])), name) : (0, chalk_1["default"])(templateObject_3 || (templateObject_3 = __makeTemplateObject(["{dim -} ", " {green.dim ", "}"], ["{dim -} ", " {green.dim ", "}"])), name, expectedVersion));
49
+ var workspaceMatch = null;
50
+ var expected = (0, get_expected_version_1.getExpectedVersion)(name, versionGroup, input);
51
+ try {
52
+ for (var instances_1 = __values(instances), instances_1_1 = instances_1.next(); !instances_1_1.done; instances_1_1 = instances_1.next()) {
53
+ var instance = instances_1_1.value;
54
+ var isMatch = instance.version === expected;
55
+ var isWorkspace = instance.dependencyType === 'workspace';
56
+ if (isMatch && isWorkspace) {
57
+ workspaceMatch = instance;
58
+ }
59
+ }
60
+ }
61
+ catch (e_1_1) { e_1 = { error: e_1_1 }; }
62
+ finally {
63
+ try {
64
+ if (instances_1_1 && !instances_1_1.done && (_b = instances_1["return"])) _b.call(instances_1);
65
+ }
66
+ finally { if (e_1) throw e_1.error; }
67
+ }
68
+ if (isBanned) {
69
+ console.log((0, chalk_1["default"])(templateObject_2 || (templateObject_2 = __makeTemplateObject(["{red ", " ", "} {dim.red is defined in this version group as banned from use}"], ["{red ", " ", "} {dim.red is defined in this version group as banned from use}"])), constants_1.ICON.cross, name));
70
+ }
71
+ else if (workspaceMatch) {
72
+ var shortPath = (0, path_1.relative)(constants_1.CWD, workspaceMatch.wrapper.filePath);
73
+ var reason = (0, chalk_1["default"])(templateObject_3 || (templateObject_3 = __makeTemplateObject(["{dim : ", " is developed in this repo at ", "}"], ["{dim : ", " is developed in this repo at ", "}"])), expected, shortPath);
74
+ console.log((0, chalk_1["default"])(templateObject_4 || (templateObject_4 = __makeTemplateObject(["{dim -} ", "", ""], ["{dim -} ", "", ""])), name, reason));
75
+ }
76
+ else {
77
+ var reason = (0, chalk_1["default"])(templateObject_5 || (templateObject_5 = __makeTemplateObject(["{dim : ", " is the highest valid semver version in use}"], ["{dim : ", " is the highest valid semver version in use}"])), expected);
78
+ console.log((0, chalk_1["default"])(templateObject_6 || (templateObject_6 = __makeTemplateObject(["{dim -} ", "", ""], ["{dim -} ", "", ""])), name, reason));
79
+ }
40
80
  instances.forEach(function (_a) {
41
81
  var dependencyType = _a.dependencyType, version = _a.version, wrapper = _a.wrapper;
42
- if (dependencyType === 'workspace') {
43
- var shortPath = (0, path_1.relative)(constants_1.CWD, wrapper.filePath);
44
- console.log((0, chalk_1["default"])(templateObject_4 || (templateObject_4 = __makeTemplateObject(["{red ", " {dim at ", "}}"], ["{red ", " {dim at ", "}}"])), version, shortPath));
82
+ var isMatch = version === expected;
83
+ var isLocal = dependencyType === 'workspace';
84
+ var shortPath = (0, path_1.relative)(constants_1.CWD, wrapper.filePath);
85
+ var loc = isLocal ? 'version' : dependencyType;
86
+ if (isMatch) {
87
+ console.log((0, chalk_1["default"])(templateObject_7 || (templateObject_7 = __makeTemplateObject(["{green ", " in ", " of ", "}"], ["{green ", " in ", " of ", "}"])), version, loc, shortPath));
45
88
  }
46
89
  else {
47
- console.log((0, chalk_1["default"])(templateObject_5 || (templateObject_5 = __makeTemplateObject(["{red ", " {dim in ", " of ", "}}"], ["{red ", " {dim in ", " of ", "}}"])), version, dependencyType, wrapper.contents.name));
90
+ console.log((0, chalk_1["default"])(templateObject_8 || (templateObject_8 = __makeTemplateObject(["{red ", " in ", " of ", "}"], ["{red ", " in ", " of ", "}"])), version, loc, shortPath));
48
91
  }
49
92
  });
50
93
  });
@@ -54,4 +97,4 @@ function listMismatches(input, disk) {
54
97
  }
55
98
  }
56
99
  exports.listMismatches = listMismatches;
57
- var templateObject_1, templateObject_2, templateObject_3, templateObject_4, templateObject_5;
100
+ var templateObject_1, templateObject_2, templateObject_3, templateObject_4, templateObject_5, templateObject_6, templateObject_7, templateObject_8;
@@ -43,7 +43,7 @@ export interface VersionGroup {
43
43
  */
44
44
  dependencyTypes?: DependencyType[];
45
45
  }
46
- export declare type SyncpackConfig = Readonly<{
46
+ export interface SyncpackConfig {
47
47
  /**
48
48
  * which dependency properties to search within
49
49
  */
@@ -113,7 +113,7 @@ export declare type SyncpackConfig = Readonly<{
113
113
  * your workspace/monorepo as part of the search for versions to sync
114
114
  */
115
115
  workspace: boolean;
116
- }>;
116
+ }
117
117
  export declare const ALL_PATTERNS: string[];
118
118
  export declare const DEPENDENCY_TYPES: DependencyType[];
119
119
  export declare const CWD: string;
@@ -130,4 +130,10 @@ export declare const RANGE_LTE = "<=";
130
130
  export declare const RANGE_MINOR = "^";
131
131
  export declare const RANGE_PATCH = "~";
132
132
  export declare const SEMVER_ORDER: ValidRange[];
133
+ export declare const ICON: {
134
+ cross: string;
135
+ debug: string;
136
+ skip: string;
137
+ tick: string;
138
+ };
133
139
  export declare const DEFAULT_CONFIG: SyncpackConfig;
package/dist/constants.js CHANGED
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  exports.__esModule = true;
3
- exports.DEFAULT_CONFIG = exports.SEMVER_ORDER = exports.RANGE_PATCH = exports.RANGE_MINOR = exports.RANGE_LTE = exports.RANGE_LT = exports.RANGE_LOOSE = exports.RANGE_GTE = exports.RANGE_GT = exports.RANGE_EXACT = exports.RANGE_ANY = exports.SAME = exports.LESSER = exports.GREATER = exports.CWD = exports.DEPENDENCY_TYPES = exports.ALL_PATTERNS = void 0;
3
+ exports.DEFAULT_CONFIG = exports.ICON = exports.SEMVER_ORDER = exports.RANGE_PATCH = exports.RANGE_MINOR = exports.RANGE_LTE = exports.RANGE_LT = exports.RANGE_LOOSE = exports.RANGE_GTE = exports.RANGE_GT = exports.RANGE_EXACT = exports.RANGE_ANY = exports.SAME = exports.LESSER = exports.GREATER = exports.CWD = exports.DEPENDENCY_TYPES = exports.ALL_PATTERNS = void 0;
4
4
  exports.ALL_PATTERNS = ['package.json', 'packages/*/package.json'];
5
5
  exports.DEPENDENCY_TYPES = [
6
6
  'dependencies',
@@ -34,6 +34,12 @@ exports.SEMVER_ORDER = [
34
34
  exports.RANGE_GT,
35
35
  exports.RANGE_ANY,
36
36
  ];
37
+ exports.ICON = {
38
+ cross: '✘',
39
+ debug: '?',
40
+ skip: '-',
41
+ tick: '✓'
42
+ };
37
43
  exports.DEFAULT_CONFIG = {
38
44
  dependencyTypes: [],
39
45
  dev: true,
@@ -5,7 +5,7 @@ export declare const disk: {
5
5
  readonly exit: (code: number) => void;
6
6
  };
7
7
  readonly globSync: (pattern: string) => string[];
8
- readonly readConfigFileSync: (configPath?: string | undefined) => Partial<SyncpackConfig>;
8
+ readonly readConfigFileSync: (configPath?: string) => Partial<SyncpackConfig>;
9
9
  readonly readFileSync: (filePath: string) => string;
10
10
  readonly readYamlFileSync: <T = unknown>(filePath: string) => T;
11
11
  readonly removeSync: (filePath: string) => void;
@@ -16,18 +16,15 @@ var getConfig = function (disk, program) {
16
16
  (0, log_1.verbose)('cli arguments:', program);
17
17
  var rcFile = disk.readConfigFileSync(program.configPath);
18
18
  var hasTypeOverride = (0, expect_more_1.isBoolean)(program.dev) ||
19
- (0, expect_more_1.isBoolean)(program.workspace) ||
20
19
  (0, expect_more_1.isBoolean)(program.overrides) ||
21
20
  (0, expect_more_1.isBoolean)(program.peer) ||
22
21
  (0, expect_more_1.isBoolean)(program.pnpmOverrides) ||
23
22
  (0, expect_more_1.isBoolean)(program.prod) ||
24
- (0, expect_more_1.isBoolean)(program.resolutions);
23
+ (0, expect_more_1.isBoolean)(program.resolutions) ||
24
+ (0, expect_more_1.isBoolean)(program.workspace);
25
25
  var dev = hasTypeOverride
26
26
  ? Boolean(program.dev)
27
27
  : getOption('dev', expect_more_1.isBoolean);
28
- var workspace = hasTypeOverride
29
- ? Boolean(program.workspace)
30
- : getOption('workspace', expect_more_1.isBoolean);
31
28
  var overrides = hasTypeOverride
32
29
  ? Boolean(program.overrides)
33
30
  : getOption('overrides', expect_more_1.isBoolean);
@@ -43,6 +40,9 @@ var getConfig = function (disk, program) {
43
40
  var resolutions = hasTypeOverride
44
41
  ? Boolean(program.resolutions)
45
42
  : getOption('resolutions', expect_more_1.isBoolean);
43
+ var workspace = hasTypeOverride
44
+ ? Boolean(program.workspace)
45
+ : getOption('workspace', expect_more_1.isBoolean);
46
46
  var dependencyTypes = dev ||
47
47
  overrides ||
48
48
  peer ||
@@ -51,12 +51,13 @@ var getConfig = function (disk, program) {
51
51
  resolutions ||
52
52
  workspace
53
53
  ? constants_1.DEPENDENCY_TYPES.filter(function (type) {
54
- return (type === 'dependencies' && prod) ||
55
- (type === 'devDependencies' && dev) ||
54
+ return (type === 'devDependencies' && dev) ||
56
55
  (type === 'overrides' && overrides) ||
57
56
  (type === 'peerDependencies' && peer) ||
58
57
  (type === 'pnpmOverrides' && pnpmOverrides) ||
59
- (type === 'resolutions' && resolutions);
58
+ (type === 'dependencies' && prod) ||
59
+ (type === 'resolutions' && resolutions) ||
60
+ (type === 'workspace' && workspace);
60
61
  })
61
62
  : constants_1.DEPENDENCY_TYPES;
62
63
  var filter = getOption('filter', expect_more_1.isNonEmptyString);
@@ -44,6 +44,7 @@ exports.__esModule = true;
44
44
  exports.getInstances = void 0;
45
45
  var expect_more_1 = require("expect-more");
46
46
  var minimatch_1 = __importDefault(require("minimatch"));
47
+ var log_1 = require("../log");
47
48
  function getInstances(options, wrappers) {
48
49
  var e_1, _a, e_2, _b, e_3, _c, e_4, _d;
49
50
  var _e, _f, _g, _h, _j;
@@ -62,7 +63,7 @@ function getInstances(options, wrappers) {
62
63
  if (dependencyType === 'workspace') {
63
64
  var name = (_e = wrapper.contents) === null || _e === void 0 ? void 0 : _e.name;
64
65
  var version = (_f = wrapper.contents) === null || _f === void 0 ? void 0 : _f.version;
65
- addInstance(wrapper, dependencyType, pkgName, name, version);
66
+ addInstance({ dependencyType: dependencyType, name: name, pkgName: pkgName, version: version, wrapper: wrapper });
66
67
  }
67
68
  else if (dependencyType === 'pnpmOverrides') {
68
69
  var versionsByName = (_h = (_g = wrapper.contents) === null || _g === void 0 ? void 0 : _g.pnpm) === null || _h === void 0 ? void 0 : _h.overrides;
@@ -72,7 +73,7 @@ function getInstances(options, wrappers) {
72
73
  try {
73
74
  for (var pkgs_1 = (e_3 = void 0, __values(pkgs)), pkgs_1_1 = pkgs_1.next(); !pkgs_1_1.done; pkgs_1_1 = pkgs_1.next()) {
74
75
  var _m = __read(pkgs_1_1.value, 2), name = _m[0], version = _m[1];
75
- addInstance(wrapper, dependencyType, pkgName, name, version);
76
+ addInstance({ dependencyType: dependencyType, name: name, pkgName: pkgName, version: version, wrapper: wrapper });
76
77
  }
77
78
  }
78
79
  catch (e_3_1) { e_3 = { error: e_3_1 }; }
@@ -91,7 +92,7 @@ function getInstances(options, wrappers) {
91
92
  try {
92
93
  for (var pkgs_2 = (e_4 = void 0, __values(pkgs)), pkgs_2_1 = pkgs_2.next(); !pkgs_2_1.done; pkgs_2_1 = pkgs_2.next()) {
93
94
  var _o = __read(pkgs_2_1.value, 2), name = _o[0], version = _o[1];
94
- addInstance(wrapper, dependencyType, pkgName, name, version);
95
+ addInstance({ dependencyType: dependencyType, name: name, pkgName: pkgName, version: version, wrapper: wrapper });
95
96
  }
96
97
  }
97
98
  catch (e_4_1) { e_4 = { error: e_4_1 }; }
@@ -121,14 +122,19 @@ function getInstances(options, wrappers) {
121
122
  finally { if (e_1) throw e_1.error; }
122
123
  }
123
124
  return allInstances;
124
- function addInstance(wrapper, dependencyType, pkgName, name, version) {
125
- if (!(0, expect_more_1.isNonEmptyString)(name))
126
- return;
127
- if (name.search(new RegExp(options.filter)) === -1)
128
- return;
129
- if (!(0, expect_more_1.isNonEmptyString)(version))
130
- return;
125
+ function addInstance(input) {
126
+ var dependencyType = input.dependencyType, name = input.name, pkgName = input.pkgName, version = input.version, wrapper = input.wrapper;
127
+ if (!(0, expect_more_1.isNonEmptyString)(name)) {
128
+ return (0, log_1.verbose)('skip instance, no name', input);
129
+ }
130
+ if (name.search(new RegExp(options.filter)) === -1) {
131
+ return (0, log_1.verbose)('skip instance, name does not match filter', input);
132
+ }
133
+ if (!(0, expect_more_1.isNonEmptyString)(version)) {
134
+ return (0, log_1.verbose)('skip instance, no version', input);
135
+ }
131
136
  var instance = { dependencyType: dependencyType, name: name, version: version, wrapper: wrapper };
137
+ (0, log_1.verbose)("add ".concat(name, "@").concat(version, " to ").concat(dependencyType, " ").concat(wrapper.filePath));
132
138
  allInstances.all.push(instance);
133
139
  groupInstancesBy('semverGroups', dependencyType, pkgName, instance);
134
140
  groupInstancesBy('versionGroups', dependencyType, pkgName, instance);
@@ -2,8 +2,6 @@ import * as E from 'fp-ts/lib/Either';
2
2
  import * as O from 'fp-ts/lib/Option';
3
3
  import type { SyncpackConfig } from '../../../constants';
4
4
  import type { Disk } from '../../../lib/disk';
5
- declare type MaybeFilePaths = O.Option<string[]>;
6
- declare type EitherMaybeFilePaths = E.Either<Error, MaybeFilePaths>;
7
5
  /**
8
6
  * Using --source options and/or config files on disk from npm/pnpm/yarn/lerna,
9
7
  * return an array of absolute paths to every package.json file the user is
@@ -11,5 +9,4 @@ declare type EitherMaybeFilePaths = E.Either<Error, MaybeFilePaths>;
11
9
  *
12
10
  * @returns Array of absolute file paths to package.json files
13
11
  */
14
- export declare function getFilePaths(disk: Disk, program: SyncpackConfig): EitherMaybeFilePaths;
15
- export {};
12
+ export declare function getFilePaths(disk: Disk, program: SyncpackConfig): E.Either<Error, O.Option<string[]>>;
@@ -25,9 +25,11 @@ var __importStar = (this && this.__importStar) || function (mod) {
25
25
  exports.__esModule = true;
26
26
  exports.getFilePaths = void 0;
27
27
  var expect_more_1 = require("expect-more");
28
+ var A = __importStar(require("fp-ts/lib/Array"));
28
29
  var E = __importStar(require("fp-ts/lib/Either"));
29
30
  var function_1 = require("fp-ts/lib/function");
30
31
  var O = __importStar(require("fp-ts/lib/Option"));
32
+ var S = __importStar(require("fp-ts/lib/string"));
31
33
  var get_patterns_1 = require("./get-patterns");
32
34
  var readonly_1 = require("./readonly");
33
35
  var tap_1 = require("./tap");
@@ -40,13 +42,9 @@ var try_catch_1 = require("./try-catch");
40
42
  * @returns Array of absolute file paths to package.json files
41
43
  */
42
44
  function getFilePaths(disk, program) {
43
- return (0, function_1.pipe)((0, get_patterns_1.getPatterns)(disk, program), E.traverseArray(resolvePattern), E.map((0, function_1.flow)(readonly_1.removeReadonlyType, mergeArrayOfOptionsIntoOne, O.filter(expect_more_1.isArrayOfStrings))));
45
+ return (0, function_1.pipe)(program, (0, get_patterns_1.getPatterns)(disk), O.getOrElse(function () { return []; }), E.traverseArray(resolvePattern), E.map(readonly_1.removeReadonlyType), E.map((0, function_1.flow)(A.flatten, A.uniq(S.Eq))), E.map(O.fromPredicate(expect_more_1.isArrayOfStrings)), E.map((0, tap_1.tapOption)('package.json files found')));
44
46
  function resolvePattern(pattern) {
45
- return (0, function_1.pipe)(E.tryCatch(function () { return disk.globSync(pattern); }, (0, try_catch_1.getErrorOrElse)("npm package \"glob\" threw on pattern \"".concat(pattern, "\""))), E.map((0, function_1.flow)(O.of, O.filter(expect_more_1.isArrayOfStrings), (0, tap_1.tapNone)("found 0 files matching pattern \"".concat(pattern, "\"")))));
46
- }
47
- function mergeArrayOfOptionsIntoOne(options) {
48
- var unwrap = O.getOrElse(function () { return []; });
49
- return O.of(options.reduce(function (values, option) { return values.concat(unwrap(option)); }, []));
47
+ return (0, function_1.pipe)(E.tryCatch(function () { return disk.globSync(pattern); }, (0, try_catch_1.getErrorOrElse)("npm package \"glob\" threw on pattern \"".concat(pattern, "\""))), E.map((0, function_1.flow)(O.fromPredicate(expect_more_1.isArrayOfStrings), (0, tap_1.tapOption)("files found matching pattern \"".concat(pattern, "\"")), O.getOrElse(function () { return []; }))));
50
48
  }
51
49
  }
52
50
  exports.getFilePaths = getFilePaths;
@@ -1,3 +1,3 @@
1
- import type { MaybePatterns } from '.';
1
+ import * as O from 'fp-ts/lib/Option';
2
2
  import type { Disk } from '../../../../lib/disk';
3
- export declare function getLernaPatterns(disk: Disk): () => MaybePatterns;
3
+ export declare function getLernaPatterns(disk: Disk): () => O.Option<string[]>;
@@ -1,3 +1,3 @@
1
- import type { MaybePatterns } from '.';
1
+ import * as O from 'fp-ts/lib/Option';
2
2
  import type { Disk } from '../../../../lib/disk';
3
- export declare function getPnpmPatterns(disk: Disk): () => MaybePatterns;
3
+ export declare function getPnpmPatterns(disk: Disk): () => O.Option<string[]>;
@@ -1,3 +1,3 @@
1
- import type { MaybePatterns } from '.';
1
+ import * as O from 'fp-ts/lib/Option';
2
2
  import type { Disk } from '../../../../lib/disk';
3
- export declare function getYarnPatterns(disk: Disk): () => MaybePatterns;
3
+ export declare function getYarnPatterns(disk: Disk): () => O.Option<string[]>;
@@ -1,13 +1,10 @@
1
1
  import * as O from 'fp-ts/lib/Option';
2
2
  import type { SyncpackConfig } from '../../../../constants';
3
3
  import type { Disk } from '../../../../lib/disk';
4
- declare type Patterns = string[];
5
- export declare type MaybePatterns = O.Option<Patterns>;
6
4
  /**
7
5
  * Find every glob pattern which should be used to find package.json files for
8
6
  * this monorepo.
9
7
  *
10
8
  * @returns `['./package.json', './packages/* /package.json']`
11
9
  */
12
- export declare function getPatterns(disk: Disk, program: SyncpackConfig): Patterns;
13
- export {};
10
+ export declare function getPatterns(disk: Disk): (program: SyncpackConfig) => O.Option<string[]>;
@@ -63,8 +63,10 @@ var get_yarn_patterns_1 = require("./get-yarn-patterns");
63
63
  *
64
64
  * @returns `['./package.json', './packages/* /package.json']`
65
65
  */
66
- function getPatterns(disk, program) {
67
- return (0, function_1.pipe)(O.of(program.source), O.filter(expect_more_1.isArrayOfStrings), (0, tap_1.tapNone)('no --source patterns found'), O.fold((0, function_1.flow)((0, get_yarn_patterns_1.getYarnPatterns)(disk), (0, tap_1.tapNone)('no yarn workspaces found'), O.fold((0, get_pnpm_patterns_1.getPnpmPatterns)(disk), O.of), (0, tap_1.tapNone)('no pnpm workspaces found'), O.fold((0, get_lerna_patterns_1.getLernaPatterns)(disk), O.of), (0, tap_1.tapNone)('no lerna packages found'), O.map((0, function_1.flow)(addRootDir, limitToPackageJson))), O.of), (0, tap_1.tapNone)('no patterns found, using defaults'), O.getOrElse(function () { return constants_1.ALL_PATTERNS; }));
66
+ function getPatterns(disk) {
67
+ return function (program) {
68
+ return (0, function_1.pipe)(O.of(program.source), O.filter(expect_more_1.isArrayOfStrings), (0, tap_1.tapOption)('--source patterns found'), O.fold((0, function_1.flow)((0, get_yarn_patterns_1.getYarnPatterns)(disk), O.map(addRootDir)), O.of), (0, tap_1.tapOption)('yarn workspaces found'), O.fold((0, function_1.flow)((0, get_pnpm_patterns_1.getPnpmPatterns)(disk), O.map(addRootDir)), O.of), (0, tap_1.tapOption)('pnpm workspaces found'), O.fold((0, function_1.flow)((0, get_lerna_patterns_1.getLernaPatterns)(disk), O.map(addRootDir)), O.of), (0, tap_1.tapOption)('lerna packages found'), O.map(limitToPackageJson), (0, tap_1.tapNone)('no patterns found, using defaults'), O.fold(function () { return O.some(constants_1.ALL_PATTERNS); }, O.of));
69
+ };
68
70
  function addRootDir(patterns) {
69
71
  return __spreadArray(['.'], __read(patterns), false);
70
72
  }
@@ -1,5 +1,15 @@
1
1
  import * as O from 'fp-ts/lib/Option';
2
+ declare type Fn<T> = (ma: O.Option<T>) => O.Option<T>;
2
3
  /**
3
4
  * Log a message when a pipeline contains `None` and let it continue unchanged.
4
5
  */
5
- export declare function tapNone<T>(message: string): (ma: O.Option<T>) => O.Option<T>;
6
+ export declare function tapNone<T>(message: string): Fn<T>;
7
+ /**
8
+ * Log a message when a pipeline contains `Some` and let it continue unchanged.
9
+ */
10
+ export declare function tapSome<T>(message: string): Fn<T>;
11
+ /**
12
+ * Log both possibilities of an `Option` and let it continue unchanged.
13
+ */
14
+ export declare function tapOption<T>(message: string): Fn<T>;
15
+ export {};
@@ -23,7 +23,8 @@ var __importStar = (this && this.__importStar) || function (mod) {
23
23
  return result;
24
24
  };
25
25
  exports.__esModule = true;
26
- exports.tapNone = void 0;
26
+ exports.tapOption = exports.tapSome = exports.tapNone = void 0;
27
+ var function_1 = require("fp-ts/lib/function");
27
28
  var O = __importStar(require("fp-ts/lib/Option"));
28
29
  var log_1 = require("../../log");
29
30
  /**
@@ -36,3 +37,20 @@ function tapNone(message) {
36
37
  }, O.of);
37
38
  }
38
39
  exports.tapNone = tapNone;
40
+ /**
41
+ * Log a message when a pipeline contains `Some` and let it continue unchanged.
42
+ */
43
+ function tapSome(message) {
44
+ return O.map(function logSomeValue(value) {
45
+ (0, log_1.verbose)(message, value);
46
+ return value;
47
+ });
48
+ }
49
+ exports.tapSome = tapSome;
50
+ /**
51
+ * Log both possibilities of an `Option` and let it continue unchanged.
52
+ */
53
+ function tapOption(message) {
54
+ return (0, function_1.flow)(tapSome(message), tapNone("no ".concat(message)));
55
+ }
56
+ exports.tapOption = tapOption;
package/dist/lib/log.d.ts CHANGED
@@ -1 +1 @@
1
- export declare function verbose(...values: any[]): void;
1
+ export declare function verbose(...values: unknown[]): void;
package/dist/lib/log.js CHANGED
@@ -32,13 +32,14 @@ exports.verbose = void 0;
32
32
  var chalk_1 = __importDefault(require("chalk"));
33
33
  var expect_more_1 = require("expect-more");
34
34
  var util_1 = require("util");
35
+ var constants_1 = require("../constants");
35
36
  function verbose() {
36
37
  var values = [];
37
38
  for (var _i = 0; _i < arguments.length; _i++) {
38
39
  values[_i] = arguments[_i];
39
40
  }
40
41
  if (process.env.SYNCPACK_VERBOSE) {
41
- console.info.apply(console, __spreadArray([chalk_1["default"].yellow('?')], __read(values.map(function (value) {
42
+ console.info.apply(console, __spreadArray([chalk_1["default"].yellow(constants_1.ICON.debug)], __read(values.map(function (value) {
42
43
  return (0, expect_more_1.isString)(value)
43
44
  ? chalk_1["default"].yellow(value)
44
45
  : (0, util_1.inspect)(value, false, null, true);
@@ -1,5 +1,5 @@
1
- import type { Source } from '../lib/get-input/get-wrappers';
2
- import type { Disk } from './disk';
1
+ import type { Disk } from '../disk';
2
+ import type { Source } from '../get-input/get-wrappers';
3
3
  interface FileData {
4
4
  contents: Source;
5
5
  filePath: string;
@@ -5,19 +5,21 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
5
5
  exports.__esModule = true;
6
6
  exports.writeIfChanged = void 0;
7
7
  var chalk_1 = __importDefault(require("chalk"));
8
- var os_1 = require("os");
9
8
  var path_1 = require("path");
10
- var constants_1 = require("../constants");
9
+ var constants_1 = require("../../constants");
10
+ var set_newlines_1 = require("./set-newlines");
11
11
  function writeIfChanged(disk, fileData) {
12
12
  var contents = fileData.contents, filePath = fileData.filePath, indent = fileData.indent, json = fileData.json;
13
+ var EOL = (0, set_newlines_1.detectNewlines)(json);
13
14
  var shortPath = (0, path_1.relative)(constants_1.CWD, filePath);
14
- var after = "".concat(JSON.stringify(contents, null, indent)).concat(os_1.EOL);
15
+ var source = "".concat(JSON.stringify(contents, null, indent)).concat(EOL);
16
+ var after = (0, set_newlines_1.setNewlines)(source, EOL);
15
17
  if (json !== after) {
16
18
  disk.writeFileSync(filePath, after);
17
- console.log(chalk_1["default"].green('✓'), shortPath);
19
+ console.log(chalk_1["default"].green(constants_1.ICON.tick), shortPath);
18
20
  }
19
21
  else {
20
- console.log(chalk_1["default"].dim('-'), chalk_1["default"].dim(shortPath));
22
+ console.log(chalk_1["default"].dim(constants_1.ICON.skip), chalk_1["default"].dim(shortPath));
21
23
  }
22
24
  }
23
25
  exports.writeIfChanged = writeIfChanged;
@@ -0,0 +1,4 @@
1
+ declare type Ending = '\n' | '\r' | '\r\n' | string;
2
+ export declare function setNewlines(source: string, lineEnding: Ending): string;
3
+ export declare function detectNewlines(source: string): Ending;
4
+ export {};
@@ -0,0 +1,24 @@
1
+ "use strict";
2
+ exports.__esModule = true;
3
+ exports.detectNewlines = exports.setNewlines = void 0;
4
+ var os_1 = require("os");
5
+ var LF = '\n';
6
+ var CR = '\r';
7
+ var CRLF = '\r\n';
8
+ function setNewlines(source, lineEnding) {
9
+ return source.replace(/\r\n|\n|\r/g, lineEnding);
10
+ }
11
+ exports.setNewlines = setNewlines;
12
+ function detectNewlines(source) {
13
+ var cr = source.split(CR).length;
14
+ var lf = source.split(LF).length;
15
+ var crlf = source.split(CRLF).length;
16
+ if (cr + lf === 0)
17
+ return os_1.EOL;
18
+ if (crlf === cr && crlf === lf)
19
+ return CRLF;
20
+ if (cr > lf)
21
+ return CR;
22
+ return LF;
23
+ }
24
+ exports.detectNewlines = detectNewlines;
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "syncpack",
3
3
  "description": "Manage multiple package.json files, such as in Lerna Monorepos and Yarn/Pnpm Workspaces",
4
- "version": "8.0.0",
4
+ "version": "8.2.4",
5
5
  "author": "Jamie Mason <jamie@foldleft.io> (https://github.com/JamieMason)",
6
6
  "bin": {
7
7
  "syncpack": "dist/bin.js",
@@ -25,32 +25,32 @@
25
25
  ],
26
26
  "dependencies": {
27
27
  "chalk": "4.1.2",
28
- "commander": "9.2.0",
28
+ "commander": "9.3.0",
29
29
  "cosmiconfig": "7.0.1",
30
30
  "expect-more": "1.2.0",
31
31
  "fp-ts": "2.12.1",
32
32
  "fs-extra": "10.1.0",
33
- "glob": "8.0.1",
34
- "minimatch": "5.0.1",
33
+ "glob": "8.0.3",
34
+ "minimatch": "5.1.0",
35
35
  "read-yaml-file": "2.1.0",
36
36
  "semver": "7.3.7"
37
37
  },
38
38
  "devDependencies": {
39
39
  "@types/fs-extra": "9.0.13",
40
40
  "@types/glob": "7.2.0",
41
- "@types/jest": "27.4.1",
42
- "@types/node": "17.0.31",
43
- "@types/semver": "7.3.9",
44
- "@typescript-eslint/eslint-plugin": "5.21.0",
45
- "@typescript-eslint/parser": "5.21.0",
46
- "eslint": "8.14.0",
41
+ "@types/jest": "28.1.3",
42
+ "@types/node": "18.0.0",
43
+ "@types/semver": "7.3.10",
44
+ "@typescript-eslint/eslint-plugin": "5.29.0",
45
+ "@typescript-eslint/parser": "5.29.0",
46
+ "eslint": "8.18.0",
47
47
  "eslint-plugin-import": "2.26.0",
48
- "expect-more-jest": "5.4.0",
49
- "jest": "27.5.1",
50
- "prettier": "2.6.2",
48
+ "expect-more-jest": "5.4.1",
49
+ "jest": "28.1.1",
50
+ "prettier": "2.7.1",
51
51
  "rimraf": "3.0.2",
52
- "ts-jest": "27.1.4",
53
- "typescript": "4.6.4"
52
+ "ts-jest": "28.0.5",
53
+ "typescript": "4.7.4"
54
54
  },
55
55
  "engines": {
56
56
  "node": ">=10"