Skip to content

Commit

Permalink
feat(publish): apply publishConfig overrides, closes #404 (#415)
Browse files Browse the repository at this point in the history
* feat(publish): apply publishConfig overrides, closes #404

Co-authored-by: changyoung <changyoung@toss.im>
  • Loading branch information
ghiscoding and artechventure committed Nov 19, 2022
1 parent 267fced commit 03e8157
Show file tree
Hide file tree
Showing 17 changed files with 392 additions and 9 deletions.
8 changes: 8 additions & 0 deletions __fixtures__/normal-publish-config/lerna.json
@@ -0,0 +1,8 @@
{
"version": "1.0.0",
"command": {
"publish": {
"publishConfigOverrides": true
}
}
}
3 changes: 3 additions & 0 deletions __fixtures__/normal-publish-config/package.json
@@ -0,0 +1,3 @@
{
"name": "normal"
}
11 changes: 11 additions & 0 deletions __fixtures__/normal-publish-config/packages/package-1/package.json
@@ -0,0 +1,11 @@
{
"name": "package-1",
"version": "1.0.0",
"main": "./src/index.ts",
"typings": "./src/index.d.ts",
"publishConfig": {
"main": "dist/index.js",
"typings": "dist/index.d.ts",
"access": "public"
}
}
25 changes: 25 additions & 0 deletions __fixtures__/normal-publish-config/packages/package-2/package.json
@@ -0,0 +1,25 @@
{
"name": "package-2",
"version": "1.0.0",
"dependencies": {
"package-1": "^1.0.0"
},
"typesVersions": {
"*": {
"*": ["origin"]
}
},
"publishConfig": {
"bin": "./build/bin.js",
"browser": "./build/browser.js",
"module": "./build/index.mjs",
"exports": {
"package-b": "dist/package-b.js"
},
"typesVersions": {
"*": {
"*": ["overriden"]
}
}
}
}
10 changes: 10 additions & 0 deletions __fixtures__/normal-publish-config/packages/package-3/package.json
@@ -0,0 +1,10 @@
{
"name": "package-3",
"version": "1.0.0",
"peerDependencies": {
"package-2": "^1.0.0"
},
"devDependencies": {
"package-2": "^1.0.0"
}
}
7 changes: 7 additions & 0 deletions packages/cli/schemas/lerna-schema.json
Expand Up @@ -364,6 +364,9 @@
"otp": {
"$ref": "#/$defs/commandOptions/publish/otp"
},
"publishConfigOverrides": {
"$ref": "#/$defs/commandOptions/publish/publishConfigOverrides"
},
"registry": {
"$ref": "#/$defs/commandOptions/shared/registry"
},
Expand Down Expand Up @@ -1231,6 +1234,10 @@
"type": "string",
"description": "During `lerna publish`, supply a one-time password for publishing with two-factor authentication."
},
"publishConfigOverrides": {
"type": "boolean",
"description": "apply publishConfig overrides."
},
"removePackageFields": {
"type": "array",
"items": {
Expand Down
9 changes: 9 additions & 0 deletions packages/cli/src/cli-commands/cli-publish-commands.ts
Expand Up @@ -86,6 +86,15 @@ export default {
type: 'string',
requiresArg: true,
},
'no-publish-config-overrides': {
// proxy for --publish-config-overrides
hidden: true,
type: 'boolean',
},
'publish-config-overrides': {
describe: 'apply publishConfig overrides.',
type: 'boolean',
},
registry: {
describe: 'Use the specified registry for all npm client operations.',
type: 'string',
Expand Down
9 changes: 2 additions & 7 deletions packages/cli/src/lerna-entry.ts
@@ -1,5 +1,6 @@
import loadJsonFile from 'load-json-file';
import path from 'path';
import { JsonValue } from '@lerna-lite/core';

import changedCmd from './cli-commands/cli-changed-commands';
import diffCmd from './cli-commands/cli-diff-commands';
Expand All @@ -12,14 +13,8 @@ import runCmd from './cli-commands/cli-run-commands';
import versionCmd from './cli-commands/cli-version-commands';
import cli from './lerna-cli';

interface JsonValue {
[dep: string]: string | number;
}

export function lerna(argv: any[]) {
const cliPkg = loadJsonFile.sync<{ [dep: string]: string | Array<JsonValue> }>(
path.join(__dirname, '../', 'package.json')
);
const cliPkg = loadJsonFile.sync<{ [dep: string]: JsonValue }>(path.join(__dirname, '../', 'package.json'));
const context = {
lernaVersion: (cliPkg?.version ?? '') as string,
};
Expand Down
3 changes: 3 additions & 0 deletions packages/core/src/models/command-options.ts
Expand Up @@ -143,6 +143,9 @@ export interface PublishCommandOption extends VersionCommandOption {
/** Supply a one-time password for publishing with two-factor authentication. */
otp?: string;

/** apply publishConfig overrides. */
publishConfigOverrides?: boolean;

/** Use the specified registry for all npm client operations. */
registry?: string;

Expand Down
5 changes: 5 additions & 0 deletions packages/core/src/models/interfaces.ts
Expand Up @@ -7,6 +7,11 @@ import npa from 'npm-package-arg';
import { Package } from '../package';
import { InitCommandOption, PublishCommandOption, RunCommandOption, VersionCommandOption } from './command-options';

export type JsonObject = { [Key in string]: JsonValue } & { [Key in string]?: JsonValue | undefined };
export type JsonArray = JsonValue[];
export type JsonPrimitive = string | number | boolean | null;
export type JsonValue = JsonPrimitive | JsonObject | JsonArray;

export type VersioningStrategy = 'fixed' | 'independent';
export type ChangelogType = 'fixed' | 'independent' | 'root';
export type ChangelogPresetConfig = string | { name: string; [key: string]: unknown };
Expand Down
5 changes: 5 additions & 0 deletions packages/core/src/package.ts
Expand Up @@ -127,6 +127,11 @@ export class Package {
return path.join(this.location, 'node_modules', '.bin');
}

/** alias to pkg getter (to avoid calling duplicate prop like `node.pkg.pkg` in which node is PackageGraphNode) */
get manifest(): RawManifest {
return this[PKG];
}

get manifestLocation(): string {
return path.join(this.location, 'package.json');
}
Expand Down
24 changes: 23 additions & 1 deletion packages/core/src/utils/__tests__/object-utils.spec.ts
@@ -1,7 +1,7 @@
import cloneDeep from 'clone-deep';
import npmlog from 'npmlog';

import { deleteComplexObjectProp, getComplexObjectValue } from '../object-utils';
import { deleteComplexObjectProp, getComplexObjectValue, isEmpty } from '../object-utils';

describe('deleteComplexObjectProp method', () => {
let obj = {};
Expand Down Expand Up @@ -77,3 +77,25 @@ describe('getComplexObjectValue method', () => {
expect(output).toEqual('Broadway');
});
});

describe('isEmpty method', () => {
it('should return true when input is an empty object', () => {
const output = isEmpty({});
expect(output).toBe(true);
});

it('should return true when input is null', () => {
const output = isEmpty(null as any);
expect(output).toBe(true);
});

it('should return true when input is undefined', () => {
const output = isEmpty(undefined as any);
expect(output).toBe(true);
});

it('should return false when input has at least one property', () => {
const output = isEmpty({ hello: 'world' });
expect(output).toBe(false);
});
});
8 changes: 8 additions & 0 deletions packages/core/src/utils/object-utils.ts
Expand Up @@ -37,3 +37,11 @@ export function getComplexObjectValue<T>(object: any, path: string): T {
}
return path.split('.').reduce((obj, prop) => obj?.[prop], object);
}

/**
* Check if an object is empty
* @returns {Boolean}
*/
export function isEmpty(obj: object) {
return !obj || Object.keys(obj).length === 0;
}
33 changes: 33 additions & 0 deletions packages/publish/README.md
Expand Up @@ -91,6 +91,7 @@ This is useful when a previous `lerna publish` failed to publish all packages to
- [`--temp-tag`](#--temp-tag)
- [`--verify-access`](#--verify-access)
- [`--yes`](#--yes)
- [`publishConfig` Overrides](#publishconfig-overrides)
- [`workspace:` protocol](#workspace-protocol)
- [`--workspace-strict-match (default)`](#with---workspace-strict-match-default)
- [`--no-workspace-strict-match`](#with---no-workspace-strict-match-deprecated)
Expand Down Expand Up @@ -423,6 +424,38 @@ This _non-standard_ field allows you to customize the published subdirectory jus
}
```

## `publishConfig` Overrides
Certain fields defined in `publishConfig` can be used to override other fields in the manifest before the package gets published. As per pnpm [`publishConfig`](https://pnpm.io/package_json#publishconfig) documentation, you can override any of these fields:

- `bin`, `browser`, `cpu`, `esnext`, `es2015`, `exports`, `imports`, `libc`, `main`, `module`, `os`, `type`, `types`, `typings`, `typesVersions`, `umd:main`, `unpkg`

> **Note** this option is enabled by default but can be disabled bia `lerna publish --no-publish-config-overrides` or (`"publishConfigOverrides": false` in `lerna.json`)
For instance, the following package.json:

```json
{
"name": "foo",
"version": "1.0.0",
"main": "src/index.ts",
"publishConfig": {
"main": "lib/index.js",
"typings": "lib/index.d.ts"
}
}
```

Will be published as:

```json
{
"name": "foo",
"version": "1.0.0",
"main": "lib/index.js",
"typings": "lib/index.d.ts"
}
```

<a id="lifecycle-events"><!-- back-compat with previous heading --></a>

## Lifecycle Scripts
Expand Down

0 comments on commit 03e8157

Please sign in to comment.