New Case Study:See how Anthropic automated 95% of dependency reviews with Socket.Learn More
Socket
Sign inDemoInstall
Socket

syncpack

Package Overview
Dependencies
Maintainers
1
Versions
92
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

syncpack - npm Package Compare versions

Comparing version 9.8.6 to 10.0.0

dist/config/get-custom-types.d.ts

4

dist/bin-fix-mismatches/fix-mismatches-cli.d.ts

@@ -0,3 +1,3 @@

import type { CliConfig } from '../config/types';
import type { Disk } from '../lib/disk';
import type { Syncpack } from '../types';
export declare function fixMismatchesCli(input: Partial<Syncpack.Config.Cli>, disk: Disk): void;
export declare function fixMismatchesCli(input: Partial<CliConfig>, disk: Disk): void;
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.fixMismatchesCli = void 0;
const pipe_1 = require("tightrope/fn/pipe");
const get_context_1 = require("../get-context");
const exit_if_invalid_1 = require("../lib/exit-if-invalid");
const write_if_changed_1 = require("../lib/write-if-changed");
const fix_mismatches_1 = require("./fix-mismatches");
function fixMismatchesCli(input, disk) {
(0, write_if_changed_1.writeIfChanged)((0, fix_mismatches_1.fixMismatches)((0, get_context_1.getContext)(input, disk)));
(0, pipe_1.pipe)((0, get_context_1.getContext)(input, disk), fix_mismatches_1.fixMismatches, write_if_changed_1.writeIfChanged, exit_if_invalid_1.exitIfInvalid);
}
exports.fixMismatchesCli = fixMismatchesCli;

@@ -1,2 +0,2 @@

import type { Syncpack } from '../types';
export declare function fixMismatches(ctx: Syncpack.Ctx): Syncpack.Ctx;
import type { Context } from '../get-context';
export declare function fixMismatches(ctx: Context): Context;
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.fixMismatches = void 0;
const pipe_1 = require("tightrope/fn/pipe");
const is_object_1 = require("tightrope/guard/is-object");
const is_undefined_1 = require("tightrope/guard/is-undefined");
const tap_1 = require("tightrope/result/tap");
const _R_1 = require("../get-context/$R");
const get_version_groups_1 = require("../get-version-groups");
const delete_1 = require("../get-version-groups/lib/delete");
function fixMismatches(ctx) {
ctx.versionGroups.forEach((versionGroup) => {
const invalidGroups = versionGroup.getInvalidInstanceGroups();
// Nothing to do if there are no mismatches
if (invalidGroups.length === 0)
return;
// Set the correct version on each instance.
invalidGroups.forEach((instanceGroup) => {
if (!instanceGroup.hasUnsupportedVersion()) {
(0, pipe_1.pipe)(instanceGroup.getExpectedVersion(), (0, tap_1.tap)((nextVersion) => {
instanceGroup.instances.forEach((instance) => instance.setVersion(nextVersion));
}), _R_1.$R.tapErrVerbose);
const versionGroups = (0, get_version_groups_1.getVersionGroups)(ctx);
let shouldPruneEmpty = false;
versionGroups.forEach((versionGroup) => {
versionGroup.inspect().forEach((outcome) => {
if (!outcome.isValid) {
outcome.instances.forEach((instance) => {
switch (outcome.status) {
case 'HIGHEST_SEMVER_MISMATCH':
case 'LOWEST_SEMVER_MISMATCH':
case 'PINNED_MISMATCH':
case 'SNAPPED_TO_MISMATCH':
case 'WORKSPACE_MISMATCH': {
instance.setVersion(outcome.expectedVersion);
break;
}
case 'BANNED': {
shouldPruneEmpty = true;
instance.setVersion(delete_1.DELETE);
break;
}
case 'UNSUPPORTED_MISMATCH': {
// @TODO Output something when fix-mismatches faces an unsupported mismatch
ctx.isInvalid = true;
break;
}
// @TODO case 'SEMVER_UNSATISFIED': break;
// @TODO case 'WORKSPACE_UNSATISFIED': break;
}
});
}
});
});
/** Remove eg `{"dependencies": {}, "devDependencies": {}}` */
ctx.packageJsonFiles.forEach((packageJsonFile) => {
const contents = packageJsonFile.contents;
Object.keys(contents).forEach((key) => {
const value = contents[key];
if ((0, is_object_1.isObject)(value) &&
Object.values(value).every(is_undefined_1.isUndefined)) {
delete contents[key];
}
/** Remove empty objects such as `{"dependencies": {}}` left after deleting */
if (shouldPruneEmpty) {
ctx.packageJsonFiles.forEach((packageJsonFile) => {
const contents = packageJsonFile.contents;
Object.keys(contents).forEach((key) => {
const value = contents[key];
if ((0, is_object_1.isObject)(value) && Object.values(value).every(is_undefined_1.isUndefined)) {
delete contents[key];
}
});
});
});
}
return ctx;
}
exports.fixMismatches = fixMismatches;

@@ -0,3 +1,3 @@

import type { CliConfig } from '../config/types';
import type { Disk } from '../lib/disk';
import type { Syncpack } from '../types';
export declare function formatCli(input: Partial<Syncpack.Config.Cli>, disk: Disk): void;
export declare function formatCli(input: Partial<CliConfig>, disk: Disk): void;
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.formatCli = void 0;
const pipe_1 = require("tightrope/fn/pipe");
const get_context_1 = require("../get-context");

@@ -8,4 +9,4 @@ const write_if_changed_1 = require("../lib/write-if-changed");

function formatCli(input, disk) {
(0, write_if_changed_1.writeIfChanged)((0, format_1.format)((0, get_context_1.getContext)(input, disk)));
(0, pipe_1.pipe)((0, get_context_1.getContext)(input, disk), format_1.format, write_if_changed_1.writeIfChanged);
}
exports.formatCli = formatCli;

@@ -1,2 +0,2 @@

import type { Syncpack } from '../types';
export declare function format(ctx: Syncpack.Ctx): Syncpack.Ctx;
import type { Context } from '../get-context';
export declare function format(ctx: Context): Context;

@@ -7,5 +7,8 @@ "use strict";

const is_object_1 = require("tightrope/guard/is-object");
const get_sort_az_1 = require("../config/get-sort-az");
const get_sort_first_1 = require("../config/get-sort-first");
function format(ctx) {
const { packageJsonFiles } = ctx;
const { sortAz, sortFirst } = ctx.config;
const sortAz = (0, get_sort_az_1.getSortAz)(ctx.config);
const sortFirst = (0, get_sort_first_1.getSortFirst)(ctx.config);
packageJsonFiles.forEach((packageJsonFile) => {

@@ -12,0 +15,0 @@ const { contents } = packageJsonFile;

@@ -0,3 +1,3 @@

import type { CliConfig } from '../config/types';
import type { Disk } from '../lib/disk';
import type { Syncpack } from '../types';
export declare function lintSemverRangesCli(input: Partial<Syncpack.Config.Cli>, disk: Disk): void;
export declare function lintSemverRangesCli(input: Partial<CliConfig>, disk: Disk): void;
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.lintSemverRangesCli = void 0;
const pipe_1 = require("tightrope/fn/pipe");
const get_context_1 = require("../get-context");

@@ -8,4 +9,4 @@ const exit_if_invalid_1 = require("../lib/exit-if-invalid");

function lintSemverRangesCli(input, disk) {
(0, exit_if_invalid_1.exitIfInvalid)((0, lint_semver_ranges_1.lintSemverRanges)((0, get_context_1.getContext)(input, disk)));
(0, pipe_1.pipe)((0, get_context_1.getContext)(input, disk), lint_semver_ranges_1.lintSemverRanges, exit_if_invalid_1.exitIfInvalid);
}
exports.lintSemverRangesCli = lintSemverRangesCli;

@@ -1,2 +0,2 @@

import type { Syncpack } from '../types';
export declare function lintSemverRanges(ctx: Syncpack.Ctx): Syncpack.Ctx;
import type { Context } from '../get-context';
export declare function lintSemverRanges(ctx: Context): Context;

@@ -31,23 +31,34 @@ "use strict";

const chalk_1 = __importDefault(require("chalk"));
const is_non_empty_array_1 = require("tightrope/guard/is-non-empty-array");
const constants_1 = require("../constants");
const get_semver_groups_1 = require("../get-semver-groups");
const log = __importStar(require("../lib/log"));
const sort_by_name_1 = require("../lib/sort-by-name");
function lintSemverRanges(ctx) {
const hasUserGroups = ctx.semverGroups.length > 1;
ctx.semverGroups.forEach((semverGroup, i) => {
// Nothing to do if there are no mismatches
if (!semverGroup.hasMismatches())
return;
// Record that this project has mismatches, so that eg. the CLI can exit
// with the correct status code.
ctx.isInvalid = true;
// Annotate each group
hasUserGroups && log.semverGroupHeader(semverGroup, i);
// Log each group which has mismatches
semverGroup.getMismatches().forEach(([name, mismatches]) => {
// Log the dependency name
log.invalid(name);
// Log each of the dependencies mismatches
mismatches.forEach((instance) => {
logSemverRangeMismatch(instance, semverGroup);
});
const semverGroups = (0, get_semver_groups_1.getSemverGroups)(ctx);
const hasUserGroups = (0, is_non_empty_array_1.isNonEmptyArray)(ctx.config.rcFile.semverGroups);
semverGroups.forEach((semverGroup, i) => {
semverGroup
.inspect()
.sort(sort_by_name_1.sortByName)
.forEach((report, ii) => {
// Allow eg. CLI to exit with the correct status code.
if (!report.isValid)
ctx.isInvalid = true;
switch (report.status) {
case 'WORKSPACE_SEMVER_RANGE_MISMATCH':
case 'SEMVER_RANGE_MISMATCH': {
// Annotate each group
if (ii === 0 && hasUserGroups)
log.semverGroupHeader(semverGroup, i);
console.log((0, chalk_1.default) `{red %s} %s {red %s} %s {green %s} {dim in %s of %s}`, constants_1.ICON.cross, report.name, report.instance.version, constants_1.ICON.rightArrow, report.expectedVersion, report.instance.strategy.path, report.instance.packageJsonFile.shortPath);
break;
}
case 'IGNORED':
case 'UNSUPPORTED_VERSION':
case 'VALID': {
// no action needed
break;
}
}
});

@@ -58,8 +69,1 @@ });

exports.lintSemverRanges = lintSemverRanges;
function logSemverRangeMismatch(instance, semverGroup) {
const path = instance.pathDef.path;
const shortPath = instance.packageJsonFile.shortPath;
const actual = instance.version;
const expected = semverGroup.getExpectedVersion(instance);
console.log((0, chalk_1.default) ` {red ${actual}} ${constants_1.ICON.rightArrow} {green ${expected}} {dim in ${path} of ${shortPath}}`);
}

@@ -0,3 +1,3 @@

import type { CliConfig } from '../config/types';
import type { Disk } from '../lib/disk';
import type { Syncpack } from '../types';
export declare function listMismatchesCli(input: Partial<Syncpack.Config.Cli>, disk: Disk): void;
export declare function listMismatchesCli(input: Partial<CliConfig>, disk: Disk): void;
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.listMismatchesCli = void 0;
const pipe_1 = require("tightrope/fn/pipe");
const get_context_1 = require("../get-context");

@@ -8,4 +9,4 @@ const exit_if_invalid_1 = require("../lib/exit-if-invalid");

function listMismatchesCli(input, disk) {
(0, exit_if_invalid_1.exitIfInvalid)((0, list_mismatches_1.listMismatches)((0, get_context_1.getContext)(input, disk)));
(0, pipe_1.pipe)((0, get_context_1.getContext)(input, disk), list_mismatches_1.listMismatches, exit_if_invalid_1.exitIfInvalid);
}
exports.listMismatchesCli = listMismatchesCli;

@@ -1,2 +0,2 @@

import type { Syncpack } from '../types';
export declare function listMismatches(ctx: Syncpack.Ctx): Syncpack.Ctx;
import type { Context } from '../get-context';
export declare function listMismatches(ctx: Context): Context;

@@ -31,115 +31,81 @@ "use strict";

const chalk_1 = __importDefault(require("chalk"));
const unwrap_1 = require("tightrope/option/unwrap");
const unwrap_2 = require("tightrope/result/unwrap");
const is_non_empty_array_1 = require("tightrope/guard/is-non-empty-array");
const constants_1 = require("../constants");
const get_version_groups_1 = require("../get-version-groups");
const log = __importStar(require("../lib/log"));
const sort_by_name_1 = require("../lib/sort-by-name");
function listMismatches(ctx) {
const hasUserGroups = ctx.versionGroups.length > 1;
ctx.versionGroups.forEach((versionGroup, i) => {
const invalidGroups = versionGroup.getInvalidInstanceGroups();
// Nothing to do if there are no mismatches
if (invalidGroups.length === 0)
return;
// Record that this project has mismatches, so that eg. the CLI can exit
// with the correct status code.
ctx.isInvalid = true;
// Annotate each group
hasUserGroups && log.versionGroupHeader(versionGroup, i);
// Log the mismatches
invalidGroups.forEach((instanceGroup) => {
if (versionGroup.isBanned())
return logBanned(instanceGroup);
if (versionGroup.isUnpinned())
return logUnpinned(instanceGroup);
if (versionGroup.hasSnappedToPackages())
return logSnappedTo(instanceGroup);
if (instanceGroup.hasUnsupportedVersion())
return logUnsupportedMismatches(instanceGroup);
if (instanceGroup.hasWorkspaceInstance()) {
return logWorkspaceMismatch(instanceGroup);
const versionGroups = (0, get_version_groups_1.getVersionGroups)(ctx);
const hasUserGroups = (0, is_non_empty_array_1.isNonEmptyArray)(ctx.config.rcFile.versionGroups);
versionGroups.forEach((versionGroup, i) => {
versionGroup
.inspect()
.sort(sort_by_name_1.sortByName)
.forEach((report, ii) => {
// no action needed
if (report.isValid)
return;
// Allow eg. CLI to exit with the correct status code.
ctx.isInvalid = true;
// Annotate each group
if (ii === 0 && hasUserGroups)
log.versionGroupHeader(versionGroup, i);
switch (report.status) {
case 'BANNED':
console.log((0, chalk_1.default) ` {red %s} %s {dim is banned in this version group}`, constants_1.ICON.cross, report.name);
report.instances.forEach((instance) => {
console.log((0, chalk_1.default) ` {red %s} {dim in %s of %s}`, instance.version, instance.strategy.path, instance.packageJsonFile.shortPath);
});
break;
case 'HIGHEST_SEMVER_MISMATCH':
case 'LOWEST_SEMVER_MISMATCH': {
console.log((0, chalk_1.default) `{red %s} %s {green %s} {dim is the %s valid semver version in use}`, constants_1.ICON.cross, report.name, report.expectedVersion, report.status === 'LOWEST_SEMVER_MISMATCH' ? 'lowest' : 'highest');
report.instances.forEach((instance) => {
if (instance.version !== report.expectedVersion) {
console.log((0, chalk_1.default) ` {red %s} {dim in %s of %s}`, instance.version, instance.strategy.path, instance.packageJsonFile.shortPath);
}
});
break;
}
case 'PINNED_MISMATCH': {
console.log((0, chalk_1.default) `{red %s} %s {dim is pinned in this version group at} {green %s}`, constants_1.ICON.cross, report.name, report.expectedVersion);
report.instances.forEach((instance) => {
if (instance.version !== report.expectedVersion) {
console.log((0, chalk_1.default) ` {red %s} {dim in %s of %s}`, instance.version, instance.strategy.path, instance.packageJsonFile.shortPath);
}
});
break;
}
case 'SNAPPED_TO_MISMATCH': {
console.log((0, chalk_1.default) `{red %s} %s {dim should snap to {reset.green %s}, used by %s}`, constants_1.ICON.cross, report.name, report.expectedVersion, versionGroup.config.snapTo.join(' || '));
report.instances.forEach((instance) => {
if (instance.version !== report.expectedVersion) {
console.log((0, chalk_1.default) ` {red %s} {dim in %s of %s}`, instance.version, instance.strategy.path, instance.packageJsonFile.shortPath);
}
});
break;
}
case 'UNSUPPORTED_MISMATCH': {
console.log((0, chalk_1.default) `{red %s} %s {dim has mismatched versions which syncpack cannot fix}`, constants_1.ICON.cross, report.name);
report.instances.forEach((instance) => {
console.log((0, chalk_1.default) ` {yellow %s} {dim in %s of %s}`, instance.version, instance.strategy.path, instance.packageJsonFile.shortPath);
});
break;
}
case 'WORKSPACE_MISMATCH': {
console.log((0, chalk_1.default) `{red %s} %s {green %s} {dim is developed in this repo at %s}`, constants_1.ICON.cross, report.name, report.expectedVersion, report.workspaceInstance.packageJsonFile.shortPath);
report.instances.forEach((instance) => {
if (instance.version !== report.expectedVersion) {
console.log((0, chalk_1.default) ` {red %s} {dim in %s of %s}`, instance.version, instance.strategy.path, instance.packageJsonFile.shortPath);
}
});
break;
}
// @TODO case 'SEMVER_UNSATISFIED': break;
// @TODO case 'WORKSPACE_UNSATISFIED': break;
}
logHighLowVersionMismatch(instanceGroup);
});
});
return ctx;
function logBanned(instanceGroup) {
const name = instanceGroup.name;
log.invalid(name, 'is banned in this version group');
// Log each of the dependencies mismatches
instanceGroup.instances.forEach((instance) => {
logVersionMismatch(instance);
});
}
function logUnsupportedMismatches(instanceGroup) {
const name = instanceGroup.name;
log.invalid(name, 'has mismatched versions which syncpack cannot fix');
// Log each of the dependencies mismatches
instanceGroup.instances.forEach((instance) => {
logUnsupportedVersionMismatch(instance);
});
}
function logUnpinned(instanceGroup) {
const name = instanceGroup.name;
const pinVersion = (0, unwrap_1.unwrap)(instanceGroup.versionGroup.getPinnedVersion());
log.invalid(name, (0, chalk_1.default) `is pinned in this version group at {reset.green ${pinVersion}}`);
// Log each of the dependencies mismatches
instanceGroup.instances.forEach((instance) => {
if (instance.version !== pinVersion) {
logVersionMismatch(instance);
}
});
}
function logSnappedTo(instanceGroup) {
const name = instanceGroup.name;
const versionGroup = instanceGroup.versionGroup;
const snappedVersion = (0, unwrap_2.unwrap)(instanceGroup.getSnappedVersion());
const snappedToPackages = (0, unwrap_1.unwrap)(versionGroup.getSnappedToPackages()).join(' || ');
const version = (0, unwrap_2.unwrap)(instanceGroup.getExpectedVersion());
log.invalid(name, (0, chalk_1.default) `should snap to {reset.green ${version}}, used by ${snappedToPackages}`);
// Log each of the dependencies mismatches
instanceGroup.instances.forEach((instance) => {
if (instance.version !== snappedVersion) {
logVersionMismatch(instance);
}
});
}
function logWorkspaceMismatch(instanceGroup) {
const name = instanceGroup.name;
const workspaceInstance = (0, unwrap_2.unwrap)(instanceGroup.getWorkspaceInstance());
const shortPath = workspaceInstance?.packageJsonFile.shortPath;
const expected = (0, unwrap_2.unwrap)(instanceGroup.getExpectedVersion());
log.invalid(name, (0, chalk_1.default) `{reset.green ${expected}} {dim is developed in this repo at ${shortPath}}`);
// Log each of the dependencies mismatches
instanceGroup.instances.forEach((instance) => {
if (instance.version !== expected) {
logVersionMismatch(instance);
}
});
}
function logHighLowVersionMismatch(instanceGroup) {
const name = instanceGroup.name;
const preference = instanceGroup.versionGroup
.groupConfig.preferVersion;
const direction = preference === 'highestSemver' ? 'highest' : 'lowest';
const expected = (0, unwrap_2.unwrap)(instanceGroup.getExpectedVersion());
log.invalid(name, (0, chalk_1.default) `{reset.green ${expected}} {dim is the ${direction} valid semver version in use}`);
// Log each of the dependencies mismatches
instanceGroup.instances.forEach((instance) => {
if (instance.version !== expected) {
logVersionMismatch(instance);
}
});
}
function logVersionMismatch(instance) {
const type = instance.pathDef.path;
const shortPath = instance.packageJsonFile.shortPath;
const actual = instance.version;
console.log((0, chalk_1.default) ` {red ${actual}} {dim in ${type} of ${shortPath}}`);
}
function logUnsupportedVersionMismatch(instance) {
const type = instance.pathDef.path;
const shortPath = instance.packageJsonFile.shortPath;
const actual = instance.version;
console.log((0, chalk_1.default) ` {yellow ${actual}} {dim in ${type} of ${shortPath}}`);
}
}
exports.listMismatches = listMismatches;

@@ -0,3 +1,3 @@

import type { CliConfig } from '../config/types';
import type { Disk } from '../lib/disk';
import type { Syncpack } from '../types';
export declare function listCli(input: Partial<Syncpack.Config.Cli>, disk: Disk): void;
export declare function listCli(input: Partial<CliConfig>, disk: Disk): void;
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.listCli = void 0;
const pipe_1 = require("tightrope/fn/pipe");
const get_context_1 = require("../get-context");

@@ -8,4 +9,4 @@ const exit_if_invalid_1 = require("../lib/exit-if-invalid");

function listCli(input, disk) {
(0, exit_if_invalid_1.exitIfInvalid)((0, list_1.list)((0, get_context_1.getContext)(input, disk)));
(0, pipe_1.pipe)((0, get_context_1.getContext)(input, disk), list_1.list, exit_if_invalid_1.exitIfInvalid);
}
exports.listCli = listCli;

@@ -1,2 +0,2 @@

import type { Syncpack } from '../types';
export declare function list(ctx: Syncpack.Ctx): Syncpack.Ctx;
import type { Context } from '../get-context';
export declare function list(ctx: Context): Context;

@@ -31,67 +31,71 @@ "use strict";

const chalk_1 = __importDefault(require("chalk"));
const pipe_1 = require("tightrope/fn/pipe");
const unwrap_1 = require("tightrope/option/unwrap");
const tap_1 = require("tightrope/result/tap");
const uniq_1 = require("tightrope/array/uniq");
const is_non_empty_array_1 = require("tightrope/guard/is-non-empty-array");
const constants_1 = require("../constants");
const _R_1 = require("../get-context/$R");
const get_version_groups_1 = require("../get-version-groups");
const log = __importStar(require("../lib/log"));
const sort_by_name_1 = require("../lib/sort-by-name");
function list(ctx) {
const hasUserGroups = ctx.versionGroups.length > 1;
ctx.versionGroups.forEach((versionGroup, i) => {
const instanceGroups = versionGroup.getAllInstanceGroups();
// Nothing to do if empty
if (instanceGroups.length === 0)
return;
const versionGroups = (0, get_version_groups_1.getVersionGroups)(ctx);
const hasUserGroups = (0, is_non_empty_array_1.isNonEmptyArray)(ctx.config.rcFile.versionGroups);
versionGroups.forEach((versionGroup, i) => {
// Annotate each group
hasUserGroups && log.versionGroupHeader(versionGroup, i);
instanceGroups.forEach((instanceGroup) => {
// Record that this project has mismatches, so that eg. the CLI can exit
// with the correct status code.
if (instanceGroup.isInvalid())
versionGroup
.inspect()
.sort(sort_by_name_1.sortByName)
.forEach((report) => {
// Allow eg. CLI to exit with the correct status code.
if (!report.isValid)
ctx.isInvalid = true;
if (versionGroup.isBanned())
return logBanned(instanceGroup);
if (versionGroup.isIgnored())
return logIgnored(instanceGroup);
if (versionGroup.isUnpinned())
return logUnpinned(instanceGroup);
if (instanceGroup.hasMismatchingVersions()) {
return instanceGroup.hasUnsupportedVersion()
? logUnsupportedMismatches(instanceGroup)
: logVersionMismatch(instanceGroup);
switch (report.status) {
case 'HIGHEST_SEMVER_MISMATCH':
case 'LOWEST_SEMVER_MISMATCH':
case 'PINNED_MISMATCH':
case 'SNAPPED_TO_MISMATCH':
case 'WORKSPACE_MISMATCH': {
console.log((0, chalk_1.default) `{red %s %s} %s`, constants_1.ICON.cross, report.name, listColouredVersions(report.expectedVersion, report.instances));
break;
}
case 'BANNED': {
console.log((0, chalk_1.default) `{red %s %s} {dim.red is banned in this version group}`, constants_1.ICON.cross, report.name);
break;
}
// ignored completely
case 'FILTERED_OUT':
break;
case 'IGNORED': {
console.log((0, chalk_1.default) `{dim -} {dim %s} {white is ignored in this version group}`, report.name);
break;
}
case 'VALID': {
console.log((0, chalk_1.default) `{dim -} {white %s} {dim %s}`, report.name, report.instances?.[0]?.version);
break;
}
case 'UNSUPPORTED_MISMATCH': {
console.log((0, chalk_1.default) `{red %s %s} %s`, constants_1.ICON.cross, report.name, report.instances
.map((instance) => chalk_1.default.red(instance.version))
.join(chalk_1.default.dim(', ')));
break;
}
// @TODO case 'SEMVER_UNSATISFIED': break;
// @TODO case 'WORKSPACE_UNSATISFIED': break;
}
logVersionMatch(instanceGroup);
function listColouredVersions(pinVersion, instances) {
return getAllVersions(pinVersion, instances)
.map((version) => withColour(pinVersion, version))
.join(chalk_1.default.dim(', '));
}
function withColour(pinVersion, version) {
return version === pinVersion
? chalk_1.default.green(version)
: chalk_1.default.red(version);
}
function getAllVersions(pinVersion, instances) {
return (0, uniq_1.uniq)([pinVersion].concat(instances.map((i) => i.version)));
}
});
});
return ctx;
function logVersionMatch(instanceGroup) {
console.log((0, chalk_1.default) `{dim -} {white ${instanceGroup.name}} {dim ${instanceGroup.getUniqueVersions()}}`);
}
function logVersionMismatch(instanceGroup) {
(0, pipe_1.pipe)(instanceGroup.getExpectedVersion(), (0, tap_1.tap)((expectedVersion) => {
const uniqueVersions = instanceGroup.getUniqueVersions();
console.log((0, chalk_1.default) `{red ${constants_1.ICON.cross} ${instanceGroup.name}} ${uniqueVersions
.map((version) => version === expectedVersion
? chalk_1.default.green(version)
: chalk_1.default.red(version))
.join(chalk_1.default.dim(', '))}`);
}), _R_1.$R.tapErrVerbose);
}
function logIgnored(instanceGroup) {
console.log((0, chalk_1.default) `{dim ${constants_1.ICON.skip} ${instanceGroup.name}} is ignored in this version group`);
}
function logBanned(instanceGroup) {
console.log((0, chalk_1.default) `{red ${constants_1.ICON.cross} ${instanceGroup.name}} {dim.red is banned in this version group}`);
}
function logUnpinned(instanceGroup) {
const pinVersion = (0, unwrap_1.unwrap)(instanceGroup.versionGroup.getPinnedVersion());
console.log((0, chalk_1.default) `{red ${constants_1.ICON.cross} ${instanceGroup.name}} {dim.red is pinned to ${pinVersion} in this version group}`);
}
function logUnsupportedMismatches(instanceGroup) {
console.log((0, chalk_1.default) `{red ${constants_1.ICON.cross} ${instanceGroup.name}} {dim.red has mismatched versions which syncpack cannot fix: ${instanceGroup
.getUniqueVersions()
.map((version) => chalk_1.default.yellow(version))
.join(chalk_1.default.dim(', '))}}`);
}
}
exports.list = list;

@@ -0,3 +1,3 @@

import type { CliConfig } from '../config/types';
import type { Disk } from '../lib/disk';
import type { Syncpack } from '../types';
export declare function setSemverRangesCli(input: Partial<Syncpack.Config.Cli>, disk: Disk): void;
export declare function setSemverRangesCli(input: Partial<CliConfig>, disk: Disk): void;
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.setSemverRangesCli = void 0;
const pipe_1 = require("tightrope/fn/pipe");
const get_context_1 = require("../get-context");

@@ -8,4 +9,4 @@ const write_if_changed_1 = require("../lib/write-if-changed");

function setSemverRangesCli(input, disk) {
(0, write_if_changed_1.writeIfChanged)((0, set_semver_ranges_1.setSemverRanges)((0, get_context_1.getContext)(input, disk)));
(0, pipe_1.pipe)((0, get_context_1.getContext)(input, disk), set_semver_ranges_1.setSemverRanges, write_if_changed_1.writeIfChanged);
}
exports.setSemverRangesCli = setSemverRangesCli;

@@ -1,2 +0,2 @@

import type { Syncpack } from '../types';
export declare const setSemverRanges: (ctx: Syncpack.Ctx) => Syncpack.Ctx;
import type { Context } from '../get-context';
export declare const setSemverRanges: (ctx: Context) => Context;
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.setSemverRanges = void 0;
const get_semver_groups_1 = require("../get-semver-groups");
const setSemverRanges = (ctx) => {
ctx.semverGroups.forEach((semverGroup) => {
semverGroup.instances.forEach((instance) => {
instance.setVersion(semverGroup.getExpectedVersion(instance));
(0, get_semver_groups_1.getSemverGroups)(ctx).forEach((semverGroup) => {
semverGroup.inspect().forEach((report) => {
switch (report.status) {
case 'WORKSPACE_SEMVER_RANGE_MISMATCH':
case 'SEMVER_RANGE_MISMATCH': {
report.instance.setVersion(report.expectedVersion);
break;
}
case 'FILTERED_OUT':
case 'IGNORED':
case 'UNSUPPORTED_VERSION':
case 'VALID': {
// no action needed
break;
}
}
});

@@ -9,0 +23,0 @@ });

@@ -24,2 +24,3 @@ /** Single source of truth, intended to aid testing or to override */

readonly PATCH: "~";
readonly WORKSPACE: "workspace:";
};

@@ -26,0 +27,0 @@ export declare const DEFAULT_CONFIG: {

@@ -27,2 +27,3 @@ "use strict";

PATCH: '~',
WORKSPACE: 'workspace:',
};

@@ -29,0 +30,0 @@ exports.DEFAULT_CONFIG = {

@@ -0,22 +1,14 @@

import type { O } from 'ts-toolbelt';
import type { CliConfig, RcConfig } from '../config/types';
import type { PackageJsonFile } from '../get-package-json-files/package-json-file';
import type { Disk } from '../lib/disk';
import type { Syncpack } from '../types';
import type { SemverGroup } from './get-groups/semver-group';
import type { VersionGroup } from './get-groups/version-group';
import type { PackageJsonFile } from './get-package-json-files/package-json-file';
export interface Context {
config: Syncpack.Config.Private;
config: {
cli: Partial<CliConfig>;
rcFile: O.Partial<RcConfig, 'deep'>;
};
disk: Disk;
isInvalid: boolean;
packageJsonFiles: PackageJsonFile[];
semverGroups: SemverGroup[];
versionGroups: VersionGroup[];
}
/**
* Every command in syncpack should accept the return value of this function as
* its input.
*
* The aim here is to move all disk activity to a single place, so
* that the majority of syncpack and its tests don't have to deal with the file
* system and can focus solely on transformation logic.
*/
export declare function getContext(program: Partial<Syncpack.Config.Cli>, disk?: Disk): Context;
export declare function getContext(cli: Partial<CliConfig>, disk: Disk): Context;
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.getContext = void 0;
const pipe_1 = require("tightrope/fn/pipe");
const and_then_1 = require("tightrope/result/and-then");
const map_1 = require("tightrope/result/map");
const unwrap_1 = require("tightrope/result/unwrap");
const disk_1 = require("../lib/disk");
const _R_1 = require("./$R");
const get_config_1 = require("./get-config");
const get_groups_1 = require("./get-groups");
const get_package_json_files_1 = require("./get-package-json-files");
/**
* Every command in syncpack should accept the return value of this function as
* its input.
*
* The aim here is to move all disk activity to a single place, so
* that the majority of syncpack and its tests don't have to deal with the file
* system and can focus solely on transformation logic.
*/
function getContext(program, disk = disk_1.disk) {
return (0, pipe_1.pipe)(
// merge CLI options, .syncpackrc contents, and default config
(0, get_config_1.getConfig)(disk, program), (0, and_then_1.andThen)((config) => (0, pipe_1.pipe)(
// get the package.json file which match the globs in config
(0, get_package_json_files_1.getPackageJsonFiles)(disk, config), (0, and_then_1.andThen)((packageJsonFiles) => (0, pipe_1.pipe)(
// allocate dependencies into semver and version groups
(0, get_groups_1.getGroups)(config, packageJsonFiles),
// combine everything into the final config
(0, map_1.map)(({ semverGroups, versionGroups }) => ({
const get_package_json_files_1 = require("../get-package-json-files");
function getContext(cli, disk) {
const rcFile = disk.readConfigFileSync(cli.configPath);
const config = { cli, rcFile };
const packageJsonFiles = (0, unwrap_1.unwrap)((0, get_package_json_files_1.getPackageJsonFiles)(disk, config));
return {
config,

@@ -35,10 +15,4 @@ disk,

packageJsonFiles,
semverGroups,
versionGroups,
})))))),
// if anything errored at any stage, log it when in verbose mode
_R_1.$R.tapErrVerbose,
// throw if anything errored, can't do anything without this data
unwrap_1.unwrap);
};
}
exports.getContext = getContext;

@@ -1,2 +0,3 @@

import type { Syncpack } from '../types';
import type { O } from 'ts-toolbelt';
import type { RcConfig } from '../config/types';
export type Disk = {

@@ -7,3 +8,3 @@ process: {

globSync: (pattern: string) => string[];
readConfigFileSync: (configPath?: string) => Partial<Syncpack.Config.SyncpackRc>;
readConfigFileSync: (configPath?: string) => O.Partial<RcConfig, 'deep'>;
readFileSync: (filePath: string) => string;

@@ -10,0 +11,0 @@ readYamlFileSync: <T = unknown>(filePath: string) => T;

@@ -1,2 +0,2 @@

import type { Syncpack } from '../types';
export declare function exitIfInvalid(ctx: Syncpack.Ctx): Syncpack.Ctx;
import type { Context } from '../get-context';
export declare function exitIfInvalid(ctx: Context): Context;

@@ -1,4 +0,6 @@

import type { Syncpack } from '../types';
export declare function isValidSemverRange(value: unknown): value is Syncpack.Config.SemverRange.Value;
export declare function isSemver(version: unknown): version is string;
import type { SemverRange } from '../config/types';
export declare function isValidSemverRange(value: unknown): value is SemverRange;
export declare function isSupported(version: unknown): version is string;
export declare function isWorkspaceProtocol(version: unknown): boolean;
export declare function isSemver(version: unknown): boolean;
export declare function isLooseSemver(version: unknown): boolean;
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.isLooseSemver = exports.isSemver = exports.isValidSemverRange = void 0;
exports.isLooseSemver = exports.isSemver = exports.isWorkspaceProtocol = exports.isSupported = exports.isValidSemverRange = void 0;
const is_string_1 = require("tightrope/guard/is-string");

@@ -15,5 +15,19 @@ const constants_1 = require("../constants");

value === constants_1.RANGE.MINOR ||
value === constants_1.RANGE.PATCH);
value === constants_1.RANGE.PATCH ||
value === constants_1.RANGE.WORKSPACE);
}
exports.isValidSemverRange = isValidSemverRange;
function isSupported(version) {
return version === '*' || isSemver(version) || isWorkspaceProtocol(version);
}
exports.isSupported = isSupported;
function isWorkspaceProtocol(version) {
if (!(0, is_string_1.isString)(version))
return false;
if (!version.startsWith('workspace:'))
return false;
const value = version.replace(/^workspace:/, '');
return value === '*' || isSemver(value);
}
exports.isWorkspaceProtocol = isWorkspaceProtocol;
function isSemver(version) {

@@ -34,4 +48,4 @@ const range = '(~|\\^|>=|>|<=|<)?';

function isLooseSemver(version) {
return isSemver(version) && version.search(/\.x(\.|$)/) !== -1;
return ((0, is_string_1.isString)(version) && isSemver(version) && version.search(/\.x(\.|$)/) !== -1);
}
exports.isLooseSemver = isLooseSemver;

@@ -1,9 +0,5 @@

import type { SemverGroup } from '../get-context/get-groups/semver-group';
import type { VersionGroup } from '../get-context/get-groups/version-group';
import type { AnySemverGroup } from '../get-semver-groups';
import type { AnyVersionGroup } from '../get-version-groups';
export declare function verbose(...values: unknown[]): void;
export declare function fixed(message: string): void;
export declare function skip(message: string): void;
export declare function valid(message: string, comment?: string): void;
export declare function invalid(message: string, comment?: string): void;
export declare function semverGroupHeader(group: SemverGroup, i: number): void;
export declare function versionGroupHeader(group: VersionGroup, i: number): void;
export declare function semverGroupHeader(group: AnySemverGroup, i: number): void;
export declare function versionGroupHeader(group: AnyVersionGroup, i: number): void;

@@ -6,3 +6,3 @@ "use strict";

Object.defineProperty(exports, "__esModule", { value: true });
exports.versionGroupHeader = exports.semverGroupHeader = exports.invalid = exports.valid = exports.skip = exports.fixed = exports.verbose = void 0;
exports.versionGroupHeader = exports.semverGroupHeader = exports.verbose = void 0;
const chalk_1 = __importDefault(require("chalk"));

@@ -26,28 +26,2 @@ const is_string_1 = require("tightrope/guard/is-string");

exports.verbose = verbose;
function fixed(message) {
console.log((0, chalk_1.default) `{green ${constants_1.ICON.tick}}`, message);
}
exports.fixed = fixed;
function skip(message) {
console.log(chalk_1.default.dim(constants_1.ICON.skip), chalk_1.default.dim(message));
}
exports.skip = skip;
function valid(message, comment) {
if (comment) {
console.log((0, chalk_1.default) `{dim ${constants_1.ICON.skip}} ${message} {dim ${comment}}`);
}
else {
console.log((0, chalk_1.default) `{dim ${constants_1.ICON.skip}} ${message}`);
}
}
exports.valid = valid;
function invalid(message, comment) {
if (comment) {
console.log((0, chalk_1.default) `{red ${constants_1.ICON.cross}} ${message} {dim ${comment}}`);
}
else {
console.log((0, chalk_1.default) `{red ${constants_1.ICON.cross}} ${message}`);
}
}
exports.invalid = invalid;
function semverGroupHeader(group, i) {

@@ -62,4 +36,4 @@ logHeader(group, 'Semver', i);

function logHeader(group, type, i) {
const customLabel = group.groupConfig.label;
const labelWhenDefault = group.isDefault ? `Default ${type} Group` : '';
const customLabel = group.config.label;
const labelWhenDefault = group._tag === 'CatchAll' ? `Default ${type} Group` : '';
const anonymousLabel = `${type} Group ${i + 1}`;

@@ -66,0 +40,0 @@ const label = (customLabel || labelWhenDefault || anonymousLabel).trim();

@@ -1,2 +0,2 @@

import type { Syncpack } from '../types';
export declare function setSemverRange(semverRange: Syncpack.Config.SemverRange.Value, version: string): string;
import type { SemverRange } from '../config/types';
export declare function setSemverRange(semverRange: SemverRange, version: string): string;

@@ -1,2 +0,2 @@

import type { Syncpack } from '../types';
export declare function writeIfChanged(ctx: Syncpack.Ctx): Syncpack.Ctx;
import type { Context } from '../get-context';
export declare function writeIfChanged(ctx: Context): Context;
"use strict";
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() { return m[k]; } };
}
Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
o["default"] = v;
});
var __importStar = (this && this.__importStar) || function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
__setModuleDefault(result, mod);
return result;
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.writeIfChanged = void 0;
const log = __importStar(require("./log"));
const chalk_1 = __importDefault(require("chalk"));
const constants_1 = require("../constants");
function writeIfChanged(ctx) {

@@ -32,6 +13,6 @@ ctx.packageJsonFiles.forEach((packageJsonFile) => {

packageJsonFile.write();
log.fixed(packageJsonFile.shortPath);
console.log((0, chalk_1.default) `{green ${constants_1.ICON.tick}}`, packageJsonFile.shortPath);
}
else {
log.skip(packageJsonFile.shortPath);
console.log(chalk_1.default.dim(constants_1.ICON.skip), chalk_1.default.dim(packageJsonFile.shortPath));
}

@@ -38,0 +19,0 @@ });

{
"name": "syncpack",
"description": "Consistent dependency versions in large JavaScript Monorepos",
"version": "9.8.6",
"version": "10.0.0",
"author": "Jamie Mason <jamie@foldleft.io> (https://github.com/JamieMason)",

@@ -21,2 +21,3 @@ "bin": {

"Daniel Silva (https://github.com/dsilvasc)",
"Jamie Haywood (https://github.com/jamiehaywood)",
"Jamie Mason (https://github.com/JamieMason)",

@@ -27,2 +28,3 @@ "Jody Heavener (https://github.com/jodyheavener)",

"Matt Sprague (https://github.com/uforic)",
"Siraj (https://github.com/Syhner)",
"Tom Fletcher (https://github.com/tom-fletcher)"

@@ -40,3 +42,3 @@ ],

"tightrope": "0.1.0",
"zod": "3.21.4"
"ts-toolbelt": "9.6.0"
},

@@ -61,3 +63,3 @@ "devDependencies": {

"ts-node": "10.9.1",
"typescript": "4.9.5"
"typescript": "5.0.4"
},

@@ -92,2 +94,3 @@ "engines": {

"license": "MIT",
"main": "dist/index.js",
"repository": "JamieMason/syncpack",

@@ -105,3 +108,4 @@ "resolutions": {

"test": "jest src test"
}
},
"types": "dist/index.d.ts"
}

@@ -13,4 +13,3 @@ # syncpack

Full information can be found in the documentation at
https://jamiemason.github.io/syncpack/.
Full information can be found in the documentation at https://jamiemason.github.io/syncpack/.

@@ -21,17 +20,16 @@ ## Commands

Ensure that multiple packages requiring the same dependency define the same
version, so that every package requires eg. `react@16.4.2`, instead of a
combination of `react@16.4.2`, `react@0.15.9`, and `react@16.0.0`.
Ensure that multiple packages requiring the same dependency define the same version, so that every
package requires eg. `react@16.4.2`, instead of a combination of `react@16.4.2`, `react@0.15.9`, and
`react@16.0.0`.
### [format](https://jamiemason.github.io/syncpack/format)
Organise package.json files according to a conventional format, where fields
appear in a predictable order and nested fields are ordered alphabetically.
Shorthand properties are used where available, such as the `"repository"` and
`"bugs"` fields.
Organise package.json files according to a conventional format, where fields appear in a predictable
order and nested fields are ordered alphabetically. Shorthand properties are used where available,
such as the `"repository"` and `"bugs"` fields.
### [lint-semver-ranges](https://jamiemason.github.io/syncpack/lint-semver-ranges)
Check whether dependency versions used within "dependencies", "devDependencies",
etc follow a consistent format.
Check whether dependency versions used within "dependencies", "devDependencies", etc follow a
consistent format.

@@ -44,16 +42,16 @@ ### [list](https://jamiemason.github.io/syncpack/list)

List dependencies which are required by multiple packages, where the version is
not the same across every package.
List dependencies which are required by multiple packages, where the version is not the same across
every package.
### [set-semver-ranges](https://jamiemason.github.io/syncpack/set-semver-ranges)
Ensure dependency versions used within `"dependencies"`, `"devDependencies"` etc
follow a consistent format.
Ensure dependency versions used within `"dependencies"`, `"devDependencies"` etc follow a consistent
format.
## Breaking Changes
Version [9.0.0](https://github.com/JamieMason/syncpack/releases/tag/9.0.0)
required some breaking API changes to add support for a new
[`customTypes`](https://jamiemason.github.io/syncpack/config/custom-types)
feature, but they are very simple to make.
Version [9.0.0](https://github.com/JamieMason/syncpack/releases/tag/9.0.0) required some breaking
API changes to add support for a new
[`customTypes`](https://jamiemason.github.io/syncpack/config/custom-types) feature, but they are
very simple to make.

@@ -60,0 +58,0 @@ ## Badges

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc