prepare-package 2.0.0 → 2.0.1

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/CLAUDE.md CHANGED
@@ -15,14 +15,23 @@ src/
15
15
  index.js # Main entry: resolves config, branches copy vs bundle, safety checks, CDN purge
16
16
  build.js # Esbuild config generator, version plugin, build() and createWatchContexts()
17
17
  watch.js # Watch mode: chokidar for copy, esbuild contexts for bundle
18
+ cli.js # Interactive CLI for project setup (npx pp / npx prepare-package)
18
19
  logger.js # Timestamped console logger with chalk colors
19
20
  dist/ # Copy-mode output of src/ (prepare-package builds itself with copy mode)
20
21
  ```
21
22
 
23
+ ### CLI (`npx pp` / `npx prepare-package`)
24
+ Interactive setup wizard that configures a project's `package.json`:
25
+ 1. Asks **copy** or **bundle** mode
26
+ 2. Asks source/output directories (defaults: `src`/`dist`)
27
+ 3. If bundle: asks formats, auto-derives `globalName` (TitleCase of package name) and `fileName` (`{name}.min.js`)
28
+ 4. Writes `preparePackage` config and `prepare`/`prepare:watch` scripts to `package.json`
29
+
22
30
  ### How It Runs
23
31
  - **`prepare` script**: Runs on `npm install` and `npm publish` in the consumer's project
24
32
  - **`postinstall` script**: Runs when prepare-package itself is installed as a dependency. Skips bundle mode (esbuild may not be available yet during install)
25
33
  - **`prepare:watch` script**: Starts watch mode (chokidar for copy, esbuild `.watch()` for bundle)
34
+ - **`bin` commands**: `prepare-package` and `pp` both point to `cli.js`
26
35
 
27
36
  ### Consumer Configuration
28
37
  All config lives in `preparePackage` key in the consumer's `package.json`:
package/README.md CHANGED
@@ -29,6 +29,19 @@
29
29
  npm install prepare-package --save-dev
30
30
  ```
31
31
 
32
+ ## Quick Setup
33
+ Run the interactive CLI to configure your project:
34
+ ```shell
35
+ npx pp
36
+ ```
37
+
38
+ This will walk you through selecting a build type (**copy** or **bundle**), configuring formats, and auto-deriving IIFE settings (global name from package name in TitleCase, filename as `{name}.min.js`). The CLI writes the `preparePackage` config and scripts directly to your `package.json`.
39
+
40
+ You can also use the full name:
41
+ ```shell
42
+ npx prepare-package
43
+ ```
44
+
32
45
  ## Features
33
46
  * Two modes: **copy** (default) and **bundle** (esbuild)
34
47
  * Copy mode: copies `src/` to `dist/`, replaces `{version}` in main file
package/dist/build.js CHANGED
@@ -1,7 +1,7 @@
1
1
  const path = require('path');
2
2
  const fs = require('fs');
3
3
  const logger = require('./logger');
4
- const chalk = require('chalk');
4
+ const { default: chalk } = require('chalk');
5
5
 
6
6
  /**
7
7
  * Build using esbuild based on preparePackage config
package/dist/cli.js ADDED
@@ -0,0 +1,127 @@
1
+ #!/usr/bin/env node
2
+
3
+ const fs = require('fs');
4
+ const path = require('path');
5
+ const readline = require('readline');
6
+ const { default: chalk } = require('chalk');
7
+ const logger = require('./logger');
8
+
9
+ const rl = readline.createInterface({
10
+ input: process.stdin,
11
+ output: process.stdout,
12
+ });
13
+
14
+ function ask(question, defaultValue) {
15
+ const suffix = defaultValue ? ` (${chalk.cyan(defaultValue)})` : '';
16
+ return new Promise((resolve) => {
17
+ rl.question(`${question}${suffix}: `, (answer) => {
18
+ resolve(answer.trim() || defaultValue || '');
19
+ });
20
+ });
21
+ }
22
+
23
+ function askChoice(question, choices, defaultIndex) {
24
+ console.log(`\n${question}`);
25
+ choices.forEach((choice, i) => {
26
+ const marker = i === defaultIndex ? chalk.green('❯') : ' ';
27
+ console.log(` ${marker} ${i + 1}) ${choice}`);
28
+ });
29
+
30
+ return new Promise((resolve) => {
31
+ rl.question(`Choice (${defaultIndex + 1}): `, (answer) => {
32
+ const index = parseInt(answer, 10) - 1;
33
+ resolve(choices[Number.isNaN(index) || index < 0 || index >= choices.length ? defaultIndex : index]);
34
+ });
35
+ });
36
+ }
37
+
38
+ function toTitleCase(name) {
39
+ return name
40
+ .replace(/[-_@/]/g, ' ')
41
+ .replace(/\s+/g, ' ')
42
+ .trim()
43
+ .split(' ')
44
+ .map(word => word.charAt(0).toUpperCase() + word.slice(1))
45
+ .join('');
46
+ }
47
+
48
+ async function init() {
49
+ const cwd = process.cwd();
50
+ const pkgPath = path.resolve(cwd, 'package.json');
51
+
52
+ if (!fs.existsSync(pkgPath)) {
53
+ logger.error('No package.json found in current directory. Run `npm init` first.');
54
+ process.exit(1);
55
+ }
56
+
57
+ const pkg = JSON.parse(fs.readFileSync(pkgPath, 'utf8'));
58
+
59
+ console.log(chalk.bold(`\n prepare-package init\n`));
60
+ console.log(` Setting up ${chalk.cyan(pkg.name || 'your package')}...\n`);
61
+
62
+ // Ask type
63
+ const type = await askChoice('Build type:', ['copy', 'bundle'], 0);
64
+
65
+ // Ask input/output
66
+ const input = await ask('Source directory', 'src');
67
+ const output = await ask('Output directory', 'dist');
68
+
69
+ // Build preparePackage config
70
+ const config = {
71
+ input,
72
+ output,
73
+ type,
74
+ };
75
+
76
+ // Bundle-specific config
77
+ if (type === 'bundle') {
78
+ const defaultGlobal = toTitleCase(pkg.name || 'MyLib');
79
+ const defaultFileName = `${(pkg.name || 'my-lib').replace(/@.*\//, '')}.min.js`;
80
+
81
+ const formatsRaw = await ask('Formats (comma-separated)', 'esm, cjs, iife');
82
+ const formats = formatsRaw.split(',').map(f => f.trim()).filter(Boolean);
83
+
84
+ config.build = { formats };
85
+
86
+ if (formats.includes('iife')) {
87
+ const globalName = await ask('IIFE global name', defaultGlobal);
88
+ const fileName = await ask('IIFE filename', defaultFileName);
89
+
90
+ config.build.iife = { globalName, fileName };
91
+ }
92
+ }
93
+
94
+ // Update package.json
95
+ pkg.preparePackage = config;
96
+ pkg.main = pkg.main || `./${output}/index.js`;
97
+
98
+ if (type === 'bundle') {
99
+ pkg.module = pkg.module || `./${output}/index.mjs`;
100
+ pkg.exports = pkg.exports || {
101
+ '.': {
102
+ import: `./${output}/index.mjs`,
103
+ require: `./${output}/index.js`,
104
+ },
105
+ };
106
+ }
107
+
108
+ // Add scripts
109
+ pkg.scripts = pkg.scripts || {};
110
+ pkg.scripts.prepare = `node -e "require('prepare-package')()"`;
111
+ pkg.scripts['prepare:watch'] = `node -e "require('prepare-package/watch')()"`;
112
+
113
+ // Write
114
+ fs.writeFileSync(pkgPath, `${JSON.stringify(pkg, null, 2)}\n`);
115
+
116
+ console.log(`\n${chalk.green('Done!')} Updated package.json:\n`);
117
+ console.log(chalk.gray(JSON.stringify({ preparePackage: config }, null, 2)));
118
+ console.log(`\nRun ${chalk.cyan('npm run prepare')} to build.\n`);
119
+
120
+ rl.close();
121
+ }
122
+
123
+ init().catch((err) => {
124
+ logger.error(err.message);
125
+ rl.close();
126
+ process.exit(1);
127
+ });
package/dist/index.js CHANGED
@@ -1,7 +1,7 @@
1
1
  const jetpack = require('fs-jetpack');
2
2
  const fetch = require('wonderful-fetch');
3
3
  const path = require('path');
4
- const chalk = require('chalk');
4
+ const { default: chalk } = require('chalk');
5
5
  const logger = require('./logger');
6
6
 
7
7
  // const argv = require('yargs').argv;
package/dist/logger.js CHANGED
@@ -1,4 +1,4 @@
1
- const chalk = require('chalk');
1
+ const { default: chalk } = require('chalk');
2
2
 
3
3
  // Setup logger
4
4
  const logger = {};
package/package.json CHANGED
@@ -1,15 +1,19 @@
1
1
  {
2
2
  "name": "prepare-package",
3
- "version": "2.0.0",
3
+ "version": "2.0.1",
4
4
  "description": "Prepare a Node.js package before being published",
5
5
  "main": "dist/index.js",
6
+ "bin": {
7
+ "prepare-package": "./dist/cli.js",
8
+ "pp": "./dist/cli.js"
9
+ },
6
10
  "exports": {
7
11
  ".": "./dist/index.js",
8
12
  "./watch": "./dist/watch.js"
9
13
  },
10
14
  "scripts": {
11
15
  "test": "./node_modules/mocha/bin/mocha test/ --recursive --timeout=10000",
12
- "start": "node -e \"require('./src/index.js')()\"",
16
+ "start": "npm run prepare:watch",
13
17
  "prepare": "node -e \"require('./src/index.js')()\"",
14
18
  "prepare:watch": "node -e \"require('./src/watch.js')()\"",
15
19
  "postinstall": "node -e \"require('./dist/index.js')({cwd: process.env.INIT_CWD, isPostInstall: true})\""
@@ -39,13 +43,13 @@
39
43
  "replace": {}
40
44
  },
41
45
  "dependencies": {
42
- "chalk": "^4.1.2",
43
- "chokidar": "^4.0.3",
44
- "esbuild": "^0.27.3",
46
+ "chalk": "^5.6.2",
47
+ "chokidar": "^5.0.0",
48
+ "esbuild": "^0.27.4",
45
49
  "fs-jetpack": "^5.1.0",
46
50
  "wonderful-fetch": "^1.3.4"
47
51
  },
48
52
  "devDependencies": {
49
- "mocha": "^8.4.0"
53
+ "mocha": "^11.7.5"
50
54
  }
51
55
  }