monocrate 0.5.0 → 0.6.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 (2) hide show
  1. package/README.md +72 -149
  2. package/package.json +1 -1
package/README.md CHANGED
@@ -1,193 +1,116 @@
1
1
  # Monocrate
2
2
 
3
- > From monorepo to npm in one command
3
+ From monorepo to npm in one command.
4
4
 
5
- Monocrate bundles monorepo packages for npm publishing by automatically resolving in-repo dependencies, copying compiled code, and generating a unified package.json with all third-party dependencies merged.
5
+ ## Why
6
6
 
7
- ## The Problem
7
+ Publishing from a monorepo breaks when your package depends on internal packages. npm doesn't understand workspace references like `@myorg/utils`. You're forced to either publish every internal package separately, manually copy and merge files, or bundle everything into a single file (losing module structure and type declarations).
8
8
 
9
- Publishing a package from a monorepo to npm is surprisingly painful. Your package might depend on other internal packages (like `@myorg/utils` or `@myorg/core`), but npm doesn't understand workspace dependencies. You end up with one of these bad options:
9
+ Monocrate gives you:
10
10
 
11
- 1. **Publish everything** - Every internal dependency must be published separately, even if they're implementation details
12
- 2. **Manual bundling** - Copy files, manually merge package.json dependencies, hope you didn't miss anything
13
- 3. **Complex build pipelines** - Esbuild/Rollup/Webpack configurations that bundle everything into a single file, losing the module structure
11
+ - **One command** point at your package, done
12
+ - **Self-contained output** internal dependencies are included, nothing else to publish
13
+ - **Preserved module structure** no flattening into a single file, tree-shaking works
14
+ - **Type declarations included** — `.d.ts` files just work
15
+ - **Open-source mirroring** — `--mirror-to` copies sources to a public repo alongside publishing
14
16
 
15
- ## The Solution
16
-
17
- Monocrate takes a different approach: it bundles your package and all its in-repo dependencies into a single publishable directory, preserving the original module structure. Third-party dependencies are collected from all packages and merged into a single package.json.
18
-
19
- ```
20
- monorepo/
21
- packages/
22
- app/ <-- You want to publish this
23
- utils/ <-- app depends on this
24
- core/ <-- utils depends on this
25
-
26
- $ monocrate bundle @myorg/app --output ./publish
27
-
28
- publish/
29
- index.js <-- app's compiled code
30
- _deps/
31
- _myorg_utils/ <-- utils' compiled code
32
- _myorg_core/ <-- core's compiled code
33
- package.json <-- Merged dependencies from all packages
34
- ```
35
-
36
- ## Installation
17
+ ## Install
37
18
 
38
19
  ```bash
39
20
  npm install -g monocrate
40
21
  ```
41
22
 
42
- Or use without installing:
23
+ ## Usage
43
24
 
44
25
  ```bash
45
- npx monocrate bundle my-package --output ./publish
26
+ # Prepare for inspection without publishing
27
+ monocrate prepare packages/my-app
28
+
29
+ # Publish directly to npm
30
+ monocrate publish packages/my-app --bump patch
46
31
  ```
47
32
 
48
- ## Quick Start
33
+ ### Commands
49
34
 
50
- **1. Build your packages**
35
+ **`prepare <packages...>`** — Assemble packages but don't publish. Useful for inspecting output or manual publishing.
51
36
 
52
- ```bash
53
- # Ensure all packages have been compiled to their dist/ directories
54
- npm run build --workspaces
55
- ```
37
+ **`publish <packages...>`** — Assemble and publish to npm.
56
38
 
57
- **2. Bundle for publishing**
39
+ ### Options
58
40
 
59
- ```bash
60
- monocrate bundle @myorg/app --output ./publish
61
- ```
41
+ | Flag | Description |
42
+ |------|-------------|
43
+ | `-b, --bump` | Version bump: `patch`, `minor`, `major`, or explicit version like `1.2.3`. Defaults to `minor`. |
44
+ | `-o, --output` | Output directory. Defaults to a temp directory. |
45
+ | `-r, --root` | Monorepo root. Auto-detected if omitted. |
46
+ | `-m, --mirror-to` | Mirror source files to another directory (for open-source mirrors). |
47
+ | `--report` | Write the resolved version to a file instead of stdout. |
62
48
 
63
- **3. Publish to npm**
49
+ ### Examples
64
50
 
65
51
  ```bash
66
- cd publish && npm publish
67
- ```
68
-
69
- ## Programmatic API
52
+ # Bump patch version and publish
53
+ monocrate publish packages/cli --bump patch
70
54
 
71
- Monocrate can be used as a library in your build scripts:
55
+ # Publish multiple packages with synchronized versions
56
+ monocrate publish packages/core packages/cli
72
57
 
73
- ```typescript
74
- import { bundle } from 'monocrate';
75
-
76
- const result = await bundle({
77
- packagePath: '/path/to/monorepo/packages/my-app',
78
- monorepoRoot: '/path/to/monorepo',
79
- outputDir: '/tmp/my-app-bundle',
80
- });
58
+ # Prepare to a specific directory for inspection
59
+ monocrate prepare packages/app --output ./publish-staging
81
60
 
82
- if (result.success) {
83
- console.log('Bundle created at:', result.outputPath);
84
- console.log('Included packages:', result.includedPackages);
85
- console.log('Dependencies:', result.mergedDependencies);
86
- } else {
87
- console.error('Bundle failed:', result.error);
88
- console.error('Details:', result.details);
89
- }
61
+ # Mirror sources to a public repo after publishing
62
+ monocrate publish packages/sdk --mirror-to ../public-repo/packages
90
63
  ```
91
64
 
92
- ### Convenience Function
65
+ ## How It Works
93
66
 
94
- For simpler use cases when running from the monorepo root:
67
+ 1. Discovers all packages in the monorepo via workspace configuration
68
+ 2. Builds a dependency graph starting from your target package
69
+ 3. Copies each package's `dist/` directory to the output
70
+ 4. Rewrites import statements from package names to relative paths
71
+ 5. Generates a `package.json` with merged third-party dependencies
95
72
 
96
- ```typescript
97
- import { bundlePackage } from 'monocrate';
73
+ ### Output Structure
98
74
 
99
- // Automatically discovers packages from workspace configuration
100
- const result = await bundlePackage('@myorg/app', '/tmp/bundle');
101
75
  ```
102
-
103
- ## Configuration Options
104
-
105
- | Option | Type | Default | Description |
106
- |--------|------|---------|-------------|
107
- | `packagePath` | `string` | required | Absolute path to the package to bundle |
108
- | `monorepoRoot` | `string` | required | Absolute path to the monorepo root |
109
- | `outputDir` | `string` | required | Absolute path to the output directory |
110
- | `includeSourceMaps` | `boolean` | `true` | Include `.map` files in the bundle |
111
- | `includeDeclarations` | `boolean` | `true` | Include `.d.ts` files in the bundle |
112
- | `versionConflictStrategy` | `'highest' \| 'error' \| 'warn'` | `'warn'` | How to handle version conflicts |
113
- | `cleanOutputDir` | `boolean` | `true` | Remove existing output directory before bundling |
114
- | `distDirName` | `string` | `'dist'` | Name of the compiled output directory |
115
-
116
- ### Version Conflict Strategies
117
-
118
- When multiple packages depend on the same third-party package with different versions:
119
-
120
- - **`'highest'`** - Silently use the highest semver-compatible version
121
- - **`'warn'`** - Use highest version, but log a warning
122
- - **`'error'`** - Fail the bundle operation
123
-
124
- ```typescript
125
- const result = await bundle({
126
- // ...
127
- versionConflictStrategy: 'error', // Strict mode
128
- });
76
+ monorepo/
77
+ packages/
78
+ app/ ← you want to publish this
79
+ utils/ ← app depends on this
80
+ core/ ← utils depends on this
81
+
82
+ output/
83
+ package.json ← merged deps, in-repo refs removed
84
+ dist/ ← app's compiled code
85
+ deps/
86
+ packages/
87
+ utils/dist/ utils' compiled code (imports rewritten)
88
+ core/dist/ ← core's compiled code (imports rewritten)
129
89
  ```
130
90
 
131
- ## How It Works
132
-
133
- 1. **Discover packages** - Reads workspace configuration (npm, yarn, or pnpm) to find all packages in the monorepo
134
-
135
- 2. **Build dependency graph** - Starting from your target package, recursively finds all in-repo dependencies and builds a topologically-sorted graph
136
-
137
- 3. **Validate builds** - Ensures all packages have been compiled (have a `dist/` directory)
138
-
139
- 4. **Assemble bundle** - Copies compiled code:
140
- - Root package's `dist/` goes to output root
141
- - Dependencies' `dist/` go to `_deps/<package-name>/`
142
-
143
- 5. **Transform package.json** - Generates a publish-ready package.json:
144
- - Removes workspace-specific fields (`workspaces`, `private`, `devDependencies`)
145
- - Removes in-repo dependencies
146
- - Merges third-party dependencies from all included packages
147
-
148
- ## Bundle Result
149
-
150
- The `bundle()` function returns a discriminated union:
151
-
152
- ```typescript
153
- // Success
154
- {
155
- success: true,
156
- outputPath: string, // Path to the bundle
157
- packageJson: PackageJson, // Generated package.json
158
- mergedDependencies: object, // All third-party deps
159
- includedPackages: string[], // List of bundled packages
160
- versionConflicts: VersionConflict[], // Any conflicts found
161
- }
162
-
163
- // Failure
164
- {
165
- success: false,
166
- error: string, // Error message
167
- details?: string, // Additional context
168
- cause?: Error, // Underlying error
169
- }
170
- ```
91
+ Entry points (`main`, `types`, `exports`) work unchanged because the `dist/` directory stays in the same relative position.
171
92
 
172
93
  ## Requirements
173
94
 
174
- - **Node.js 20+**
175
- - **Built packages** - All packages must have a `dist/` directory with compiled code
176
- - **Workspace configuration** - npm workspaces, yarn workspaces, or pnpm-workspace.yaml
95
+ - Node.js 20+
96
+ - All packages must be compiled (have a `dist/` directory)
97
+ - Monorepo must use npm, yarn, or pnpm workspaces
177
98
 
178
- ## Supported Package Managers
179
-
180
- Monocrate automatically detects your package manager from:
99
+ ## Programmatic API
181
100
 
182
- - `pnpm-workspace.yaml`
183
- - `workspaces` field in root `package.json`
184
- - Lock files (`pnpm-lock.yaml`, `yarn.lock`, `package-lock.json`)
101
+ ```typescript
102
+ import { monocrate } from 'monocrate';
185
103
 
186
- ## Documentation
104
+ const result = await monocrate({
105
+ pathToSubjectPackages: ['packages/my-app'],
106
+ cwd: process.cwd(),
107
+ publish: false,
108
+ bump: 'minor',
109
+ });
187
110
 
188
- - [API Reference](./docs/api.md) - Complete programmatic API documentation
189
- - [How It Works](./docs/how-it-works.md) - Deep dive into the bundling process
190
- - [Troubleshooting](./docs/troubleshooting.md) - Common errors and solutions
111
+ console.log(result.resolvedVersion); // "1.3.0"
112
+ console.log(result.outputDir); // "/tmp/monocrate-xyz/my-app"
113
+ ```
191
114
 
192
115
  ## License
193
116
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "monocrate",
3
- "version": "0.5.0",
3
+ "version": "0.6.0",
4
4
  "description": "From monorepo to npm in one command",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",