itty-packager 1.0.7 → 1.0.9
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/settings.local.json +8 -0
- package/CLAUDE.md +77 -0
- package/README.md +4 -3
- package/lib/commands/publish.js +42 -26
- package/package.json +5 -5
package/CLAUDE.md
ADDED
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
# CLAUDE.md
|
|
2
|
+
|
|
3
|
+
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
|
|
4
|
+
|
|
5
|
+
## Commands
|
|
6
|
+
|
|
7
|
+
### Development Commands
|
|
8
|
+
- `bun bin/itty.js lint` - Lint the codebase using the CLI tool itself
|
|
9
|
+
- `bun bin/itty.js build` - Build the project (not typically needed as this is the build tool itself)
|
|
10
|
+
- `echo 'No tests yet'` - Current test command (no test suite implemented)
|
|
11
|
+
|
|
12
|
+
### Release Commands
|
|
13
|
+
- `bun bin/itty.js publish --patch --tag --dry-run --src=. --no-license` - Dry run release
|
|
14
|
+
- `bun bin/itty.js publish --patch --tag --push --src=. --no-license` - Patch release (quiet by default)
|
|
15
|
+
- `bun bin/itty.js publish --minor --tag --push --src=. --no-license` - Minor release
|
|
16
|
+
- `bun bin/itty.js publish --major --tag --push --src=. --no-license` - Major release
|
|
17
|
+
- Add `--verbose` flag to any command for detailed output including npm and git details
|
|
18
|
+
|
|
19
|
+
### CLI Usage
|
|
20
|
+
The main CLI entry point is `bin/itty.js` which provides three core commands:
|
|
21
|
+
- `itty build` - TypeScript compilation with Rollup
|
|
22
|
+
- `itty lint` - ESLint with built-in TypeScript configuration
|
|
23
|
+
- `itty publish` - Version bumping and npm publishing
|
|
24
|
+
|
|
25
|
+
## Architecture
|
|
26
|
+
|
|
27
|
+
### Core Components
|
|
28
|
+
|
|
29
|
+
**CLI Entry Point** (`bin/itty.js`):
|
|
30
|
+
- Main executable that dynamically imports command modules
|
|
31
|
+
- Handles global flags (--help, --version) and subcommand routing
|
|
32
|
+
- Supports build, lint, and publish subcommands
|
|
33
|
+
|
|
34
|
+
**Build System** (`lib/builder.js`):
|
|
35
|
+
- Core build logic using Rollup and TypeScript
|
|
36
|
+
- Handles ESM/CJS hybrid builds, minification with terser, sourcemaps
|
|
37
|
+
- Automatically updates package.json exports based on build outputs
|
|
38
|
+
- Supports snippet generation for README injection
|
|
39
|
+
- Single file exports map to root export, multiple files get individual exports
|
|
40
|
+
|
|
41
|
+
**Command Modules** (`lib/commands/`):
|
|
42
|
+
- **build.js**: Wraps builder.js with CLI argument parsing
|
|
43
|
+
- **lint.js**: ESLint integration with smart config detection
|
|
44
|
+
- **publish.js**: Version bumping, package extraction, and npm publishing
|
|
45
|
+
|
|
46
|
+
**ESLint Configuration** (`lib/configs/`):
|
|
47
|
+
- **createConfig.mjs**: Factory function for extending base TypeScript ESLint config
|
|
48
|
+
- **eslint.config.mjs**: Base configuration with TypeScript support
|
|
49
|
+
- Automatically used when no local ESLint config is found
|
|
50
|
+
|
|
51
|
+
### Key Architectural Patterns
|
|
52
|
+
|
|
53
|
+
**Dynamic Command Loading**: Commands are lazily loaded to improve startup time and allow future extensibility.
|
|
54
|
+
|
|
55
|
+
**Smart Configuration**: The lint command detects local ESLint configs and falls back to built-in TypeScript configuration when none exists.
|
|
56
|
+
|
|
57
|
+
**Clean Package Publishing**: The publish command creates a flat package structure by extracting build artifacts to a temporary directory, copying essential files (README, LICENSE, CHANGELOG), and transforming package.json paths before publishing.
|
|
58
|
+
|
|
59
|
+
**Extensible ESLint**: Projects can extend the built-in config using `createConfig()` from `itty-packager/lib/configs/createConfig.mjs`.
|
|
60
|
+
|
|
61
|
+
### Build Output Handling
|
|
62
|
+
|
|
63
|
+
The build system automatically manages package.json exports:
|
|
64
|
+
- Single TypeScript file → root export (`"."`)
|
|
65
|
+
- Multiple TypeScript files → individual named exports
|
|
66
|
+
- Paths are automatically updated to point to dist/ directory
|
|
67
|
+
- ESM builds by default, CJS optional with `--hybrid` flag
|
|
68
|
+
|
|
69
|
+
### Publishing Workflow
|
|
70
|
+
|
|
71
|
+
The publish command transforms the package structure:
|
|
72
|
+
1. Extracts build artifacts from dist/ to temporary directory
|
|
73
|
+
2. Copies root files (README.md, LICENSE, .npmrc)
|
|
74
|
+
3. Transforms package.json paths (e.g., `./dist/file.mjs` → `./file.mjs`)
|
|
75
|
+
4. Publishes the clean, flat structure
|
|
76
|
+
5. Updates root package.json with new version
|
|
77
|
+
6. Optionally handles git tagging and pushing
|
package/README.md
CHANGED
|
@@ -138,7 +138,7 @@ Version bump and publish your package to npm with clean, flat package structure.
|
|
|
138
138
|
- `--no-cleanup` - Leave temporary directory after publishing
|
|
139
139
|
- `--public` - Publish as public package (`--access=public`)
|
|
140
140
|
- `--no-license` - Do not copy LICENSE file to published package
|
|
141
|
-
-
|
|
141
|
+
- `-v, --verbose` - Show detailed output including npm and git command details
|
|
142
142
|
|
|
143
143
|
**Git Options:**
|
|
144
144
|
- `--tag` - Create git tag for release
|
|
@@ -148,7 +148,7 @@ Version bump and publish your package to npm with clean, flat package structure.
|
|
|
148
148
|
**Default Behavior:**
|
|
149
149
|
- Defaults to patch version bump if no type specified
|
|
150
150
|
- Extracts build artifacts to temporary directory
|
|
151
|
-
- Copies root files: `README.md`, `LICENSE`,
|
|
151
|
+
- Copies root files: `README.md`, `LICENSE`, `.npmrc` (if they exist)
|
|
152
152
|
- Transforms package.json paths (e.g., `./dist/file.mjs` → `./file.mjs`)
|
|
153
153
|
- Creates clean, flat package structure in node_modules
|
|
154
154
|
|
|
@@ -158,6 +158,7 @@ itty publish # Patch bump and publish from dist/ (default)
|
|
|
158
158
|
itty publish --minor --tag # Minor bump, publish, and create git tag
|
|
159
159
|
itty publish --type=alpha # Pre-release alpha version
|
|
160
160
|
itty publish --dry-run # Test the publish process
|
|
161
|
+
itty publish --verbose # Show detailed output during publish
|
|
161
162
|
itty publish --no-license # Publish without copying LICENSE file
|
|
162
163
|
```
|
|
163
164
|
|
|
@@ -166,7 +167,7 @@ itty publish --no-license # Publish without copying LICENSE file
|
|
|
166
167
|
The publish command creates a clean package structure by:
|
|
167
168
|
|
|
168
169
|
1. **Extracting build artifacts** from your `dist/` directory to package root
|
|
169
|
-
2. **Copying essential files** like README, LICENSE
|
|
170
|
+
2. **Copying essential files** like README, LICENSE
|
|
170
171
|
3. **Transforming paths** in package.json to point to root-level files
|
|
171
172
|
4. **Publishing the clean structure** so users get flat imports
|
|
172
173
|
|
package/lib/commands/publish.js
CHANGED
|
@@ -72,19 +72,35 @@ function versionBump(currentVersion, type) {
|
|
|
72
72
|
}
|
|
73
73
|
}
|
|
74
74
|
|
|
75
|
-
async function runCommand(command, cwd = process.cwd()) {
|
|
75
|
+
async function runCommand(command, cwd = process.cwd(), verbose = false) {
|
|
76
76
|
return new Promise((resolve, reject) => {
|
|
77
77
|
const [cmd, ...args] = command.split(' ')
|
|
78
78
|
const proc = spawn(cmd, args, {
|
|
79
|
-
stdio: 'inherit',
|
|
79
|
+
stdio: verbose ? 'inherit' : 'pipe',
|
|
80
80
|
cwd,
|
|
81
81
|
shell: true
|
|
82
82
|
})
|
|
83
83
|
|
|
84
|
+
let stdout = ''
|
|
85
|
+
let stderr = ''
|
|
86
|
+
|
|
87
|
+
if (!verbose) {
|
|
88
|
+
proc.stdout?.on('data', (data) => {
|
|
89
|
+
stdout += data.toString()
|
|
90
|
+
})
|
|
91
|
+
proc.stderr?.on('data', (data) => {
|
|
92
|
+
stderr += data.toString()
|
|
93
|
+
})
|
|
94
|
+
}
|
|
95
|
+
|
|
84
96
|
proc.on('close', (code) => {
|
|
85
97
|
if (code === 0) {
|
|
86
|
-
resolve()
|
|
98
|
+
resolve({ stdout, stderr })
|
|
87
99
|
} else {
|
|
100
|
+
// Always show error output regardless of verbose setting
|
|
101
|
+
if (!verbose && stderr) {
|
|
102
|
+
console.error(stderr)
|
|
103
|
+
}
|
|
88
104
|
reject(new Error(`Command failed with exit code ${code}: ${command}`))
|
|
89
105
|
}
|
|
90
106
|
})
|
|
@@ -153,9 +169,10 @@ export async function publishCommand(args) {
|
|
|
153
169
|
type: 'boolean',
|
|
154
170
|
description: 'Do not copy LICENSE file to published package'
|
|
155
171
|
},
|
|
156
|
-
|
|
172
|
+
verbose: {
|
|
157
173
|
type: 'boolean',
|
|
158
|
-
|
|
174
|
+
short: 'v',
|
|
175
|
+
description: 'Show detailed output including npm and git command details'
|
|
159
176
|
},
|
|
160
177
|
help: {
|
|
161
178
|
type: 'boolean',
|
|
@@ -185,7 +202,7 @@ Publish Options:
|
|
|
185
202
|
--no-cleanup Leave temporary directory after publishing
|
|
186
203
|
--public Publish as public package (--access=public)
|
|
187
204
|
--no-license Do not copy LICENSE file to published package
|
|
188
|
-
|
|
205
|
+
-v, --verbose Show detailed output including npm and git command details
|
|
189
206
|
|
|
190
207
|
Git Options:
|
|
191
208
|
--tag Create git tag for release
|
|
@@ -229,7 +246,7 @@ This creates a clean, flat package structure in node_modules.
|
|
|
229
246
|
const shouldPush = publishArgs.push
|
|
230
247
|
const noGit = publishArgs['no-git']
|
|
231
248
|
const noLicense = publishArgs['no-license']
|
|
232
|
-
const
|
|
249
|
+
const verbose = publishArgs.verbose
|
|
233
250
|
|
|
234
251
|
try {
|
|
235
252
|
// Read package.json
|
|
@@ -238,7 +255,7 @@ This creates a clean, flat package structure in node_modules.
|
|
|
238
255
|
const newVersion = versionBump(pkg.version, releaseType)
|
|
239
256
|
|
|
240
257
|
console.log(`📦 Publishing ${pkg.name} v${pkg.version} → v${newVersion}`)
|
|
241
|
-
console.log(`📁 Source: ${publishArgs.src}/`)
|
|
258
|
+
if (verbose) console.log(`📁 Source: ${publishArgs.src}/`)
|
|
242
259
|
|
|
243
260
|
// Check if source directory exists
|
|
244
261
|
if (!await fs.pathExists(srcDir)) {
|
|
@@ -246,12 +263,12 @@ This creates a clean, flat package structure in node_modules.
|
|
|
246
263
|
}
|
|
247
264
|
|
|
248
265
|
// Clean and create temp directory
|
|
249
|
-
console.log(`🧹 Preparing ${publishArgs.dest}/`)
|
|
266
|
+
if (verbose) console.log(`🧹 Preparing ${publishArgs.dest}/`)
|
|
250
267
|
await fs.emptyDir(tempDir)
|
|
251
268
|
await fs.ensureDir(tempDir)
|
|
252
269
|
|
|
253
270
|
// Copy source files to temp directory
|
|
254
|
-
console.log(`📋 Copying ${publishArgs.src}/ to ${path.relative(rootPath, tempDir)}/`)
|
|
271
|
+
if (verbose) console.log(`📋 Copying ${publishArgs.src}/ to ${path.relative(rootPath, tempDir)}/`)
|
|
255
272
|
|
|
256
273
|
const filter = (src) => {
|
|
257
274
|
// Always exclude node_modules
|
|
@@ -280,14 +297,13 @@ This creates a clean, flat package structure in node_modules.
|
|
|
280
297
|
|
|
281
298
|
// Add optional files based on flags
|
|
282
299
|
if (!noLicense) rootFiles.push('LICENSE')
|
|
283
|
-
if (!noChangelog) rootFiles.push('CHANGELOG.md')
|
|
284
300
|
|
|
285
301
|
for (const file of rootFiles) {
|
|
286
302
|
const srcFile = path.join(rootPath, file)
|
|
287
303
|
const destFile = path.join(tempDir, file)
|
|
288
304
|
|
|
289
305
|
if (await fs.pathExists(srcFile)) {
|
|
290
|
-
console.log(`📄 Copying ${file}`)
|
|
306
|
+
if (verbose) console.log(`📄 Copying ${file}`)
|
|
291
307
|
await fs.copy(srcFile, destFile)
|
|
292
308
|
}
|
|
293
309
|
}
|
|
@@ -300,7 +316,7 @@ This creates a clean, flat package structure in node_modules.
|
|
|
300
316
|
const tempPkgPath = path.join(tempDir, 'package.json')
|
|
301
317
|
|
|
302
318
|
const transformMessage = isRootPublish ? '' : ' (transforming paths)'
|
|
303
|
-
console.log(`📝 Updating package.json to v${newVersion}${transformMessage}`)
|
|
319
|
+
if (verbose) console.log(`📝 Updating package.json to v${newVersion}${transformMessage}`)
|
|
304
320
|
await fs.writeJSON(tempPkgPath, updatedPkg, { spaces: 2 })
|
|
305
321
|
|
|
306
322
|
if (dryRun) {
|
|
@@ -315,41 +331,41 @@ This creates a clean, flat package structure in node_modules.
|
|
|
315
331
|
SEMVER_TYPES.includes(releaseType) ? '' : `--tag=${releaseType}`
|
|
316
332
|
].filter(Boolean).join(' ')
|
|
317
333
|
|
|
318
|
-
console.log(`Running: ${publishCmd}`)
|
|
319
|
-
await runCommand(publishCmd, tempDir)
|
|
334
|
+
if (verbose) console.log(`Running: ${publishCmd}`)
|
|
335
|
+
await runCommand(publishCmd, tempDir, verbose)
|
|
320
336
|
|
|
321
337
|
// Update root package.json
|
|
322
|
-
console.log(`📝 Updating root package.json`)
|
|
338
|
+
if (verbose) console.log(`📝 Updating root package.json`)
|
|
323
339
|
await fs.writeJSON(pkgPath, updatedPkg, { spaces: 2 })
|
|
324
340
|
}
|
|
325
341
|
|
|
326
342
|
// Git operations
|
|
327
343
|
if (!noGit && !dryRun) {
|
|
328
344
|
if (shouldPush || shouldTag) {
|
|
329
|
-
console.log(`📋 Committing changes...`)
|
|
330
|
-
await runCommand('git add .', rootPath)
|
|
331
|
-
await runCommand(`git commit -m "released v${newVersion}"`, rootPath)
|
|
345
|
+
if (verbose) console.log(`📋 Committing changes...`)
|
|
346
|
+
await runCommand('git add .', rootPath, verbose)
|
|
347
|
+
await runCommand(`git commit -m "released v${newVersion}"`, rootPath, verbose)
|
|
332
348
|
}
|
|
333
349
|
|
|
334
350
|
if (shouldTag) {
|
|
335
|
-
console.log(`🏷️ Creating git tag v${newVersion}`)
|
|
336
|
-
await runCommand(`git tag -a v${newVersion} -m "Release v${newVersion}"`, rootPath)
|
|
351
|
+
if (verbose) console.log(`🏷️ Creating git tag v${newVersion}`)
|
|
352
|
+
await runCommand(`git tag -a v${newVersion} -m "Release v${newVersion}"`, rootPath, verbose)
|
|
337
353
|
}
|
|
338
354
|
|
|
339
355
|
if (shouldPush) {
|
|
340
|
-
console.log(`📤 Pushing to remote...`)
|
|
341
|
-
await runCommand('git push', rootPath)
|
|
356
|
+
if (verbose) console.log(`📤 Pushing to remote...`)
|
|
357
|
+
await runCommand('git push', rootPath, verbose)
|
|
342
358
|
|
|
343
359
|
if (shouldTag) {
|
|
344
|
-
console.log(`📤 Pushing tags...`)
|
|
345
|
-
await runCommand('git push --tags', rootPath)
|
|
360
|
+
if (verbose) console.log(`📤 Pushing tags...`)
|
|
361
|
+
await runCommand('git push --tags', rootPath, verbose)
|
|
346
362
|
}
|
|
347
363
|
}
|
|
348
364
|
}
|
|
349
365
|
|
|
350
366
|
// Cleanup
|
|
351
367
|
if (!noCleanup) {
|
|
352
|
-
console.log(`🧹 Cleaning up ${publishArgs.dest}/`)
|
|
368
|
+
if (verbose) console.log(`🧹 Cleaning up ${publishArgs.dest}/`)
|
|
353
369
|
await fs.remove(tempDir)
|
|
354
370
|
}
|
|
355
371
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "itty-packager",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.9",
|
|
4
4
|
"description": "Universal build tool for itty libraries",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
@@ -9,10 +9,10 @@
|
|
|
9
9
|
"scripts": {
|
|
10
10
|
"lint": "bun bin/itty.js lint",
|
|
11
11
|
"test": "echo 'No tests yet'",
|
|
12
|
-
"release:dry": "bun bin/itty.js publish --patch --tag --dry-run --src=. --no-license
|
|
13
|
-
"release": "bun bin/itty.js publish --patch --tag --push --src=. --no-license
|
|
14
|
-
"release:minor": "bun bin/itty.js publish --minor --tag --push --src=. --no-license
|
|
15
|
-
"release:major": "bun bin/itty.js publish --major --tag --push --src=. --no-license
|
|
12
|
+
"release:dry": "bun bin/itty.js publish --patch --tag --dry-run --src=. --no-license",
|
|
13
|
+
"release": "bun bin/itty.js publish --patch --tag --push --src=. --no-license",
|
|
14
|
+
"release:minor": "bun bin/itty.js publish --minor --tag --push --src=. --no-license",
|
|
15
|
+
"release:major": "bun bin/itty.js publish --major --tag --push --src=. --no-license"
|
|
16
16
|
},
|
|
17
17
|
"keywords": [
|
|
18
18
|
"build",
|