itty-packager 1.0.11 โ 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/.claude/settings.local.json +3 -1
- package/bin/itty.js +2 -0
- package/lib/commands/prepare.js +153 -0
- package/lib/commands/publish.js +13 -0
- package/package.json +1 -1
package/bin/itty.js
CHANGED
|
@@ -5,6 +5,7 @@ import { parseArgs } from 'node:util'
|
|
|
5
5
|
const subcommands = {
|
|
6
6
|
build: () => import('../lib/commands/build.js').then(m => m.buildCommand),
|
|
7
7
|
lint: () => import('../lib/commands/lint.js').then(m => m.lintCommand),
|
|
8
|
+
prepare: () => import('../lib/commands/prepare.js').then(m => m.prepareCommand),
|
|
8
9
|
publish: () => import('../lib/commands/publish.js').then(m => m.publishCommand),
|
|
9
10
|
// Future subcommands can be added here:
|
|
10
11
|
// deploy: () => import('../lib/commands/deploy.js').then(m => m.deployCommand),
|
|
@@ -73,6 +74,7 @@ Usage: itty <subcommand> [options]
|
|
|
73
74
|
Subcommands:
|
|
74
75
|
build Build your library with rollup and typescript
|
|
75
76
|
lint Lint your code with ESLint
|
|
77
|
+
prepare Run lint, test, and build in sequence
|
|
76
78
|
publish Version and publish your package to npm
|
|
77
79
|
|
|
78
80
|
Global Options:
|
|
@@ -0,0 +1,153 @@
|
|
|
1
|
+
import { parseArgs } from 'node:util'
|
|
2
|
+
import { spawn } from 'node:child_process'
|
|
3
|
+
import fs from 'fs-extra'
|
|
4
|
+
import path from 'node:path'
|
|
5
|
+
import { build } from '../builder.js'
|
|
6
|
+
import { lintCommand } from './lint.js'
|
|
7
|
+
|
|
8
|
+
export async function prepareCommand(args) {
|
|
9
|
+
const { values: prepareArgs } = parseArgs({
|
|
10
|
+
args,
|
|
11
|
+
options: {
|
|
12
|
+
verbose: {
|
|
13
|
+
type: 'boolean',
|
|
14
|
+
short: 'v',
|
|
15
|
+
description: 'Show all output from underlying commands'
|
|
16
|
+
},
|
|
17
|
+
help: {
|
|
18
|
+
type: 'boolean',
|
|
19
|
+
short: 'h',
|
|
20
|
+
description: 'Show help'
|
|
21
|
+
}
|
|
22
|
+
},
|
|
23
|
+
allowPositionals: false
|
|
24
|
+
})
|
|
25
|
+
|
|
26
|
+
if (prepareArgs.help) {
|
|
27
|
+
console.log(`
|
|
28
|
+
itty prepare - Run lint, test, and build in sequence
|
|
29
|
+
|
|
30
|
+
Usage: itty prepare [options]
|
|
31
|
+
|
|
32
|
+
Options:
|
|
33
|
+
-v, --verbose Show all output from underlying commands
|
|
34
|
+
-h, --help Show help
|
|
35
|
+
|
|
36
|
+
Examples:
|
|
37
|
+
itty prepare # Run lint, test, build silently (show only failures)
|
|
38
|
+
itty prepare --verbose # Run with full output from all commands
|
|
39
|
+
|
|
40
|
+
Note:
|
|
41
|
+
- Uses package.json scripts if available (lint, test), falls back to built-in commands
|
|
42
|
+
- Only shows output when commands fail, unless --verbose is used
|
|
43
|
+
- Stops on first failure
|
|
44
|
+
`)
|
|
45
|
+
return
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
const cwd = process.cwd()
|
|
49
|
+
const packageJsonPath = path.join(cwd, 'package.json')
|
|
50
|
+
|
|
51
|
+
let packageJson = {}
|
|
52
|
+
if (await fs.pathExists(packageJsonPath)) {
|
|
53
|
+
packageJson = await fs.readJson(packageJsonPath)
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
const scripts = packageJson.scripts || {}
|
|
57
|
+
const verbose = prepareArgs.verbose
|
|
58
|
+
|
|
59
|
+
console.log('๐ Running prepare sequence...')
|
|
60
|
+
|
|
61
|
+
// 1. Lint
|
|
62
|
+
try {
|
|
63
|
+
if (scripts.lint) {
|
|
64
|
+
console.log('๐ Running lint script...')
|
|
65
|
+
await runNpmScript('lint', verbose)
|
|
66
|
+
} else {
|
|
67
|
+
console.log('๐ Running built-in lint...')
|
|
68
|
+
await lintCommand([])
|
|
69
|
+
}
|
|
70
|
+
if (!verbose) console.log('โ
Lint passed')
|
|
71
|
+
} catch (error) {
|
|
72
|
+
throw new Error(`Lint failed: ${error.message}`)
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
// 2. Test
|
|
76
|
+
try {
|
|
77
|
+
if (scripts.test) {
|
|
78
|
+
console.log('๐งช Running test script...')
|
|
79
|
+
await runNpmScript('test', verbose)
|
|
80
|
+
if (!verbose) console.log('โ
Tests passed')
|
|
81
|
+
} else {
|
|
82
|
+
console.log('๐งช No test script found, skipping tests')
|
|
83
|
+
}
|
|
84
|
+
} catch (error) {
|
|
85
|
+
throw new Error(`Tests failed: ${error.message}`)
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
// 3. Build
|
|
89
|
+
try {
|
|
90
|
+
if (scripts.build) {
|
|
91
|
+
console.log('๐จ Running build script...')
|
|
92
|
+
await runNpmScript('build', verbose)
|
|
93
|
+
if (!verbose) console.log('โ
Build completed')
|
|
94
|
+
} else {
|
|
95
|
+
// Check if there's a src directory or TypeScript files to build
|
|
96
|
+
const srcExists = await fs.pathExists(path.join(cwd, 'src'))
|
|
97
|
+
if (srcExists) {
|
|
98
|
+
console.log('๐จ Running built-in build...')
|
|
99
|
+
await build({})
|
|
100
|
+
if (!verbose) console.log('โ
Build completed')
|
|
101
|
+
} else {
|
|
102
|
+
console.log('๐จ No build script or src directory found, skipping build')
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
} catch (error) {
|
|
106
|
+
throw new Error(`Build failed: ${error.message}`)
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
console.log('๐ Prepare sequence completed successfully')
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
async function runNpmScript(scriptName, verbose) {
|
|
113
|
+
return new Promise((resolve, reject) => {
|
|
114
|
+
const stdio = verbose ? 'inherit' : 'pipe'
|
|
115
|
+
const npm = spawn('npm', ['run', scriptName], {
|
|
116
|
+
stdio,
|
|
117
|
+
cwd: process.cwd(),
|
|
118
|
+
shell: true
|
|
119
|
+
})
|
|
120
|
+
|
|
121
|
+
let stdout = ''
|
|
122
|
+
let stderr = ''
|
|
123
|
+
|
|
124
|
+
if (!verbose) {
|
|
125
|
+
npm.stdout?.on('data', (data) => {
|
|
126
|
+
stdout += data.toString()
|
|
127
|
+
})
|
|
128
|
+
|
|
129
|
+
npm.stderr?.on('data', (data) => {
|
|
130
|
+
stderr += data.toString()
|
|
131
|
+
})
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
npm.on('close', (code) => {
|
|
135
|
+
if (code === 0) {
|
|
136
|
+
resolve()
|
|
137
|
+
} else {
|
|
138
|
+
// Show output on failure even if not verbose
|
|
139
|
+
if (!verbose && (stdout || stderr)) {
|
|
140
|
+
console.error('\n--- Output from failed command ---')
|
|
141
|
+
if (stdout) console.log(stdout)
|
|
142
|
+
if (stderr) console.error(stderr)
|
|
143
|
+
console.error('--- End output ---\n')
|
|
144
|
+
}
|
|
145
|
+
reject(new Error(`Script '${scriptName}' exited with code ${code}`))
|
|
146
|
+
}
|
|
147
|
+
})
|
|
148
|
+
|
|
149
|
+
npm.on('error', (error) => {
|
|
150
|
+
reject(new Error(`Failed to run script '${scriptName}': ${error.message}`))
|
|
151
|
+
})
|
|
152
|
+
})
|
|
153
|
+
}
|
package/lib/commands/publish.js
CHANGED
|
@@ -2,6 +2,7 @@ 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 { prepareCommand } from './prepare.js'
|
|
5
6
|
|
|
6
7
|
const SEMVER_TYPES = ['major', 'minor', 'patch']
|
|
7
8
|
|
|
@@ -169,6 +170,10 @@ export async function publishCommand(args) {
|
|
|
169
170
|
type: 'boolean',
|
|
170
171
|
description: 'Do not copy LICENSE file to published package'
|
|
171
172
|
},
|
|
173
|
+
prepare: {
|
|
174
|
+
type: 'boolean',
|
|
175
|
+
description: 'Run prepare (lint, test, build) before publishing'
|
|
176
|
+
},
|
|
172
177
|
verbose: {
|
|
173
178
|
type: 'boolean',
|
|
174
179
|
short: 'v',
|
|
@@ -201,6 +206,7 @@ Publish Options:
|
|
|
201
206
|
--dry-run Build and prepare but do not publish
|
|
202
207
|
--no-cleanup Leave temporary directory after publishing
|
|
203
208
|
--public Publish as public package (--access=public)
|
|
209
|
+
--prepare Run prepare (lint, test, build) before publishing
|
|
204
210
|
--no-license Do not copy LICENSE file to published package
|
|
205
211
|
-v, --verbose Show detailed output including npm and git command details
|
|
206
212
|
|
|
@@ -246,9 +252,16 @@ This creates a clean, flat package structure in node_modules.
|
|
|
246
252
|
const shouldPush = publishArgs.push
|
|
247
253
|
const noGit = publishArgs['no-git']
|
|
248
254
|
const noLicense = publishArgs['no-license']
|
|
255
|
+
const shouldPrepare = publishArgs.prepare
|
|
249
256
|
const verbose = publishArgs.verbose
|
|
250
257
|
|
|
251
258
|
try {
|
|
259
|
+
// Run prepare if requested
|
|
260
|
+
if (shouldPrepare) {
|
|
261
|
+
console.log('๐ Running prepare sequence before publishing...')
|
|
262
|
+
await prepareCommand(verbose ? ['--verbose'] : [])
|
|
263
|
+
console.log('โ
Prepare completed successfully\n')
|
|
264
|
+
}
|
|
252
265
|
// Read package.json
|
|
253
266
|
const pkgPath = path.join(rootPath, 'package.json')
|
|
254
267
|
const pkg = await fs.readJSON(pkgPath)
|