@jmlweb/tsup-config-base 1.0.1 → 1.1.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.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,11 @@
1
1
  # @jmlweb/tsup-config-base
2
2
 
3
+ ## 1.1.0
4
+
5
+ ### Minor Changes
6
+
7
+ - 41b71c1: Add CLI preset with shebang support via createTsupCliConfig function
8
+
3
9
  ## 1.0.1
4
10
 
5
11
  ### Patch Changes
package/README.md CHANGED
@@ -7,22 +7,23 @@
7
7
 
8
8
  > Base tsup configuration for jmlweb projects. Provides sensible defaults and a clean API for creating consistent build configurations.
9
9
 
10
- ## Features
10
+ ## Features
11
11
 
12
- - **Sensible Defaults**: Pre-configured with common settings for TypeScript libraries
13
- - **Dual Format**: Generates both CommonJS and ESM outputs by default
14
- - **TypeScript Declarations**: Automatic `.d.ts` generation enabled
15
- - **Clean API**: Simple function to create configurations with external dependencies
16
- - **Zero Config**: Works out of the box with minimal setup
17
- - **Fully Typed**: Complete TypeScript support with exported types
12
+ - 🎯 **Sensible Defaults**: Pre-configured with common settings for TypeScript libraries
13
+ - 📦 **Dual Format**: Generates both CommonJS and ESM outputs by default
14
+ - 📝 **TypeScript Declarations**: Automatic `.d.ts` generation enabled
15
+ - 🔧 **Clean API**: Simple function to create configurations with external dependencies
16
+ - **Zero Config**: Works out of the box with minimal setup
17
+ - 🛠️ **Fully Typed**: Complete TypeScript support with exported types
18
+ - 🖥️ **CLI Preset**: Specialized configuration for CLI packages with shebang support
18
19
 
19
- ## Installation
20
+ ## 📦 Installation
20
21
 
21
22
  ```bash
22
23
  npm install --save-dev @jmlweb/tsup-config-base tsup
23
24
  ```
24
25
 
25
- ## Quick Start
26
+ ## 🚀 Quick Start
26
27
 
27
28
  Create a `tsup.config.ts` file in your project root:
28
29
 
@@ -32,7 +33,7 @@ import { createTsupConfig } from '@jmlweb/tsup-config-base';
32
33
  export default createTsupConfig();
33
34
  ```
34
35
 
35
- ## Examples
36
+ ## 💡 Examples
36
37
 
37
38
  ### Basic Setup (No Externals)
38
39
 
@@ -113,7 +114,61 @@ export default createTsupConfig({
113
114
  });
114
115
  ```
115
116
 
116
- ## Configuration Details
117
+ ### Object-Style Entry Points
118
+
119
+ ```typescript
120
+ // tsup.config.ts
121
+ import { createTsupConfig } from '@jmlweb/tsup-config-base';
122
+
123
+ export default createTsupConfig({
124
+ entry: {
125
+ index: 'src/index.ts',
126
+ utils: 'src/utils/index.ts',
127
+ },
128
+ });
129
+ ```
130
+
131
+ ### CLI Package Configuration
132
+
133
+ For CLI packages that need shebang injection, use `createTsupCliConfig`:
134
+
135
+ ```typescript
136
+ // tsup.config.ts
137
+ import { createTsupCliConfig } from '@jmlweb/tsup-config-base';
138
+
139
+ export default createTsupCliConfig();
140
+ // Output: dist/cli.js with #!/usr/bin/env node shebang
141
+ ```
142
+
143
+ ### CLI with Custom Entry
144
+
145
+ ```typescript
146
+ // tsup.config.ts
147
+ import { createTsupCliConfig } from '@jmlweb/tsup-config-base';
148
+
149
+ export default createTsupCliConfig({
150
+ entry: { bin: 'src/bin.ts' },
151
+ external: ['commander'],
152
+ });
153
+ ```
154
+
155
+ ### CLI with Library API
156
+
157
+ ```typescript
158
+ // tsup.config.ts
159
+ import { createTsupCliConfig } from '@jmlweb/tsup-config-base';
160
+
161
+ export default createTsupCliConfig({
162
+ entry: {
163
+ cli: 'src/cli.ts',
164
+ index: 'src/index.ts',
165
+ },
166
+ shebang: 'cli', // Only add shebang to cli entry
167
+ external: ['commander'],
168
+ });
169
+ ```
170
+
171
+ ## 📋 Configuration Details
117
172
 
118
173
  ### Default Settings
119
174
 
@@ -130,41 +185,101 @@ export default createTsupConfig({
130
185
 
131
186
  #### `createTsupConfig(options?: TsupConfigOptions): Options`
132
187
 
133
- Creates a tsup configuration with sensible defaults.
188
+ Creates a tsup configuration with sensible defaults for library packages.
134
189
 
135
190
  **Parameters:**
136
191
 
137
- | Option | Type | Default | Description |
138
- | ---------- | ------------------------------ | ------------------ | -------------------------------- |
139
- | `entry` | `string[]` | `['src/index.ts']` | Entry point files |
140
- | `format` | `('cjs' \| 'esm' \| 'iife')[]` | `['cjs', 'esm']` | Output formats |
141
- | `dts` | `boolean` | `true` | Generate declaration files |
142
- | `clean` | `boolean` | `true` | Clean output before build |
143
- | `outDir` | `string` | `'dist'` | Output directory |
144
- | `external` | `(string \| RegExp)[]` | `[]` | Packages to exclude from bundle |
145
- | `options` | `Partial<Options>` | `{}` | Additional tsup options to merge |
192
+ | Option | Type | Default | Description |
193
+ | ---------- | ------------------------------------ | ------------------ | -------------------------------- |
194
+ | `entry` | `string[] \| Record<string, string>` | `['src/index.ts']` | Entry point files |
195
+ | `format` | `('cjs' \| 'esm' \| 'iife')[]` | `['cjs', 'esm']` | Output formats |
196
+ | `dts` | `boolean` | `true` | Generate declaration files |
197
+ | `clean` | `boolean` | `true` | Clean output before build |
198
+ | `outDir` | `string` | `'dist'` | Output directory |
199
+ | `external` | `(string \| RegExp)[]` | `[]` | Packages to exclude from bundle |
200
+ | `options` | `Partial<Options>` | `{}` | Additional tsup options to merge |
146
201
 
147
202
  **Returns:** A complete tsup `Options` object.
148
203
 
149
- #### `BASE_DEFAULTS`
204
+ #### `createTsupCliConfig(options?: TsupCliConfigOptions): Options | Options[]`
205
+
206
+ Creates a CLI-specific tsup configuration with shebang support.
207
+
208
+ **Parameters:**
209
+
210
+ | Option | Type | Default | Description |
211
+ | ---------- | ------------------------------------ | ----------------------- | ------------------------------------------- |
212
+ | `entry` | `string[] \| Record<string, string>` | `{ cli: 'src/cli.ts' }` | Entry point files |
213
+ | `format` | `('cjs' \| 'esm' \| 'iife')[]` | `['esm']` | Output formats (ESM only by default) |
214
+ | `dts` | `boolean` | `true` | Generate declaration files |
215
+ | `clean` | `boolean` | `true` | Clean output before build |
216
+ | `outDir` | `string` | `'dist'` | Output directory |
217
+ | `external` | `(string \| RegExp)[]` | `[]` | Packages to exclude from bundle |
218
+ | `target` | `NodeTarget` | `'node18'` | Node.js target version |
219
+ | `shebang` | `boolean \| string \| string[]` | `true` | Add shebang to entries (true = all entries) |
220
+ | `options` | `Partial<Options>` | `{}` | Additional tsup options to merge |
150
221
 
151
- Exported constant containing the default configuration values for reference.
222
+ **Returns:** A tsup `Options` object, or an array of `Options` when selective shebang is used.
152
223
 
153
- #### `Options` (re-exported from tsup)
224
+ #### Exported Constants
154
225
 
155
- The tsup Options type is re-exported for convenience when extending configurations.
226
+ - `BASE_DEFAULTS` - Default library configuration values
227
+ - `CLI_DEFAULTS` - Default CLI configuration values
228
+ - `Options` - Re-exported from tsup
156
229
 
157
- ## When to Use
230
+ #### Type Exports
231
+
232
+ - `EntryConfig` - Entry point configuration type (`string[] | Record<string, string>`)
233
+ - `NodeTarget` - Node.js target version type (`'node16' | 'node18' | 'node20' | 'node22' | ...`)
234
+ - `TsupConfigOptions` - Options for `createTsupConfig`
235
+ - `TsupCliConfigOptions` - Options for `createTsupCliConfig`
236
+
237
+ ## 🎯 When to Use
158
238
 
159
239
  Use this configuration when you want:
160
240
 
161
- - Consistent build configuration across multiple packages
162
- - Dual-format output (CommonJS + ESM) for maximum compatibility
163
- - Automatic TypeScript declaration generation
164
- - A clean, simple API for specifying externals
165
- - Easy customization without repeating boilerplate
241
+ - Consistent build configuration across multiple packages
242
+ - Dual-format output (CommonJS + ESM) for maximum compatibility
243
+ - Automatic TypeScript declaration generation
244
+ - A clean, simple API for specifying externals
245
+ - Easy customization without repeating boilerplate
246
+ - ✅ CLI packages with proper shebang injection
247
+
248
+ ## 🔧 Extending the Configuration
249
+
250
+ You can extend the configuration for your specific needs:
251
+
252
+ ### Adding Custom Options
253
+
254
+ ```typescript
255
+ // tsup.config.ts
256
+ import { createTsupConfig } from '@jmlweb/tsup-config-base';
257
+
258
+ export default createTsupConfig({
259
+ external: ['vitest'],
260
+ options: {
261
+ minify: true,
262
+ sourcemap: true,
263
+ splitting: true,
264
+ target: 'es2022',
265
+ },
266
+ });
267
+ ```
268
+
269
+ ### Overriding Defaults
270
+
271
+ ```typescript
272
+ // tsup.config.ts
273
+ import { createTsupConfig } from '@jmlweb/tsup-config-base';
274
+
275
+ export default createTsupConfig({
276
+ format: ['esm'], // ESM only
277
+ dts: false, // Disable type declarations
278
+ outDir: 'build', // Custom output directory
279
+ });
280
+ ```
166
281
 
167
- ## Externals Strategy
282
+ ### Externals Strategy
168
283
 
169
284
  When configuring `external`, include:
170
285
 
@@ -188,7 +303,7 @@ export default createTsupConfig({
188
303
  });
189
304
  ```
190
305
 
191
- ## Usage with Scripts
306
+ ## 📝 Usage with Scripts
192
307
 
193
308
  Add build scripts to your `package.json`:
194
309
 
@@ -209,24 +324,24 @@ npm run build # Build the package
209
324
  npm run clean # Clean build output
210
325
  ```
211
326
 
212
- ## Requirements
327
+ ## 📋 Requirements
213
328
 
214
329
  - **Node.js** >= 18.0.0
215
330
  - **tsup** >= 8.0.0
216
331
 
217
- ## Peer Dependencies
332
+ ## 📦 Peer Dependencies
218
333
 
219
334
  This package requires the following peer dependency:
220
335
 
221
336
  - `tsup` (>=8.0.0)
222
337
 
223
- ## Related Packages
338
+ ## 🔗 Related Packages
224
339
 
225
340
  - [`@jmlweb/eslint-config-base`](../eslint-config-base) - ESLint config for TypeScript projects
226
341
  - [`@jmlweb/prettier-config-base`](../prettier-config-base) - Prettier config for consistent formatting
227
342
  - [`@jmlweb/tsconfig-base`](../tsconfig-base) - TypeScript configuration
228
343
  - [`@jmlweb/vitest-config`](../vitest-config) - Vitest configuration for testing
229
344
 
230
- ## License
345
+ ## 📄 License
231
346
 
232
347
  MIT
package/dist/index.cjs CHANGED
@@ -21,6 +21,8 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
21
21
  var index_exports = {};
22
22
  __export(index_exports, {
23
23
  BASE_DEFAULTS: () => BASE_DEFAULTS,
24
+ CLI_DEFAULTS: () => CLI_DEFAULTS,
25
+ createTsupCliConfig: () => createTsupCliConfig,
24
26
  createTsupConfig: () => createTsupConfig
25
27
  });
26
28
  module.exports = __toCommonJS(index_exports);
@@ -31,6 +33,15 @@ var BASE_DEFAULTS = {
31
33
  clean: true,
32
34
  outDir: "dist"
33
35
  };
36
+ var CLI_DEFAULTS = {
37
+ entry: { cli: "src/cli.ts" },
38
+ format: ["esm"],
39
+ dts: true,
40
+ clean: true,
41
+ outDir: "dist",
42
+ target: "node18",
43
+ shebang: true
44
+ };
34
45
  var createTsupConfig = (config = {}) => {
35
46
  const {
36
47
  entry = BASE_DEFAULTS.entry,
@@ -51,8 +62,114 @@ var createTsupConfig = (config = {}) => {
51
62
  ...options
52
63
  };
53
64
  };
65
+ var SHEBANG = "#!/usr/bin/env node";
66
+ var createTsupCliConfig = (config = {}) => {
67
+ const {
68
+ entry = CLI_DEFAULTS.entry,
69
+ format = CLI_DEFAULTS.format,
70
+ dts = CLI_DEFAULTS.dts,
71
+ clean = CLI_DEFAULTS.clean,
72
+ outDir = CLI_DEFAULTS.outDir,
73
+ external = [],
74
+ target = CLI_DEFAULTS.target,
75
+ shebang = CLI_DEFAULTS.shebang,
76
+ options = {}
77
+ } = config;
78
+ const shebangEntries = normalizeShebangConfig(shebang);
79
+ if (shebangEntries === "all") {
80
+ return {
81
+ entry,
82
+ format,
83
+ dts,
84
+ clean,
85
+ outDir,
86
+ target,
87
+ banner: { js: SHEBANG },
88
+ ...external.length > 0 && { external },
89
+ ...options
90
+ };
91
+ }
92
+ if (shebangEntries.length === 0) {
93
+ return {
94
+ entry,
95
+ format,
96
+ dts,
97
+ clean,
98
+ outDir,
99
+ target,
100
+ ...external.length > 0 && { external },
101
+ ...options
102
+ };
103
+ }
104
+ const entryObject = normalizeEntry(entry);
105
+ const shebangSet = new Set(shebangEntries);
106
+ const withShebang = {};
107
+ const withoutShebang = {};
108
+ for (const [name, path] of Object.entries(entryObject)) {
109
+ if (shebangSet.has(name)) {
110
+ withShebang[name] = path;
111
+ } else {
112
+ withoutShebang[name] = path;
113
+ }
114
+ }
115
+ const configs = [];
116
+ if (Object.keys(withShebang).length > 0) {
117
+ configs.push({
118
+ entry: withShebang,
119
+ format,
120
+ dts,
121
+ clean,
122
+ outDir,
123
+ target,
124
+ banner: { js: SHEBANG },
125
+ ...external.length > 0 && { external },
126
+ ...options
127
+ });
128
+ }
129
+ if (Object.keys(withoutShebang).length > 0) {
130
+ configs.push({
131
+ entry: withoutShebang,
132
+ format,
133
+ dts,
134
+ // Only clean on first config
135
+ clean: configs.length === 0 ? clean : false,
136
+ outDir,
137
+ target,
138
+ ...external.length > 0 && { external },
139
+ ...options
140
+ });
141
+ }
142
+ return configs.length === 1 ? configs[0] : configs;
143
+ };
144
+ var normalizeEntry = (entry) => {
145
+ if (Array.isArray(entry)) {
146
+ return entry.reduce(
147
+ (acc, path) => {
148
+ const name = path.replace(/^.*\//, "").replace(/\.[^.]+$/, "");
149
+ acc[name] = path;
150
+ return acc;
151
+ },
152
+ {}
153
+ );
154
+ }
155
+ return entry;
156
+ };
157
+ var normalizeShebangConfig = (shebang) => {
158
+ if (shebang === true) {
159
+ return "all";
160
+ }
161
+ if (shebang === false) {
162
+ return [];
163
+ }
164
+ if (typeof shebang === "string") {
165
+ return [shebang];
166
+ }
167
+ return shebang;
168
+ };
54
169
  // Annotate the CommonJS export names for ESM import in node:
55
170
  0 && (module.exports = {
56
171
  BASE_DEFAULTS,
172
+ CLI_DEFAULTS,
173
+ createTsupCliConfig,
57
174
  createTsupConfig
58
175
  });
package/dist/index.d.cts CHANGED
@@ -1,15 +1,32 @@
1
1
  import { Options } from 'tsup';
2
2
  export { Options } from 'tsup';
3
3
 
4
+ /**
5
+ * Entry points configuration - can be an array of paths or an object mapping names to paths
6
+ */
7
+ type EntryConfig = string[] | Record<string, string>;
8
+ /**
9
+ * Node.js target version for CLI builds
10
+ */
11
+ type NodeTarget = 'node16' | 'node18' | 'node20' | 'node22' | `node${number}`;
4
12
  /**
5
13
  * Options for creating a base tsup configuration
6
14
  */
7
15
  interface TsupConfigOptions {
8
16
  /**
9
17
  * Entry points for the build
18
+ * Can be an array of paths or an object mapping output names to source paths
10
19
  * @default ['src/index.ts']
20
+ * @example
21
+ * ```typescript
22
+ * // Array format
23
+ * entry: ['src/index.ts', 'src/cli.ts']
24
+ *
25
+ * // Object format (named entries)
26
+ * entry: { index: 'src/index.ts', cli: 'src/cli.ts' }
27
+ * ```
11
28
  */
12
- entry?: string[];
29
+ entry?: EntryConfig;
13
30
  /**
14
31
  * Output formats
15
32
  * @default ['cjs', 'esm']
@@ -41,16 +58,102 @@ interface TsupConfigOptions {
41
58
  */
42
59
  options?: Omit<Options, 'entry' | 'format' | 'dts' | 'clean' | 'outDir' | 'external'>;
43
60
  }
61
+ /**
62
+ * Options for creating a CLI-specific tsup configuration
63
+ */
64
+ interface TsupCliConfigOptions {
65
+ /**
66
+ * Entry points for the build
67
+ * Can be an array of paths or an object mapping output names to source paths
68
+ * @default { cli: 'src/cli.ts' }
69
+ * @example
70
+ * ```typescript
71
+ * // Single CLI entry
72
+ * entry: { cli: 'src/cli.ts' }
73
+ *
74
+ * // CLI with library API
75
+ * entry: { cli: 'src/cli.ts', index: 'src/index.ts' }
76
+ *
77
+ * // Array format
78
+ * entry: ['src/cli.ts', 'src/index.ts']
79
+ * ```
80
+ */
81
+ entry?: EntryConfig;
82
+ /**
83
+ * Output formats
84
+ * @default ['esm']
85
+ */
86
+ format?: ('cjs' | 'esm' | 'iife')[];
87
+ /**
88
+ * Generate TypeScript declaration files
89
+ * @default true
90
+ */
91
+ dts?: boolean;
92
+ /**
93
+ * Clean output directory before build
94
+ * @default true
95
+ */
96
+ clean?: boolean;
97
+ /**
98
+ * Output directory
99
+ * @default 'dist'
100
+ */
101
+ outDir?: string;
102
+ /**
103
+ * External packages to exclude from the bundle
104
+ * @default []
105
+ */
106
+ external?: (string | RegExp)[];
107
+ /**
108
+ * Node.js target version for the build
109
+ * @default 'node18'
110
+ */
111
+ target?: NodeTarget;
112
+ /**
113
+ * Add shebang (#!/usr/bin/env node) to the output
114
+ * When true, adds shebang to all entry points
115
+ * When a string or array, only adds shebang to matching entry names
116
+ * @default true
117
+ * @example
118
+ * ```typescript
119
+ * // Add shebang to all entries
120
+ * shebang: true
121
+ *
122
+ * // Add shebang only to 'cli' entry
123
+ * shebang: 'cli'
124
+ *
125
+ * // Add shebang to specific entries
126
+ * shebang: ['cli', 'bin']
127
+ * ```
128
+ */
129
+ shebang?: boolean | string | string[];
130
+ /**
131
+ * Additional tsup options to merge with the base configuration
132
+ */
133
+ options?: Omit<Options, 'entry' | 'format' | 'dts' | 'clean' | 'outDir' | 'external' | 'target'>;
134
+ }
44
135
  /**
45
136
  * Base tsup configuration defaults used across all @jmlweb packages
46
137
  */
47
138
  declare const BASE_DEFAULTS: {
48
- entry: string[];
139
+ entry: EntryConfig;
49
140
  format: ("cjs" | "esm")[];
50
141
  dts: true;
51
142
  clean: true;
52
143
  outDir: string;
53
144
  };
145
+ /**
146
+ * CLI-specific tsup configuration defaults
147
+ */
148
+ declare const CLI_DEFAULTS: {
149
+ entry: EntryConfig;
150
+ format: ("esm")[];
151
+ dts: true;
152
+ clean: true;
153
+ outDir: string;
154
+ target: NodeTarget;
155
+ shebang: boolean | string | string[];
156
+ };
54
157
  /**
55
158
  * Creates a base tsup configuration with sensible defaults
56
159
  *
@@ -84,5 +187,42 @@ declare const BASE_DEFAULTS: {
84
187
  * ```
85
188
  */
86
189
  declare const createTsupConfig: (config?: TsupConfigOptions) => Options;
190
+ /**
191
+ * Creates a CLI-specific tsup configuration with shebang support
192
+ *
193
+ * This preset is optimized for CLI packages with:
194
+ * - ESM-only output by default
195
+ * - Automatic shebang injection
196
+ * - Node.js target specification
197
+ * - Support for object-style entry points
198
+ *
199
+ * @example
200
+ * ```typescript
201
+ * // Simple CLI with shebang
202
+ * import { createTsupCliConfig } from '@jmlweb/tsup-config-base';
203
+ * export default createTsupCliConfig();
204
+ * ```
205
+ *
206
+ * @example
207
+ * ```typescript
208
+ * // CLI with library API (shebang only on cli entry)
209
+ * import { createTsupCliConfig } from '@jmlweb/tsup-config-base';
210
+ * export default createTsupCliConfig({
211
+ * entry: { cli: 'src/cli.ts', index: 'src/index.ts' },
212
+ * shebang: 'cli', // Only add shebang to cli entry
213
+ * });
214
+ * ```
215
+ *
216
+ * @example
217
+ * ```typescript
218
+ * // CLI targeting Node.js 22
219
+ * import { createTsupCliConfig } from '@jmlweb/tsup-config-base';
220
+ * export default createTsupCliConfig({
221
+ * target: 'node22',
222
+ * external: ['commander'],
223
+ * });
224
+ * ```
225
+ */
226
+ declare const createTsupCliConfig: (config?: TsupCliConfigOptions) => Options | Options[];
87
227
 
88
- export { BASE_DEFAULTS, type TsupConfigOptions, createTsupConfig };
228
+ export { BASE_DEFAULTS, CLI_DEFAULTS, type EntryConfig, type NodeTarget, type TsupCliConfigOptions, type TsupConfigOptions, createTsupCliConfig, createTsupConfig };
package/dist/index.d.ts CHANGED
@@ -1,15 +1,32 @@
1
1
  import { Options } from 'tsup';
2
2
  export { Options } from 'tsup';
3
3
 
4
+ /**
5
+ * Entry points configuration - can be an array of paths or an object mapping names to paths
6
+ */
7
+ type EntryConfig = string[] | Record<string, string>;
8
+ /**
9
+ * Node.js target version for CLI builds
10
+ */
11
+ type NodeTarget = 'node16' | 'node18' | 'node20' | 'node22' | `node${number}`;
4
12
  /**
5
13
  * Options for creating a base tsup configuration
6
14
  */
7
15
  interface TsupConfigOptions {
8
16
  /**
9
17
  * Entry points for the build
18
+ * Can be an array of paths or an object mapping output names to source paths
10
19
  * @default ['src/index.ts']
20
+ * @example
21
+ * ```typescript
22
+ * // Array format
23
+ * entry: ['src/index.ts', 'src/cli.ts']
24
+ *
25
+ * // Object format (named entries)
26
+ * entry: { index: 'src/index.ts', cli: 'src/cli.ts' }
27
+ * ```
11
28
  */
12
- entry?: string[];
29
+ entry?: EntryConfig;
13
30
  /**
14
31
  * Output formats
15
32
  * @default ['cjs', 'esm']
@@ -41,16 +58,102 @@ interface TsupConfigOptions {
41
58
  */
42
59
  options?: Omit<Options, 'entry' | 'format' | 'dts' | 'clean' | 'outDir' | 'external'>;
43
60
  }
61
+ /**
62
+ * Options for creating a CLI-specific tsup configuration
63
+ */
64
+ interface TsupCliConfigOptions {
65
+ /**
66
+ * Entry points for the build
67
+ * Can be an array of paths or an object mapping output names to source paths
68
+ * @default { cli: 'src/cli.ts' }
69
+ * @example
70
+ * ```typescript
71
+ * // Single CLI entry
72
+ * entry: { cli: 'src/cli.ts' }
73
+ *
74
+ * // CLI with library API
75
+ * entry: { cli: 'src/cli.ts', index: 'src/index.ts' }
76
+ *
77
+ * // Array format
78
+ * entry: ['src/cli.ts', 'src/index.ts']
79
+ * ```
80
+ */
81
+ entry?: EntryConfig;
82
+ /**
83
+ * Output formats
84
+ * @default ['esm']
85
+ */
86
+ format?: ('cjs' | 'esm' | 'iife')[];
87
+ /**
88
+ * Generate TypeScript declaration files
89
+ * @default true
90
+ */
91
+ dts?: boolean;
92
+ /**
93
+ * Clean output directory before build
94
+ * @default true
95
+ */
96
+ clean?: boolean;
97
+ /**
98
+ * Output directory
99
+ * @default 'dist'
100
+ */
101
+ outDir?: string;
102
+ /**
103
+ * External packages to exclude from the bundle
104
+ * @default []
105
+ */
106
+ external?: (string | RegExp)[];
107
+ /**
108
+ * Node.js target version for the build
109
+ * @default 'node18'
110
+ */
111
+ target?: NodeTarget;
112
+ /**
113
+ * Add shebang (#!/usr/bin/env node) to the output
114
+ * When true, adds shebang to all entry points
115
+ * When a string or array, only adds shebang to matching entry names
116
+ * @default true
117
+ * @example
118
+ * ```typescript
119
+ * // Add shebang to all entries
120
+ * shebang: true
121
+ *
122
+ * // Add shebang only to 'cli' entry
123
+ * shebang: 'cli'
124
+ *
125
+ * // Add shebang to specific entries
126
+ * shebang: ['cli', 'bin']
127
+ * ```
128
+ */
129
+ shebang?: boolean | string | string[];
130
+ /**
131
+ * Additional tsup options to merge with the base configuration
132
+ */
133
+ options?: Omit<Options, 'entry' | 'format' | 'dts' | 'clean' | 'outDir' | 'external' | 'target'>;
134
+ }
44
135
  /**
45
136
  * Base tsup configuration defaults used across all @jmlweb packages
46
137
  */
47
138
  declare const BASE_DEFAULTS: {
48
- entry: string[];
139
+ entry: EntryConfig;
49
140
  format: ("cjs" | "esm")[];
50
141
  dts: true;
51
142
  clean: true;
52
143
  outDir: string;
53
144
  };
145
+ /**
146
+ * CLI-specific tsup configuration defaults
147
+ */
148
+ declare const CLI_DEFAULTS: {
149
+ entry: EntryConfig;
150
+ format: ("esm")[];
151
+ dts: true;
152
+ clean: true;
153
+ outDir: string;
154
+ target: NodeTarget;
155
+ shebang: boolean | string | string[];
156
+ };
54
157
  /**
55
158
  * Creates a base tsup configuration with sensible defaults
56
159
  *
@@ -84,5 +187,42 @@ declare const BASE_DEFAULTS: {
84
187
  * ```
85
188
  */
86
189
  declare const createTsupConfig: (config?: TsupConfigOptions) => Options;
190
+ /**
191
+ * Creates a CLI-specific tsup configuration with shebang support
192
+ *
193
+ * This preset is optimized for CLI packages with:
194
+ * - ESM-only output by default
195
+ * - Automatic shebang injection
196
+ * - Node.js target specification
197
+ * - Support for object-style entry points
198
+ *
199
+ * @example
200
+ * ```typescript
201
+ * // Simple CLI with shebang
202
+ * import { createTsupCliConfig } from '@jmlweb/tsup-config-base';
203
+ * export default createTsupCliConfig();
204
+ * ```
205
+ *
206
+ * @example
207
+ * ```typescript
208
+ * // CLI with library API (shebang only on cli entry)
209
+ * import { createTsupCliConfig } from '@jmlweb/tsup-config-base';
210
+ * export default createTsupCliConfig({
211
+ * entry: { cli: 'src/cli.ts', index: 'src/index.ts' },
212
+ * shebang: 'cli', // Only add shebang to cli entry
213
+ * });
214
+ * ```
215
+ *
216
+ * @example
217
+ * ```typescript
218
+ * // CLI targeting Node.js 22
219
+ * import { createTsupCliConfig } from '@jmlweb/tsup-config-base';
220
+ * export default createTsupCliConfig({
221
+ * target: 'node22',
222
+ * external: ['commander'],
223
+ * });
224
+ * ```
225
+ */
226
+ declare const createTsupCliConfig: (config?: TsupCliConfigOptions) => Options | Options[];
87
227
 
88
- export { BASE_DEFAULTS, type TsupConfigOptions, createTsupConfig };
228
+ export { BASE_DEFAULTS, CLI_DEFAULTS, type EntryConfig, type NodeTarget, type TsupCliConfigOptions, type TsupConfigOptions, createTsupCliConfig, createTsupConfig };
package/dist/index.js CHANGED
@@ -6,6 +6,15 @@ var BASE_DEFAULTS = {
6
6
  clean: true,
7
7
  outDir: "dist"
8
8
  };
9
+ var CLI_DEFAULTS = {
10
+ entry: { cli: "src/cli.ts" },
11
+ format: ["esm"],
12
+ dts: true,
13
+ clean: true,
14
+ outDir: "dist",
15
+ target: "node18",
16
+ shebang: true
17
+ };
9
18
  var createTsupConfig = (config = {}) => {
10
19
  const {
11
20
  entry = BASE_DEFAULTS.entry,
@@ -26,7 +35,113 @@ var createTsupConfig = (config = {}) => {
26
35
  ...options
27
36
  };
28
37
  };
38
+ var SHEBANG = "#!/usr/bin/env node";
39
+ var createTsupCliConfig = (config = {}) => {
40
+ const {
41
+ entry = CLI_DEFAULTS.entry,
42
+ format = CLI_DEFAULTS.format,
43
+ dts = CLI_DEFAULTS.dts,
44
+ clean = CLI_DEFAULTS.clean,
45
+ outDir = CLI_DEFAULTS.outDir,
46
+ external = [],
47
+ target = CLI_DEFAULTS.target,
48
+ shebang = CLI_DEFAULTS.shebang,
49
+ options = {}
50
+ } = config;
51
+ const shebangEntries = normalizeShebangConfig(shebang);
52
+ if (shebangEntries === "all") {
53
+ return {
54
+ entry,
55
+ format,
56
+ dts,
57
+ clean,
58
+ outDir,
59
+ target,
60
+ banner: { js: SHEBANG },
61
+ ...external.length > 0 && { external },
62
+ ...options
63
+ };
64
+ }
65
+ if (shebangEntries.length === 0) {
66
+ return {
67
+ entry,
68
+ format,
69
+ dts,
70
+ clean,
71
+ outDir,
72
+ target,
73
+ ...external.length > 0 && { external },
74
+ ...options
75
+ };
76
+ }
77
+ const entryObject = normalizeEntry(entry);
78
+ const shebangSet = new Set(shebangEntries);
79
+ const withShebang = {};
80
+ const withoutShebang = {};
81
+ for (const [name, path] of Object.entries(entryObject)) {
82
+ if (shebangSet.has(name)) {
83
+ withShebang[name] = path;
84
+ } else {
85
+ withoutShebang[name] = path;
86
+ }
87
+ }
88
+ const configs = [];
89
+ if (Object.keys(withShebang).length > 0) {
90
+ configs.push({
91
+ entry: withShebang,
92
+ format,
93
+ dts,
94
+ clean,
95
+ outDir,
96
+ target,
97
+ banner: { js: SHEBANG },
98
+ ...external.length > 0 && { external },
99
+ ...options
100
+ });
101
+ }
102
+ if (Object.keys(withoutShebang).length > 0) {
103
+ configs.push({
104
+ entry: withoutShebang,
105
+ format,
106
+ dts,
107
+ // Only clean on first config
108
+ clean: configs.length === 0 ? clean : false,
109
+ outDir,
110
+ target,
111
+ ...external.length > 0 && { external },
112
+ ...options
113
+ });
114
+ }
115
+ return configs.length === 1 ? configs[0] : configs;
116
+ };
117
+ var normalizeEntry = (entry) => {
118
+ if (Array.isArray(entry)) {
119
+ return entry.reduce(
120
+ (acc, path) => {
121
+ const name = path.replace(/^.*\//, "").replace(/\.[^.]+$/, "");
122
+ acc[name] = path;
123
+ return acc;
124
+ },
125
+ {}
126
+ );
127
+ }
128
+ return entry;
129
+ };
130
+ var normalizeShebangConfig = (shebang) => {
131
+ if (shebang === true) {
132
+ return "all";
133
+ }
134
+ if (shebang === false) {
135
+ return [];
136
+ }
137
+ if (typeof shebang === "string") {
138
+ return [shebang];
139
+ }
140
+ return shebang;
141
+ };
29
142
  export {
30
143
  BASE_DEFAULTS,
144
+ CLI_DEFAULTS,
145
+ createTsupCliConfig,
31
146
  createTsupConfig
32
147
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@jmlweb/tsup-config-base",
3
- "version": "1.0.1",
3
+ "version": "1.1.0",
4
4
  "description": "Base tsup configuration for jmlweb projects with sensible defaults",
5
5
  "type": "module",
6
6
  "main": "./dist/index.cjs",