pm.ts63 lines · main
| 1 | export type Pm = 'npm' | 'pnpm' | 'yarn' | 'bun'; |
| 2 | export const PMS: readonly Pm[] = ['npm', 'pnpm', 'yarn', 'bun']; |
| 3 | |
| 4 | export type PmBlock = Record<Pm, string>; |
| 5 | |
| 6 | /** |
| 7 | * Run an already-installed bin (from ./node_modules/.bin) using each PM's |
| 8 | * native shortcut. Lines are prefixed with `$ ` to match the existing docs |
| 9 | * code style. |
| 10 | */ |
| 11 | export function pmExec(...lines: string[]): PmBlock { |
| 12 | const prefix: PmBlock = { |
| 13 | npm: 'npx', |
| 14 | pnpm: 'pnpm', |
| 15 | yarn: 'yarn', |
| 16 | bun: 'bunx', |
| 17 | }; |
| 18 | const out = {} as PmBlock; |
| 19 | for (const m of PMS) { |
| 20 | out[m] = lines.map((l) => `$ ${prefix[m]} ${l}`).join('\n'); |
| 21 | } |
| 22 | return out; |
| 23 | } |
| 24 | |
| 25 | /** |
| 26 | * One-shot remote execution without a prior install (npx / dlx / bunx style). |
| 27 | */ |
| 28 | export function pmDlx(cmd: string): PmBlock { |
| 29 | return { |
| 30 | npm: `$ npx ${cmd}`, |
| 31 | pnpm: `$ pnpm dlx ${cmd}`, |
| 32 | yarn: `$ yarn dlx ${cmd}`, |
| 33 | bun: `$ bunx ${cmd}`, |
| 34 | }; |
| 35 | } |
| 36 | |
| 37 | /** |
| 38 | * Install one or more packages. `dev: true` switches to a dev-dep install. |
| 39 | */ |
| 40 | export function pmInstall(pkgs: string, options: { dev?: boolean } = {}): PmBlock { |
| 41 | const dev = options.dev ?? false; |
| 42 | return { |
| 43 | npm: `$ npm install ${dev ? '-D ' : ''}${pkgs}`, |
| 44 | pnpm: `$ pnpm add ${dev ? '-D ' : ''}${pkgs}`, |
| 45 | yarn: `$ yarn add ${dev ? '-D ' : ''}${pkgs}`, |
| 46 | bun: `$ bun add ${dev ? '-d ' : ''}${pkgs}`, |
| 47 | }; |
| 48 | } |
| 49 | |
| 50 | /** Same literal line across every PM — for things like `mkdir` that don't vary. */ |
| 51 | export function pmPlain(...lines: string[]): PmBlock { |
| 52 | const body = lines.join('\n'); |
| 53 | return { npm: body, pnpm: body, yarn: body, bun: body }; |
| 54 | } |
| 55 | |
| 56 | /** Concatenate several blocks vertically, preserving each PM's own body. */ |
| 57 | export function pmJoin(...blocks: PmBlock[]): PmBlock { |
| 58 | const out = {} as PmBlock; |
| 59 | for (const m of PMS) { |
| 60 | out[m] = blocks.map((b) => b[m]).join('\n'); |
| 61 | } |
| 62 | return out; |
| 63 | } |