From c4bdecbaa7a07c4252fc3d1573f34e73cb5edc39 Mon Sep 17 00:00:00 2001 From: Christian Preston Date: Tue, 6 Feb 2024 17:42:43 -0500 Subject: [PATCH] feat: `pm-install` generator (#9) Co-authored-by: Pooya Parsa Co-authored-by: uncenter <47499684+uncenter@users.noreply.github.com> --- README.md | 59 +++++++++++++++++++++++++++--------- package.json | 2 ++ playground/README.md | 25 ++++++++++++++- pnpm-lock.yaml | 16 ++++++---- src/generators/index.ts | 2 ++ src/generators/pm-install.ts | 47 ++++++++++++++++++++++++++++ 6 files changed, 130 insertions(+), 21 deletions(-) create mode 100644 src/generators/pm-install.ts diff --git a/README.md b/README.md index d92a957..160d0da 100644 --- a/README.md +++ b/README.md @@ -49,27 +49,20 @@ There are several available generators for automd each supporting different argu See [open issues](https://github.com/unjs/automd/issues?q=is%3Aopen+is%3Aissue+label%3Agenerator) for proposed generators and feel free to suggest any generator ideas to be included! -### `jsdocs` Generator +### `jsdocs` -jsdocs generator can automatically read through your code and extract and sync documentation of function exports leveraging JSDocs and TypeScript hints. +The `jsdocs` generator can automatically read through your code and extract and sync documentation of function exports leveraging JSDocs and TypeScript hints. Internally it uses [untyped](https://untyped.unjs.io/) and [jiti](https://github.com/unjs/jiti) loader for JSDocs parsing and TypeScript support. #### Usage -```md - - -... - - -``` + + (make sure to have some utility exports in `src/index.ts` annotated with JSDocs.) -**Example Output:** - - ## Utils +**Updated Result:** @@ -84,11 +77,49 @@ Internally it uses [untyped](https://untyped.unjs.io/) and [jiti](https://github -### Args supported for `jsdocs` +#### Arguments - `src`: Path to the source file. The default is `./src/index` and can be omitted. - `headingLevel`: Nested level for markdown group headings (default is `2` => `##`). Note: Each function uses `headingLevel+1` for the title in nested levels. -- `group`: Only render function exportes annotated with `@group name`. By default, there is no group filter. Value can be a string or array of strings. +- `group`: Only render function exports annotated with `@group name`. By default, there is no group filter. Value can be a string or an array of strings. + +### `pm-install` + +The `pm-install` generator generates commands for several JavaScript package managers. + +#### Usage + + + + +**Updated Result:** + + + + ```sh + # ✨ Auto-detect + npx nypm i -D package-name + + # npm + npm install -D package-name + + # yarn + yarn add -D package-name + + # pnpm + pnpm install -D package-name + + # bun + bun install -D package-name + ``` + + + +#### Arguments + +- `name`: The package name (by default tries to read from the `name` field in `package.json`). +- `dev`: Install as a dev dependency. (defaults to `false`). +- `auto`: Auto-detect package manager using [unjs/nypm](https://github.com/unjs/nypm#-nypm). (defaults to `true`). ## Development diff --git a/package.json b/package.json index 9784aa7..ddbb575 100644 --- a/package.json +++ b/package.json @@ -37,6 +37,8 @@ "consola": "^3.2.3", "destr": "^2.0.2", "magic-string": "^0.30.7", + "omark": "^0.1.0", + "pkg-types": "^1.0.3", "scule": "^1.3.0", "untyped": "^1.4.2" }, diff --git a/playground/README.md b/playground/README.md index 555d370..a91b2c5 100644 --- a/playground/README.md +++ b/playground/README.md @@ -1,8 +1,31 @@ +## Usage + + + +```sh +# ✨ Auto-detect +npx nypm i -D package-name + +# npm +npm install -D package-name + +# yarn +yarn add -D package-name + +# pnpm +pnpm install -D package-name + +# bun +bun install -D package-name +``` + + + ## Utils -#### `add(a, b)` +### `add(a, b)` Adds two numbers together. diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 3d01fce..57e807d 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -17,6 +17,12 @@ dependencies: magic-string: specifier: ^0.30.7 version: 0.30.7 + omark: + specifier: ^0.1.0 + version: 0.1.0 + pkg-types: + specifier: ^1.0.3 + version: 1.0.3 scule: specifier: ^1.3.0 version: 1.3.0 @@ -821,7 +827,6 @@ packages: resolution: {integrity: sha512-Y9rRfJG5jcKOE0CLisYbojUjIrIEE7AGMzA/Sm4BslANhbS+cDMpgBdcPT91oJ7OuJ9hYJBx59RjbhxVnrF8Xg==} engines: {node: '>=0.4.0'} hasBin: true - dev: true /ajv@6.12.6: resolution: {integrity: sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==} @@ -2656,7 +2661,6 @@ packages: /jsonc-parser@3.2.1: resolution: {integrity: sha512-AilxAyFOAcK5wA1+LeaySVBrHsGQvUFCDWXKpZjzaL0PqW+xfBOttn8GNtWKFWqneyMZj41MWF9Kl6iPWLwgOA==} - dev: true /jsonfile@6.1.0: resolution: {integrity: sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==} @@ -2855,7 +2859,6 @@ packages: pathe: 1.1.2 pkg-types: 1.0.3 ufo: 1.3.2 - dev: true /mri@1.2.0: resolution: {integrity: sha512-tzzskb3bG8LvYGFF/mDTpq3jpI6Q9wc3LEmBaghu+DdCssd1FakN7Bc0hVNmEyGq1bq3RgfkCb3cmQLpNPOroA==} @@ -2998,6 +3001,10 @@ packages: resolution: {integrity: sha512-zuHHiGTYTA1sYJ/wZN+t5HKZaH23i4yI1HMwbuXm24Nid7Dv0KcuRlKoNKS9UNfAVSBlnGLcuQrnOKWOZoEGaw==} dev: true + /omark@0.1.0: + resolution: {integrity: sha512-l+7hOfsjru88QuW7E937KH7BSz99NownkNTGigi+e4JzeSSCosMp2v3eVW1wdmgm99pFbzaUVg1kiT2V0QvvtQ==} + dev: false + /once@1.4.0: resolution: {integrity: sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==} dependencies: @@ -3121,7 +3128,6 @@ packages: /pathe@1.1.2: resolution: {integrity: sha512-whLdWMYL2TwI08hn8/ZqAbrVemu0LNaNNJZX73O6qaIdCTfXutsLhMkjdENX0qhsQ9uIimo4/aQOmXkoon2nDQ==} - dev: true /perfect-debounce@1.0.0: resolution: {integrity: sha512-xCy9V055GLEqoFaHoC1SoLIaLmWctgCUaBaWxDZ7/Zx4CTyX7cJQLJOok/orfjZAh9kEYpjJa4d0KcJmCbctZA==} @@ -3141,7 +3147,6 @@ packages: jsonc-parser: 3.2.1 mlly: 1.5.0 pathe: 1.1.2 - dev: true /pluralize@8.0.0: resolution: {integrity: sha512-Nc3IT5yHzflTfbjgqWcCPpo7DaKy4FnpB0l/zCAW0Tc7jxAiuqSxHasntB3D7887LSrA93kDJ9IXovxJYxyLCA==} @@ -3977,7 +3982,6 @@ packages: /ufo@1.3.2: resolution: {integrity: sha512-o+ORpgGwaYQXgqGDwd+hkS4PuZ3QnmqMMxRuajK/a38L6fTpcE5GPIfrf+L/KemFzfUpeUQc1rRS1iDBozvnFA==} - dev: true /unbox-primitive@1.0.2: resolution: {integrity: sha512-61pPlCD9h51VoreyJ0BReideM3MDKMKnh6+V9L08331ipq6Q8OFXZYiqP6n/tbHx4s5I9uRhcye6BrbkizkBDw==} diff --git a/src/generators/index.ts b/src/generators/index.ts index b15c0ed..e9cec19 100644 --- a/src/generators/index.ts +++ b/src/generators/index.ts @@ -1,6 +1,8 @@ import { Generator } from "../generator"; import jsdocs from "./jsdocs"; +import pmInstall from "./pm-install"; export default { jsdocs, + "pm-install": pmInstall, } as Record; diff --git a/src/generators/pm-install.ts b/src/generators/pm-install.ts new file mode 100644 index 0000000..c933c25 --- /dev/null +++ b/src/generators/pm-install.ts @@ -0,0 +1,47 @@ +import { readPackageJSON } from "pkg-types"; +import { codeBlock } from "omark"; +import { defineGenerator } from "../generator"; + +export default defineGenerator({ + name: "pm-install", + async generate({ options, args }) { + const name = args.name || (await inferPackageName(options.dir)); + + if (!name) { + return { + contents: "", + }; + } + + const pkgInstalls = [ + ["npm", "install"], + ["yarn", "add"], + ["pnpm", "install"], + ["bun", "install"], + ]; + + // TODO: support noAuto/no-auto + if (args.auto ?? true) { + pkgInstalls.unshift(["npx nypm", "i"]); + } + + return { + contents: codeBlock( + pkgInstalls + .map( + ([cmd, install]) => + `# ${cmd.includes("nypm") ? "✨ Auto-detect" : cmd}\n${cmd} ${install}${args.dev ? " -D" : ""} ${name}`, + ) + .join("\n\n"), + "sh", + ), + }; + }, +}); + +async function inferPackageName(dir: string) { + const pkgName = await readPackageJSON(dir) + .then((pkg) => pkg?.name) + .catch(() => undefined); + return pkgName || process.env.npm_package_name; +}