Skip to content
Open
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
95 changes: 49 additions & 46 deletions cli/src/npm-client.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import crypto from 'node:crypto'
import process from 'node:process'
import { execFile } from 'node:child_process'
import { promisify } from 'node:util'
import { mkdtempDisposable, writeFile } from 'node:fs/promises'
import { mkdtemp, writeFile, rm } from 'node:fs/promises'
import { tmpdir } from 'node:os'
import { join } from 'node:path'
import * as v from 'valibot'
Expand Down Expand Up @@ -572,54 +572,57 @@ export async function packageInit(
): Promise<NpmExecResult> {
validatePackageName(name)

// Let Node clean up the temp directory automatically when this scope exits.
await using tempDir = await mkdtempDisposable(join(tmpdir(), 'npmx-init-'))

// Determine access type based on whether it's a scoped package
const isScoped = name.startsWith('@')
const access = isScoped ? 'public' : undefined

// Create minimal package.json
const packageJson = {
name,
version: '0.0.0',
description: `Placeholder for ${name}`,
main: 'index.js',
scripts: {},
keywords: [],
author: author ? `${author} (https://www.npmjs.com/~${author})` : '',
license: 'UNLICENSED',
private: false,
...(access && { publishConfig: { access } }),
}
const tempDirPath = await mkdtemp(join(tmpdir(), 'npmx-init-'))

await writeFile(join(tempDir.path, 'package.json'), JSON.stringify(packageJson, null, 2))
try {
// Determine access type based on whether it's a scoped package
const isScoped = name.startsWith('@')
const access = isScoped ? 'public' : undefined

// Create minimal package.json
const packageJson = {
name,
version: '0.0.0',
description: `Placeholder for ${name}`,
main: 'index.js',
scripts: {},
keywords: [],
author: author ? `${author} (https://www.npmjs.com/~${author})` : '',
license: 'UNLICENSED',
private: false,
...(access && { publishConfig: { access } }),
}

// Create empty index.js
await writeFile(join(tempDir.path, 'index.js'), '// Placeholder\n')
await writeFile(join(tempDirPath, 'package.json'), JSON.stringify(packageJson, null, 2))

// Build npm publish args
const args = ['publish']
if (access) {
args.push('--access', access)
}
// Create empty index.js
await writeFile(join(tempDirPath, 'index.js'), '// Placeholder\n')

const displayCmd = options?.otp
? ['npm', ...args, '--otp', '******'].join(' ')
: ['npm', ...args].join(' ')
logCommand(`${displayCmd} (in temp dir for ${name})`)

const result = await execNpm(args, { ...options, cwd: tempDir.path, silent: true })

if (result.exitCode === 0) {
logSuccess(`Published ${name}@0.0.0`)
} else if (result.requiresOtp) {
logError('OTP required')
} else if (result.authFailure) {
logError('Authentication required - please run "npm login" and restart the connector')
} else {
logError(result.stderr.split('\n')[0] || 'Command failed')
}
// Build npm publish args
const args = ['publish']
if (access) {
args.push('--access', access)
}

return result
const displayCmd = options?.otp
? ['npm', ...args, '--otp', '******'].join(' ')
: ['npm', ...args].join(' ')
logCommand(`${displayCmd} (in temp dir for ${name})`)

const result = await execNpm(args, { ...options, cwd: tempDirPath, silent: true })

if (result.exitCode === 0) {
logSuccess(`Published ${name}@0.0.0`)
} else if (result.requiresOtp) {
logError('OTP required')
} else if (result.authFailure) {
logError('Authentication required - please run "npm login" and restart the connector')
} else {
logError(result.stderr.split('\n')[0] || 'Command failed')
}

return result
} finally {
await rm(tempDirPath, { recursive: true, force: true })
}
Comment thread
coderabbitai[bot] marked this conversation as resolved.
Outdated
}
Loading