itty-packager 1.0.12 → 1.2.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.
@@ -2,7 +2,8 @@
2
2
  "permissions": {
3
3
  "allow": [
4
4
  "Bash(bun bin/itty.js lint:*)",
5
- "Bash(bun bin/itty.js prepare:*)"
5
+ "Bash(bun bin/itty.js prepare:*)",
6
+ "Bash(bun bin/itty.js publish:*)"
6
7
  ],
7
8
  "deny": []
8
9
  }
@@ -61,10 +61,10 @@ Note:
61
61
  // 1. Lint
62
62
  try {
63
63
  if (scripts.lint) {
64
- console.log('📋 Running lint script...')
64
+ console.log('🔍 Running lint script...')
65
65
  await runNpmScript('lint', verbose)
66
66
  } else {
67
- console.log('📋 Running built-in lint...')
67
+ console.log('🔍 Running built-in lint...')
68
68
  await lintCommand([])
69
69
  }
70
70
  if (!verbose) console.log('✅ Lint passed')
@@ -2,6 +2,8 @@ import { parseArgs } from 'node:util'
2
2
  import { spawn } from 'node:child_process'
3
3
  import fs from 'fs-extra'
4
4
  import path from 'node:path'
5
+ import readline from 'node:readline'
6
+ import { prepareCommand } from './prepare.js'
5
7
 
6
8
  const SEMVER_TYPES = ['major', 'minor', 'patch']
7
9
 
@@ -72,6 +74,71 @@ function versionBump(currentVersion, type) {
72
74
  }
73
75
  }
74
76
 
77
+ async function getCommitMessage(newVersion, silent = false) {
78
+ if (silent) {
79
+ return `released v${newVersion}`
80
+ }
81
+
82
+ return new Promise((resolve) => {
83
+ const rl = readline.createInterface({
84
+ input: process.stdin,
85
+ output: process.stdout
86
+ })
87
+
88
+ console.log('\nEnter optional commit message (empty submission skips):')
89
+ console.log('\x1b[90mPress Enter to finish, Ctrl+C to skip\x1b[0m')
90
+ process.stdout.write('\n')
91
+
92
+ let inputLines = []
93
+ let firstInput = true
94
+
95
+ rl.on('line', (input) => {
96
+ if (firstInput && input.trim() === '') {
97
+ // First line is empty, skip custom message
98
+ rl.close()
99
+ resolve(`released v${newVersion}`)
100
+ return
101
+ }
102
+
103
+ firstInput = false
104
+
105
+ if (input.trim() === '' && inputLines.length > 0) {
106
+ // Empty line after content - finish input
107
+ finishInput()
108
+ return
109
+ }
110
+
111
+ inputLines.push(input)
112
+ })
113
+
114
+ const finishInput = () => {
115
+ rl.close()
116
+ const customMessage = inputLines.join('\n').trim()
117
+
118
+ if (!customMessage) {
119
+ resolve(`released v${newVersion}`)
120
+ } else {
121
+ // Escape quotes in the custom message
122
+ const escapedMessage = customMessage.replace(/"/g, '\\"')
123
+ resolve(`released v${newVersion} - ${escapedMessage}`)
124
+ }
125
+ }
126
+
127
+ rl.on('SIGINT', () => {
128
+ console.log('\nSkipped. Using default commit message.')
129
+ rl.close()
130
+ resolve(`released v${newVersion}`)
131
+ })
132
+
133
+ // Handle Ctrl+D (EOF) as completion
134
+ rl.on('close', () => {
135
+ if (!firstInput && inputLines.length > 0) {
136
+ finishInput()
137
+ }
138
+ })
139
+ })
140
+ }
141
+
75
142
  async function runCommand(command, cwd = process.cwd(), verbose = false) {
76
143
  return new Promise((resolve, reject) => {
77
144
  const [cmd, ...args] = command.split(' ')
@@ -169,6 +236,14 @@ export async function publishCommand(args) {
169
236
  type: 'boolean',
170
237
  description: 'Do not copy LICENSE file to published package'
171
238
  },
239
+ prepare: {
240
+ type: 'boolean',
241
+ description: 'Run prepare (lint, test, build) before publishing'
242
+ },
243
+ silent: {
244
+ type: 'boolean',
245
+ description: 'Skip interactive prompts (use default commit message)'
246
+ },
172
247
  verbose: {
173
248
  type: 'boolean',
174
249
  short: 'v',
@@ -201,6 +276,8 @@ Publish Options:
201
276
  --dry-run Build and prepare but do not publish
202
277
  --no-cleanup Leave temporary directory after publishing
203
278
  --public Publish as public package (--access=public)
279
+ --prepare Run prepare (lint, test, build) before publishing
280
+ --silent Skip interactive prompts (use default commit message)
204
281
  --no-license Do not copy LICENSE file to published package
205
282
  -v, --verbose Show detailed output including npm and git command details
206
283
 
@@ -246,9 +323,17 @@ This creates a clean, flat package structure in node_modules.
246
323
  const shouldPush = publishArgs.push
247
324
  const noGit = publishArgs['no-git']
248
325
  const noLicense = publishArgs['no-license']
326
+ const shouldPrepare = publishArgs.prepare
327
+ const silent = publishArgs.silent
249
328
  const verbose = publishArgs.verbose
250
329
 
251
330
  try {
331
+ // Run prepare if requested
332
+ if (shouldPrepare) {
333
+ console.log('🚀 Running prepare sequence before publishing...')
334
+ await prepareCommand(verbose ? ['--verbose'] : [])
335
+ console.log('✅ Prepare completed successfully\n')
336
+ }
252
337
  // Read package.json
253
338
  const pkgPath = path.join(rootPath, 'package.json')
254
339
  const pkg = await fs.readJSON(pkgPath)
@@ -342,9 +427,12 @@ This creates a clean, flat package structure in node_modules.
342
427
  // Git operations
343
428
  if (!noGit && !dryRun) {
344
429
  if (shouldPush || shouldTag) {
430
+ // Get commit message (interactive or default)
431
+ const commitMessage = await getCommitMessage(newVersion, silent)
432
+
345
433
  if (verbose) console.log(`📋 Committing changes...`)
346
434
  await runCommand('git add .', rootPath, verbose)
347
- await runCommand(`git commit -m "released v${newVersion}"`, rootPath, verbose)
435
+ await runCommand(`git commit -m "${commitMessage}"`, rootPath, verbose)
348
436
  }
349
437
 
350
438
  if (shouldTag) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "itty-packager",
3
- "version": "1.0.12",
3
+ "version": "1.2.0",
4
4
  "description": "Universal build tool for itty libraries",
5
5
  "type": "module",
6
6
  "bin": {