@papit/create
v0.0.12
Published
Scaffolds papit packages, components and monorepo projects from templates, interactively or through flags. Run it inside a papit workspace to add a package or component, or outside one to start a new project.
Maintainers
Readme
@papit/create
Scaffolds papit packages, components and monorepo projects from templates, interactively or through flags. Run it inside a papit workspace to add a package or component, or outside one to start a new project.
Installation
No install needed:
npm create @papitIt also installs as a dev dependency with the papit-create bin:
npm install -D @papit/createUsage
Pick a runner from a menu:
npm create @papitGo straight to a runner (npm needs the -- to pass the flags on):
npm create @papit -- --package
npm create @papit -- --component
npm create @papit -- --projectThe papit repo root wires it up as npm run create:
{
"scripts": {
"create": "npm create @papit -- --package --html-prefix=pap"
}
}Fully non-interactive, from inside a workspace:
npm create @papit -- --package=node --name=my-tool --description="Does a thing." --agreeThe folder under packages/ is still picked from a menu.
Outside a papit workspace, it always runs the project runner.
CLI flags
| Flag | Runner | Description |
| --- | --- | --- |
| --package[=<template>] | all | Run the package runner. With a value, it's the template too (browser, game, node, theme, web-component or a custom one). |
| --component | all | Run the component runner. |
| --project | all | Run the project runner. |
| --showcase | all | Run the showcase runner (experimental, see below). |
| --<custom> | all | Run a custom runner from bin/runners/<custom>/. |
| --type=<template> | package, component | Template to use, when --package has no value. |
| --name=<name> | package, component, project | Name. Spaces and - separate words: my button becomes my-button / MyButton. |
| --description=<text> | package, project | Description for package.json and the README. |
| --html-prefix=<prefix> | package, component, showcase | Tag prefix for web components (pap gives pap-<name>). Falls back to the package's then the root's papit.htmlprefix, otherwise prompts. |
| --agree | package, component | Yes to everything: folder creation, git commit and npm install. |
| --commit | package, component | Commit the result without asking. |
| --install | package | Run npm install without asking. |
| --yes / --no | package | Answer the commit and install questions. |
| --location=<path> | project | Where to create the project. Default: prompted, then <path>/<name>. |
| --license=<id> | project | License for the generated package.jsons. Default MIT. |
| --skip-git | project | Don't git init and commit. |
| --verbose, --debug | all | Log levels, see @papit/arguments. |
Runners
package
- Pick or create a folder under
packages/(--agreeskips the creation confirm). - Pick a template, unless
--package=<template>or--typenames one. - For a web component, settle the html prefix. When the root has none, it offers to save yours as the root's
papit.htmlprefix. - Ask for name and description. The name must not already exist in the workspace (
<scope>/<name>). - Copy the template into
<folder>/<name>and replace the template variables..gitkeepfiles are dropped. - Run the component runner for a first component with the package's own name, using the component template of the same type.
- Install and commit (
add: <scope>/<name> package), when agreed.
component
Adds a component to the package you're in. The template is the package's papit.type, then --package / --type, otherwise prompted. It registers the component under papit.components in the package's package.json, then copies each top-level template folder:
| Template folder | Goes to |
| --- | --- |
| src | src/ when it's empty, otherwise src/components/<name>/ |
| tests, views, others | <folder>/<name>/ |
The first component of a new package lands directly in src/ and in views/experiment/. Commits as add: <name> component when agreed.
project
Creates a new papit monorepo from the project template: prompts for name, description and location, asks before replacing an existing folder, copies the template, then git init, commits (init: <name> initialized) and runs npm install. The root package is named @<name>/root.
showcase
Experimental. For every web-component, game and theme package in the workspace whose first view isn't views/showcase, it generates one from asset/showcase-templates/individual, with a tab per existing view (--view-filter, default showcase, raw, experiment).
Custom runners
Any folder in <workspace-root>/bin/runners/ with a runner.js becomes a runner, listed in the menu and selectable as --<folder>. The names package, component, project and showcase are taken.
// bin/runners/release-notes/runner.js
import { Arguments } from "@papit/arguments";
import { Information } from "@papit/information";
export default async function () {
console.log(Information.root.location, Arguments.string("since"));
}The default export is called with no arguments. Read flags and the workspace through @papit/arguments and @papit/information.
Custom templates
| Location | Requirement |
| --- | --- |
| bin/runners/package/<template>/ | Must contain a package.json. |
| bin/runners/component/<template>/ | Top-level folders are copied as in the component runner. |
They're listed next to the built-in ones and selected by name. The project runner has no custom templates.
Package templates
Every package template has package.json, README.md, tsconfig.json, tsconfig.prod.json, .gitignore and asset/translations/en.json. Scripts include build (npx @papit/build), test, start and component.
| Template | papit.type | Gets |
| --- | --- | --- |
| browser | browser | Playwright tests, asset/icons, asset/images. |
| game | game | Playwright tests, views/, asset/models, asset/textures. |
| node | node | node:test tests (npm test, npm run test:only), npm start builds and runs lib/bundle.js. |
| theme | theme | Ships lib/theme.css as the package export. Playwright tests. No build script. |
| web-component | web-component | Playwright tests, views/, @papit/web-component as a dependency, papit.htmlprefix. |
web-component
On top of the above, a web component package gets:
"analyse": "npx @papit/analyse", which writesanalyse.json(see @papit/analyse)"generate:react": "npx @papit/react", which writessrc/react-wrapper.tsx(see @papit/react)react^19as an optional peerDependency, tsconfig"jsx": "react-jsx"andpathsmapping the package's own name to./index
The ./react export isn't in the template. Add it by hand once src/react-wrapper.tsx has been generated, so the import path is @papit/<name>/react:
"./react": { "import": "./lib/react-wrapper.js", "types": "./lib/react-wrapper.d.ts" }Without the file, @papit/bundle-js would build that entry from src/index.ts instead.
Component templates
One per package type, each filled in with the component's name:
| Template | src | tests | views |
| --- | --- | --- | --- |
| browser | component.ts, index.ts, types.ts | Playwright unit.test.ts, snapshot.test.ts, test page | demo page |
| game | component.ts, index.ts, types.ts | Playwright unit.test.ts, snapshot.test.ts, test page | demo page |
| node | component.ts, index.ts, types.ts | unit.test.js | none |
| theme | theme.css | Playwright unit.test.ts, snapshot.test.ts, test page | demo page |
| web-component | a CustomElement class, style.css, types.ts, index.ts that defines <prefix>-<name> | Playwright unit.test.ts, snapshot.test.ts, test page | demo page |
Project template
A root package.json with npm workspaces (packages/**/*, excluding asset/ folders) and these scripts:
| Script | Runs |
| --- | --- |
| analyse | Every workspace's analyse script (npm run analyse --workspaces --if-present). |
| build | npx @papit/build |
| test | node bin/test.mjs, every package's npm test. |
| start | npx @papit/server --serve --info |
| create | npm create @papit -- --package |
| clean | node bin/clean.mjs |
| version:reset, version:sync | npx @papit/version --reset / --sync |
devDependencies: @papit/build, @papit/bundle-js, @papit/bundle-ts, @papit/server, @papit/create, @papit/version, @papit/arguments, @papit/terminal, @papit/information, @papit/analyse, @papit/react, esbuild and typescript. A project that uses generate:react adds react and @types/react as root devDependencies itself.
Also included: .gitignore (ignores packages/**/lib/ and the generated packages/**/analyse.json), GitHub workflows for pull requests and publishing, .vscode settings, .nvmrc, bin/ helpers and an example custom runner in bin/runners/example-runner/.
Template variables
Replaced in every copied file.
| Variable | Package | Component | Project | Value |
| --- | :-: | :-: | :-: | --- |
| VARIABLE_NAME | ✓ | ✓ | ✓ | Kebab-case name. Project: @<name>/root. |
| VARIABLE_FULL_NAME | ✓ | ✓ | | <scope>/<name>. Component: the package's name. |
| VARIABLE_CLASS_NAME | ✓ | ✓ | | PascalCase name. |
| VARIABLE_HTML_NAME | ✓ | ✓ | | <prefix>-<name> |
| VARIABLE_HTML_PREFIX | ✓ | | | The html prefix, or empty. |
| VARIABLE_DESCRIPTION | ✓ | | ✓ | The description. |
| VARIABLE_LAYER_FOLDER | ✓ | | | Name of the folder the package goes in, e.g. atoms. |
| VARIABLE_LOCAL_DESTINATION | ✓ | | | Package path from the workspace root. |
| VARIABLE_GITHUB_REPO | ✓ | | | Root repository.url without git+ and .git. |
| VARIABLE_PROJECTLICENSE | ✓ | | ✓ | Root license (default MIT). Project: --license. |
| VARIABLE_USER | ✓ | | ✓ | $USER, prompted when unset. |
License
Licensed under the @Papit License 1.0 Copyright (c) 2024 Henry Pap (@onkelhoy)
Key points
- ✅ Free to use in commercial projects
- ✅ Free to modify and distribute
- ✅ Attribution required
- ❌ Cannot resell the component itself as a standalone product
See the LICENSE file for full details.
Related
- @papit/information Finds the workspace root, its scope and existing packages.
- @papit/arguments Parses the flags.
- @papit/build Builds the packages it creates.
- @papit/analyse
Behind the web component template's
analysescript. - @papit/react
Behind the web component template's
generate:reactscript.
