@emeryld/manager 0.2.0 → 0.2.2

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/src/release.ts DELETED
@@ -1,410 +0,0 @@
1
- // src/release.js
2
- import { readFile, writeFile } from 'node:fs/promises'
3
- import path from 'node:path'
4
- import { stageCommitPush } from './git.js'
5
- import { askLine, promptSingleKey, promptYesNoAll } from './prompts.js'
6
- import { bumpVersion, isSemver, type BumpType } from './semver.js'
7
- import type { LoadedPackage } from './utils/log.js'
8
- import { colors, formatPkgName, logGlobal, logPkg } from './utils/log.js'
9
- import { run } from './utils/run.js'
10
-
11
- // in release.js
12
-
13
- type VersionStrategy =
14
- | { mode: 'bump'; bumpType: BumpType; preid?: string }
15
- | { mode: 'sync'; version: string }
16
- | { mode: 'noop' }
17
-
18
- export interface PublishOptions {
19
- nonInteractive?: boolean
20
- bumpType?: BumpType // used when nonInteractive, now includes pre* types
21
- preid?: string // e.g. "alpha" | "beta" | "rc"
22
- syncVersion?: string // used when nonInteractive
23
- tag?: string // e.g. "next" or "beta"
24
- dryRun?: boolean
25
- provenance?: boolean
26
- // Optional: used only for git tag message, if you want:
27
- releaseNotes?: string
28
- }
29
-
30
- export interface PublishOptions {
31
- nonInteractive?: boolean
32
- bumpType?: BumpType // used when nonInteractive
33
- syncVersion?: string // used when nonInteractive
34
- tag?: string // e.g. "next" or "beta"
35
- dryRun?: boolean
36
- provenance?: boolean
37
- }
38
-
39
- const bumpMap: Record<string, BumpType> = {
40
- '1': 'patch',
41
- '2': 'minor',
42
- '3': 'major',
43
- // mapped from pre-release submenu later, but keep named keys for nonInteractive
44
- patch: 'patch',
45
- minor: 'minor',
46
- major: 'major',
47
- prepatch: 'prepatch',
48
- preminor: 'preminor',
49
- premajor: 'premajor',
50
- prerelease: 'prerelease',
51
- }
52
-
53
- function preBumpFromChoice(choice: string): BumpType | undefined {
54
- switch (choice) {
55
- case '1':
56
- return 'prepatch'
57
- case '2':
58
- return 'preminor'
59
- case '3':
60
- return 'premajor'
61
- case '4':
62
- return 'prerelease'
63
- default:
64
- return undefined
65
- }
66
- }
67
-
68
- async function writePackageJson(pkgPath: string, json: unknown) {
69
- await writeFile(pkgPath, `${JSON.stringify(json, null, 2)}\n`)
70
- }
71
-
72
- async function refreshPackagesFromDisk(pkgs: LoadedPackage[]) {
73
- await Promise.all(
74
- pkgs.map(async (pkg) => {
75
- const raw = await readFile(pkg.packageJsonPath, 'utf8')
76
- const json = JSON.parse(raw)
77
- pkg.json = json
78
- pkg.version = json.version ?? pkg.version
79
- if (json.name) pkg.name = json.name
80
- }),
81
- )
82
- }
83
-
84
- async function ensureNpmAuth() {
85
- try {
86
- await run('pnpm', ['whoami'])
87
- } catch {
88
- throw new Error(
89
- 'Not authenticated to registry. Run "pnpm login" and retry.',
90
- )
91
- }
92
- }
93
-
94
- function ensureNotPrivate(targets: LoadedPackage[]) {
95
- const privates = targets.filter((p) => p.json?.private)
96
- if (privates.length) {
97
- const names = privates.map((p) => p.name).join(', ')
98
- throw new Error(`Refusing to publish private packages: ${names}`)
99
- }
100
- }
101
-
102
- async function publishPackage(pkg: LoadedPackage, opts: PublishOptions = {}) {
103
- const args = ['publish', '--access', 'public']
104
-
105
- let tag = opts.tag
106
- if (!tag) {
107
- tag = inferTagFromVersion(pkg.version || '')
108
- }
109
- if (tag) args.push('--tag', tag)
110
-
111
- if (opts.dryRun) args.push('--dry-run')
112
- if (opts.provenance) args.push('--provenance')
113
-
114
- logPkg(pkg, `Publishing ${pkg.name}…`, colors.green)
115
- try {
116
- await run('pnpm', args, { cwd: pkg.path })
117
- logPkg(pkg, `${pkg.name} published.`, colors.green)
118
-
119
- const tagName = `${pkg.name}@${pkg.version}`
120
- const tagMessage = opts.releaseNotes
121
- ? `release ${pkg.version}\n\n${opts.releaseNotes}`
122
- : `release ${pkg.version}`
123
-
124
- await run('git', ['tag', '-a', tagName, '-m', tagMessage])
125
- await run('git', ['push', 'origin', tagName])
126
- } catch (err) {
127
- console.error(colors.red(`Publish failed for ${pkg.name}.`))
128
- console.error(
129
- colors.dim('To revert the version commit: git revert HEAD && git push'),
130
- )
131
- throw err
132
- }
133
- }
134
-
135
- async function applyVersionStrategy(
136
- strategy: VersionStrategy,
137
- targetPkg: LoadedPackage,
138
- packages: LoadedPackage[],
139
- opts: PublishOptions = {},
140
- ): Promise<{ changedPaths: string[]; commitMessage: string }> {
141
- if (strategy.mode === 'noop') {
142
- console.log('\nSkipping version bump (no version change selected).')
143
- return { changedPaths: [], commitMessage: '' }
144
- }
145
-
146
- if (strategy.mode === 'sync') {
147
- console.log()
148
- logGlobal('Syncing all package versions…', colors.cyan)
149
- await run('pnpm', ['sync', strategy.version])
150
- packages.forEach((pkg) => {
151
- pkg.version = strategy.version
152
- pkg.json.version = strategy.version
153
- })
154
- return {
155
- changedPaths: [
156
- 'package.json',
157
- ...packages.map((pkg) =>
158
- path.relative(process.cwd(), pkg.packageJsonPath),
159
- ),
160
- ],
161
- commitMessage: `chore(release): sync ${strategy.version}`,
162
- }
163
- }
164
-
165
- // mode === 'bump'
166
- const nextVersion = bumpVersion(
167
- targetPkg.version,
168
- strategy.bumpType,
169
- strategy.preid,
170
- )
171
- console.log(
172
- `\nUpdating ${formatPkgName(targetPkg)} version to ${colors.green(nextVersion)}`,
173
- )
174
- targetPkg.json.version = nextVersion
175
- targetPkg.version = nextVersion
176
- await writePackageJson(targetPkg.packageJsonPath, targetPkg.json)
177
- return {
178
- changedPaths: [path.relative(process.cwd(), targetPkg.packageJsonPath)],
179
- commitMessage: opts?.releaseNotes
180
- ? `chore(release): ${targetPkg.name}@${nextVersion} - ${opts.releaseNotes}`
181
- : `chore(release): ${targetPkg.name}@${nextVersion}`,
182
- }
183
- }
184
-
185
- function strategyFromOptions(
186
- targetPkg: LoadedPackage,
187
- selection: LoadedPackage[],
188
- opts?: PublishOptions,
189
- ): VersionStrategy | undefined {
190
- if (!opts?.nonInteractive) return undefined
191
- if (opts.syncVersion) {
192
- if (!isSemver(opts.syncVersion))
193
- throw new Error(`Invalid version "${opts.syncVersion}"`)
194
- return { mode: 'sync', version: opts.syncVersion }
195
- }
196
- if (opts.bumpType)
197
- return { mode: 'bump', bumpType: opts.bumpType, preid: opts.preid }
198
- return { mode: 'noop' }
199
- }
200
-
201
- function inferTagFromVersion(version: string): string | undefined {
202
- const match = version.match(/-([0-9A-Za-z-]+)(?:\.\d+)?$/)
203
- if (!match) return undefined
204
- const preid = match[1].toLowerCase()
205
- if (['alpha', 'beta', 'rc'].includes(preid)) return preid
206
- return 'next'
207
- }
208
-
209
- function inferPreidFromVersion(version: string): string | undefined {
210
- const match = version.match(/-([0-9A-Za-z-]+)/)
211
- return match?.[1]?.toLowerCase()
212
- }
213
-
214
- export async function promptVersionStrategy(
215
- targetPkg: LoadedPackage,
216
- selection: LoadedPackage[],
217
- opts?: PublishOptions,
218
- ): Promise<VersionStrategy> {
219
- const viaOpts = strategyFromOptions(targetPkg, selection, opts)
220
- if (viaOpts) return viaOpts
221
-
222
- console.log('\nCurrent package versions:')
223
- for (const pkg of selection) {
224
- const marker =
225
- selection.length === 1 && pkg.dirName === targetPkg.dirName ? '*' : '•'
226
- console.log(
227
- ` ${marker} ${formatPkgName(pkg)} ${pkg.dirName} ${colors.yellow(pkg.version)}`,
228
- )
229
- }
230
-
231
- console.log('\nSelect version strategy:')
232
- console.log(' 1) Patch')
233
- console.log(' 2) Minor')
234
- console.log(' 3) Major')
235
- console.log(' 4) Pre-release (alpha / beta / rc)')
236
- console.log(' 5) Sync packages')
237
- console.log(' 6) No version change')
238
-
239
- const choice = await promptSingleKey('Choice: ', (key) => {
240
- if (['1', '2', '3', '4', '5', '6'].includes(key)) return key
241
- return undefined
242
- })
243
- console.log(choice)
244
-
245
- // Sync
246
- if (choice === '5') {
247
- const desired = await askLine('Enter unified version: ')
248
- if (!isSemver(desired)) throw new Error(`Invalid version "${desired}"`)
249
- return { mode: 'sync', version: desired }
250
- }
251
-
252
- // No version change
253
- if (choice === '6') {
254
- const ans = await promptYesNoAll('Publish without changing any versions?')
255
- if (ans === 'no') {
256
- console.log('Aborting.')
257
- process.exit(0)
258
- }
259
- return { mode: 'noop' }
260
- }
261
-
262
- // Pre-release submenu
263
- let preid: string | undefined
264
- let bumpType: BumpType | undefined
265
-
266
- if (choice === '4') {
267
- const currentVersion = targetPkg.version || '?'
268
- const defaultPreid = inferPreidFromVersion(currentVersion) || 'alpha'
269
- const preview = (type: BumpType) => {
270
- try {
271
- return bumpVersion(currentVersion, type, defaultPreid)
272
- } catch {
273
- return '?'
274
- }
275
- }
276
-
277
- console.log('\nSelect pre-release bump type:')
278
- console.log(` 1) prepatch (${currentVersion} -> ${preview('prepatch')})`)
279
- console.log(` 2) preminor (${currentVersion} -> ${preview('preminor')})`)
280
- console.log(` 3) premajor (${currentVersion} -> ${preview('premajor')})`)
281
- console.log(
282
- ` 4) prerelease (${currentVersion} -> ${preview('prerelease')})`,
283
- )
284
-
285
- const preChoice = await promptSingleKey('Choice: ', (key) => {
286
- if (['1', '2', '3', '4'].includes(key)) return key
287
- return undefined
288
- })
289
- console.log(preChoice)
290
-
291
- bumpType = preBumpFromChoice(preChoice)
292
- if (!bumpType) throw new Error('Invalid pre-release selection.')
293
-
294
- const rawPreid = await askLine(
295
- 'Pre-release identifier (e.g. alpha, beta, rc) [alpha]: ',
296
- )
297
- preid = (rawPreid.trim() || 'alpha').toLowerCase()
298
- } else {
299
- // Regular patch / minor / major
300
- bumpType = bumpMap[choice] as BumpType | undefined
301
- }
302
-
303
- if (!bumpType) throw new Error('Invalid selection.')
304
-
305
- // Preview what will happen
306
- if (selection.length === 1) {
307
- const proposed = bumpVersion(targetPkg.version, bumpType, preid)
308
- console.log(
309
- `\nTarget package: ${formatPkgName(targetPkg)} -> ${colors.green(proposed)}`,
310
- )
311
- const others = selection.filter((pkg) => pkg.dirName !== targetPkg.dirName)
312
- if (others.length) {
313
- console.log('Other packages:')
314
- others.forEach((pkg) => {
315
- console.log(` - ${formatPkgName(pkg)} ${colors.yellow(pkg.version)}`)
316
- })
317
- }
318
- } else {
319
- console.log(
320
- `\nApplying a ${bumpType}${
321
- preid ? ` (${preid})` : ''
322
- } bump to all selected packages:`,
323
- )
324
- selection.forEach((pkg) => {
325
- const nextVersion = bumpVersion(pkg.version, bumpType!, preid)
326
- const arrow = nextVersion === pkg.version ? '─' : '→'
327
- console.log(
328
- ` - ${formatPkgName(pkg)} ${colors.yellow(pkg.version)} ${arrow} ${colors.green(
329
- nextVersion,
330
- )}`,
331
- )
332
- })
333
- }
334
-
335
- const confirm = await promptYesNoAll(
336
- selection.length === 1
337
- ? `Apply ${bumpType}${preid ? ` (${preid})` : ''} bump to ${targetPkg.name}?`
338
- : `Apply ${bumpType}${preid ? ` (${preid})` : ''} bump to all selected packages?`,
339
- )
340
- if (confirm === 'no') {
341
- console.log('Aborting.')
342
- process.exit(0)
343
- }
344
-
345
- return { mode: 'bump', bumpType, preid }
346
- }
347
-
348
- export async function releaseSingle(
349
- targetPkg: LoadedPackage,
350
- packages: LoadedPackage[],
351
- opts: PublishOptions = {},
352
- ) {
353
- await ensureNpmAuth()
354
- await refreshPackagesFromDisk([targetPkg])
355
- ensureNotPrivate([targetPkg])
356
-
357
- console.log(`\n${formatPkgName(targetPkg)} ${colors.dim('(single release)')}`)
358
- const strategy = await promptVersionStrategy(targetPkg, [targetPkg], opts)
359
- const { changedPaths, commitMessage } = await applyVersionStrategy(
360
- strategy,
361
- targetPkg,
362
- packages,
363
- opts,
364
- )
365
- await stageCommitPush(changedPaths, commitMessage)
366
- await publishPackage(targetPkg, opts)
367
- }
368
-
369
- export async function releaseMultiple(
370
- targets: LoadedPackage[],
371
- packages: LoadedPackage[],
372
- opts: PublishOptions = {},
373
- ) {
374
- await ensureNpmAuth()
375
- await refreshPackagesFromDisk(targets)
376
- ensureNotPrivate(targets)
377
-
378
- console.log(`\n🚀 ${'*'} Publishing all selected packages`)
379
- const strategy = await promptVersionStrategy(targets[0], targets, opts)
380
- let changedPaths: string[] = []
381
- let commitMessage = ''
382
-
383
- if (strategy.mode === 'sync') {
384
- const result = await applyVersionStrategy(
385
- strategy,
386
- targets[0],
387
- packages,
388
- opts,
389
- )
390
- changedPaths = result.changedPaths
391
- commitMessage = result.commitMessage
392
- } else if (strategy.mode === 'bump') {
393
- for (const pkg of targets) {
394
- const result = await applyVersionStrategy(strategy, pkg, packages, opts)
395
- changedPaths.push(...result.changedPaths)
396
- }
397
- commitMessage = `chore(release): ${targets.map((p) => `${p.name}@${p.version}`).join(', ')}`
398
- }
399
-
400
- if (changedPaths.length || commitMessage) {
401
- await stageCommitPush(
402
- changedPaths,
403
- commitMessage || `chore(release): publish ${targets.length} package(s)`,
404
- )
405
- }
406
-
407
- for (const pkg of targets) {
408
- await publishPackage(pkg, opts)
409
- }
410
- }
package/src/semver.ts DELETED
@@ -1,27 +0,0 @@
1
- // src/semver.js
2
- import { inc, valid, } from 'semver'
3
-
4
- export type BumpType =
5
- | 'patch'
6
- | 'minor'
7
- | 'major'
8
- | 'prepatch'
9
- | 'preminor'
10
- | 'premajor'
11
- | 'prerelease'
12
-
13
- export function bumpVersion(version: string, type: BumpType, preid?: string) {
14
- let next
15
- if (preid) {
16
- next = inc(version, type as any, preid)
17
- } else {
18
- next = inc(version, type as any)
19
- }
20
- if (!next)
21
- throw new Error(`Cannot bump invalid version "${version}" by "${type}"`)
22
- return next
23
- }
24
-
25
- export function isSemver(version: string) {
26
- return Boolean(valid(version))
27
- }
@@ -1,213 +0,0 @@
1
- #!/usr/bin/env node
2
- import { readFile, writeFile, readdir } from 'node:fs/promises'
3
- import { existsSync } from 'node:fs'
4
- import path from 'node:path'
5
- import { pathToFileURL } from 'node:url'
6
-
7
- const rootDir = process.cwd()
8
- const ansi = (code) => (text) => `\x1b[${code}m${text}\x1b[0m`
9
- const colors = {
10
- cyan: ansi(36),
11
- green: ansi(32),
12
- yellow: ansi(33),
13
- magenta: ansi(35),
14
- red: ansi(31),
15
- dim: ansi(2),
16
- }
17
-
18
- const palette = ['cyan', 'green', 'yellow', 'magenta', 'red']
19
-
20
- function manifestFilePath() {
21
- return path.join(rootDir, 'scripts', 'packages.mjs')
22
- }
23
-
24
- function normalizeManifestPath(value) {
25
- const absolute = path.resolve(rootDir, value || '')
26
- let relative = path.relative(rootDir, absolute)
27
- if (!relative) return ''
28
- relative = relative.replace(/\\/g, '/')
29
- return relative.replace(/^(?:\.\/)+/, '')
30
- }
31
-
32
- function colorFromSeed(seed) {
33
- const normalized = `${seed}`.trim() || 'package'
34
- let hash = 0
35
- for (let i = 0; i < normalized.length; i++) {
36
- hash = (hash * 31 + normalized.charCodeAt(i)) >>> 0
37
- }
38
- return palette[hash % palette.length]
39
- }
40
-
41
- function isManifestMissing(error) {
42
- if (typeof error !== 'object' || error === null) return false
43
- const code = error.code
44
- return code === 'ERR_MODULE_NOT_FOUND' || code === 'ENOENT'
45
- }
46
-
47
- async function loadWorkspaceManifest() {
48
- const manifestPath = manifestFilePath()
49
- try {
50
- const manifestModule = await import(pathToFileURL(manifestPath).href)
51
- if (Array.isArray(manifestModule?.PACKAGE_MANIFEST)) {
52
- return manifestModule.PACKAGE_MANIFEST
53
- }
54
- } catch (error) {
55
- if (isManifestMissing(error)) return undefined
56
- throw error
57
- }
58
- return undefined
59
- }
60
-
61
- async function inferManifestFromWorkspace() {
62
- try {
63
- const packagesDir = path.join(rootDir, 'packages')
64
- const entries = await readdir(packagesDir, { withFileTypes: true })
65
- const manifest = []
66
- for (const entry of entries) {
67
- if (!entry.isDirectory()) continue
68
- const pkgJsonPath = path.join(packagesDir, entry.name, 'package.json')
69
- try {
70
- const raw = await readFile(pkgJsonPath, 'utf8')
71
- const json = JSON.parse(raw)
72
- const pkgName = (json.name || entry.name).trim() || entry.name
73
- manifest.push({
74
- name: pkgName,
75
- path: normalizeManifestPath(path.relative(rootDir, path.join(packagesDir, entry.name))),
76
- color: colorFromSeed(pkgName),
77
- })
78
- } catch {
79
- continue
80
- }
81
- }
82
- return manifest
83
- } catch {
84
- return []
85
- }
86
- }
87
-
88
- function mergeManifestEntries(inferred, overrides) {
89
- const normalizedOverrides = new Map()
90
- overrides?.forEach((entry) => {
91
- const normalized = normalizeManifestPath(entry.path)
92
- if (!normalized) return
93
- normalizedOverrides.set(normalized, { ...entry, path: normalized })
94
- })
95
-
96
- const merged = []
97
- for (const baseEntry of inferred) {
98
- const normalized = normalizeManifestPath(baseEntry.path)
99
- const override = normalizedOverrides.get(normalized)
100
- if (override) {
101
- normalizedOverrides.delete(normalized)
102
- const name = override.name || baseEntry.name
103
- const color = override.color ?? baseEntry.color ?? colorFromSeed(name)
104
- merged.push({ name, path: normalized, color })
105
- } else {
106
- merged.push({ ...baseEntry, path: normalized })
107
- }
108
- }
109
-
110
- normalizedOverrides.forEach((entry) => {
111
- const name = entry.name || path.basename(entry.path) || 'package'
112
- const color = entry.color ?? colorFromSeed(name)
113
- merged.push({ name, path: entry.path, color })
114
- })
115
-
116
- return merged
117
- }
118
-
119
- const registerPackageEntry = (map, pkgPath, entry) => {
120
- if (!map.has(pkgPath)) {
121
- map.set(pkgPath, entry)
122
- }
123
- }
124
-
125
- async function collectPackageEntries() {
126
- const packagesDir = path.join(rootDir, 'packages')
127
- const records = new Map()
128
-
129
- registerPackageEntry(records, path.join(rootDir, 'package.json'), {
130
- name: 'workspace root',
131
- pkgPath: path.join(rootDir, 'package.json'),
132
- color: 'magenta',
133
- })
134
-
135
- const [workspaceManifest, inferred] = await Promise.all([
136
- loadWorkspaceManifest(),
137
- inferManifestFromWorkspace(),
138
- ])
139
- const manifestEntries = mergeManifestEntries(inferred, workspaceManifest)
140
-
141
- for (const manifestEntry of manifestEntries) {
142
- if (!manifestEntry.path) continue
143
- const pkgPath = path.join(rootDir, manifestEntry.path, 'package.json')
144
- registerPackageEntry(records, pkgPath, {
145
- name: manifestEntry.name,
146
- pkgPath,
147
- color: manifestEntry.color ?? colorFromSeed(manifestEntry.name),
148
- })
149
- }
150
-
151
- try {
152
- const entries = await readdir(packagesDir, { withFileTypes: true })
153
- for (const entry of entries) {
154
- if (!entry.isDirectory()) continue
155
- const pkgPath = path.join(packagesDir, entry.name, 'package.json')
156
- registerPackageEntry(records, pkgPath, {
157
- name: entry.name,
158
- pkgPath,
159
- color: colorFromSeed(entry.name),
160
- })
161
- }
162
- } catch (error) {
163
- console.error(`Failed to read packages directory: ${error}`)
164
- }
165
-
166
- return Array.from(records.values())
167
- }
168
-
169
- async function main() {
170
- const version = process.argv[2]
171
-
172
- if (!version) {
173
- console.error('Usage: pnpm sync <version>')
174
- process.exitCode = 1
175
- return
176
- }
177
-
178
- const semverPattern = /^\d+\.\d+\.\d+(?:[-+].*)?$/
179
- if (!semverPattern.test(version)) {
180
- console.error(`Invalid version "${version}". Expected semver (e.g. 1.6.0).`)
181
- process.exitCode = 1
182
- return
183
- }
184
-
185
- const packageEntries = await collectPackageEntries()
186
-
187
- await Promise.all(
188
- packageEntries.map(async (entry) => {
189
- if (!existsSync(entry.pkgPath)) {
190
- console.warn(
191
- `${colors[entry.color ?? 'cyan']('●')} ${colors.yellow(
192
- `Skipping missing package file: ${path.relative(rootDir, entry.pkgPath)}`,
193
- )}`,
194
- )
195
- return
196
- }
197
- const raw = await readFile(entry.pkgPath, 'utf8')
198
- const json = JSON.parse(raw)
199
- const previousVersion = json.version ?? 'unknown'
200
- json.version = version
201
- const formatted = `${JSON.stringify(json, null, 2)}\n`
202
- await writeFile(entry.pkgPath, formatted)
203
- console.log(
204
- `${colors[entry.color ?? 'cyan']('●')} ${colors.cyan('[sync]')} ${path.relative(rootDir, entry.pkgPath)} ${colors.dim(`${previousVersion} -> ${version}`)}`,
205
- )
206
- }),
207
- )
208
- }
209
-
210
- main().catch((error) => {
211
- console.error(error)
212
- process.exitCode = 1
213
- })
@@ -1,11 +0,0 @@
1
- // src/utils/colors.js
2
- const ansi = (code: number) => (text: string) => `\x1b[${code}m${text}\x1b[0m`
3
- export const colors = {
4
- cyan: ansi(36),
5
- green: ansi(32),
6
- yellow: ansi(33),
7
- magenta: ansi(35),
8
- red: ansi(31),
9
- bold: ansi(1),
10
- dim: ansi(2),
11
- }
package/src/utils/log.ts DELETED
@@ -1,42 +0,0 @@
1
- // src/utils/log.js
2
- import { colors } from './colors.js'
3
-
4
- export type PackageColor = 'cyan' | 'green' | 'yellow' | 'magenta' | 'red'
5
- export const defaultPackageColor: PackageColor = 'cyan'
6
- export const globalEmoji = '🚀'
7
-
8
- export interface LoadedPackage {
9
- dirName: string
10
- path: string
11
- packageJsonPath: string
12
- json: Record<string, any>
13
- version: string
14
- name: string
15
- color: PackageColor
16
- substitute: string
17
- }
18
-
19
- export const formatPkgName = (pkg: LoadedPackage) => {
20
- const primary = pkg.substitute
21
- const displayName = pkg.name ?? pkg.dirName
22
- const fileLabel = pkg.dirName
23
- const colorizer = colors[pkg.color ?? defaultPackageColor]
24
- return `${colorizer(colors.bold(primary))} ${colors.dim(
25
- `(${displayName}) [${fileLabel}]`,
26
- )}`
27
- }
28
-
29
- export const logPkg = (
30
- pkg: LoadedPackage,
31
- message: string,
32
- colorizer = colors.cyan,
33
- ) => {
34
- const label = colors[pkg.color ?? defaultPackageColor](pkg.substitute)
35
- console.log(`${label} ${colorizer(message)}`)
36
- }
37
-
38
- export const logGlobal = (message: string, colorizer = colors.magenta) => {
39
- console.log(`${globalEmoji} ${colorizer(message)}`)
40
- }
41
-
42
- export { colors }