@canonical/summon-package 0.1.0
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/README.md +496 -0
- package/biome.json +6 -0
- package/package.json +42 -0
- package/src/__tests__/generators.test.ts +295 -0
- package/src/index.ts +14 -0
- package/src/package/index.ts +306 -0
- package/src/shared/index.ts +330 -0
- package/src/templates/README.md.ejs +29 -0
- package/src/templates/biome.json.ejs +6 -0
- package/src/templates/cli.ts.ejs +8 -0
- package/src/templates/index.css.ejs +5 -0
- package/src/templates/index.ts.ejs +7 -0
- package/src/templates/package.json.ejs +112 -0
- package/src/templates/storybook-main.ts.ejs +5 -0
- package/src/templates/storybook-preview.ts.ejs +26 -0
- package/src/templates/tsconfig-react.json.ejs +8 -0
- package/src/templates/tsconfig.json.ejs +8 -0
- package/tsconfig.json +9 -0
package/README.md
ADDED
|
@@ -0,0 +1,496 @@
|
|
|
1
|
+
# @canonical/summon-package
|
|
2
|
+
|
|
3
|
+
Package scaffolding for the pragma monorepo. Generates new npm packages with proper TypeScript configuration, linting, and workspace integration.
|
|
4
|
+
|
|
5
|
+
## Why Use This?
|
|
6
|
+
|
|
7
|
+
Setting up a new package in a monorepo involves:
|
|
8
|
+
- Creating the directory structure
|
|
9
|
+
- Writing package.json with correct workspace references
|
|
10
|
+
- Setting up TypeScript config that extends the workspace config
|
|
11
|
+
- Configuring Biome for linting
|
|
12
|
+
- Adding the right scripts
|
|
13
|
+
- Running package manager install
|
|
14
|
+
|
|
15
|
+
This generator does all of that in one command, ensuring consistency across the monorepo.
|
|
16
|
+
|
|
17
|
+
## Installation
|
|
18
|
+
|
|
19
|
+
```bash
|
|
20
|
+
bun add @canonical/summon-package
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
Requires `@canonical/summon` as a peer dependency:
|
|
24
|
+
|
|
25
|
+
```bash
|
|
26
|
+
bun add @canonical/summon
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
Or link globally:
|
|
30
|
+
|
|
31
|
+
```bash
|
|
32
|
+
cd /path/to/summon-package
|
|
33
|
+
bun link
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
---
|
|
37
|
+
|
|
38
|
+
## Quick Start
|
|
39
|
+
|
|
40
|
+
```bash
|
|
41
|
+
# Interactive — prompts guide you through options
|
|
42
|
+
summon package
|
|
43
|
+
|
|
44
|
+
# Direct — specify options
|
|
45
|
+
summon package --name=@canonical/my-tool --type=tool-ts
|
|
46
|
+
|
|
47
|
+
# With React support
|
|
48
|
+
summon package --name=@canonical/my-lib --type=library --with-react
|
|
49
|
+
|
|
50
|
+
# Preview first
|
|
51
|
+
summon package --name=@canonical/my-tool --type=tool-ts --dry-run
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
---
|
|
55
|
+
|
|
56
|
+
## Package Types
|
|
57
|
+
|
|
58
|
+
### `tool-ts` — TypeScript Tool
|
|
59
|
+
|
|
60
|
+
For internal tools that run directly from source. No build step needed.
|
|
61
|
+
|
|
62
|
+
**Use for:** CLI tools, scripts, generators, dev utilities
|
|
63
|
+
|
|
64
|
+
**License:** GPL-3.0 (internal only)
|
|
65
|
+
|
|
66
|
+
**Entry:** `src/index.ts`
|
|
67
|
+
|
|
68
|
+
```bash
|
|
69
|
+
summon package --name=@canonical/my-tool --type=tool-ts
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
Creates:
|
|
73
|
+
|
|
74
|
+
```
|
|
75
|
+
packages/my-tool/
|
|
76
|
+
├── package.json # type: module, main: src/index.ts
|
|
77
|
+
├── tsconfig.json # extends workspace config
|
|
78
|
+
├── biome.json # extends workspace biome
|
|
79
|
+
├── README.md
|
|
80
|
+
└── src/
|
|
81
|
+
└── index.ts # export entry point
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
Example package.json:
|
|
85
|
+
|
|
86
|
+
```json
|
|
87
|
+
{
|
|
88
|
+
"name": "@canonical/my-tool",
|
|
89
|
+
"version": "0.1.0",
|
|
90
|
+
"type": "module",
|
|
91
|
+
"main": "src/index.ts",
|
|
92
|
+
"license": "GPL-3.0",
|
|
93
|
+
"scripts": {
|
|
94
|
+
"check": "biome check .",
|
|
95
|
+
"check:fix": "biome check --write ."
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
### `library` — Publishable Library
|
|
101
|
+
|
|
102
|
+
For packages distributed to npm with compiled output.
|
|
103
|
+
|
|
104
|
+
**Use for:** Shared utilities, component libraries, public packages
|
|
105
|
+
|
|
106
|
+
**License:** LGPL-3.0 (can be used in proprietary projects)
|
|
107
|
+
|
|
108
|
+
**Entry:** `dist/esm/index.js`
|
|
109
|
+
|
|
110
|
+
```bash
|
|
111
|
+
summon package --name=@canonical/my-lib --type=library
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
Creates:
|
|
115
|
+
|
|
116
|
+
```
|
|
117
|
+
packages/my-lib/
|
|
118
|
+
├── package.json # type: module, main: dist/esm/index.js
|
|
119
|
+
├── tsconfig.json # extends workspace config, outDir: dist
|
|
120
|
+
├── biome.json
|
|
121
|
+
├── README.md
|
|
122
|
+
└── src/
|
|
123
|
+
└── index.ts
|
|
124
|
+
```
|
|
125
|
+
|
|
126
|
+
Example package.json:
|
|
127
|
+
|
|
128
|
+
```json
|
|
129
|
+
{
|
|
130
|
+
"name": "@canonical/my-lib",
|
|
131
|
+
"version": "0.1.0",
|
|
132
|
+
"type": "module",
|
|
133
|
+
"main": "dist/esm/index.js",
|
|
134
|
+
"types": "dist/esm/index.d.ts",
|
|
135
|
+
"license": "LGPL-3.0",
|
|
136
|
+
"scripts": {
|
|
137
|
+
"build": "tsc",
|
|
138
|
+
"check": "biome check .",
|
|
139
|
+
"check:fix": "biome check --write ."
|
|
140
|
+
},
|
|
141
|
+
"files": ["dist", "README.md"]
|
|
142
|
+
}
|
|
143
|
+
```
|
|
144
|
+
|
|
145
|
+
### `css` — CSS-Only Package
|
|
146
|
+
|
|
147
|
+
For pure CSS packages with no TypeScript.
|
|
148
|
+
|
|
149
|
+
**Use for:** Design tokens, CSS utilities, style primitives
|
|
150
|
+
|
|
151
|
+
**License:** LGPL-3.0
|
|
152
|
+
|
|
153
|
+
**Entry:** `src/index.css`
|
|
154
|
+
|
|
155
|
+
```bash
|
|
156
|
+
summon package --name=@canonical/my-styles --type=css
|
|
157
|
+
```
|
|
158
|
+
|
|
159
|
+
Creates:
|
|
160
|
+
|
|
161
|
+
```
|
|
162
|
+
packages/my-styles/
|
|
163
|
+
├── package.json # main: src/index.css
|
|
164
|
+
├── biome.json
|
|
165
|
+
├── README.md
|
|
166
|
+
└── src/
|
|
167
|
+
└── index.css
|
|
168
|
+
```
|
|
169
|
+
|
|
170
|
+
---
|
|
171
|
+
|
|
172
|
+
## Options Reference
|
|
173
|
+
|
|
174
|
+
### Core Options
|
|
175
|
+
|
|
176
|
+
| Flag | Description | Default |
|
|
177
|
+
|------|-------------|---------|
|
|
178
|
+
| `--name` | Full package name with scope (e.g., `@canonical/my-package`) | Interactive prompt |
|
|
179
|
+
| `--type` | Package type: `tool-ts`, `library`, or `css` | Interactive prompt |
|
|
180
|
+
| `--description` | Package description for package.json | Empty |
|
|
181
|
+
|
|
182
|
+
### Feature Flags
|
|
183
|
+
|
|
184
|
+
| Flag | Description | Default |
|
|
185
|
+
|------|-------------|---------|
|
|
186
|
+
| `--with-react` | Add React dependencies and JSX config | `false` |
|
|
187
|
+
| `--with-storybook` | Add Storybook configuration | `false` |
|
|
188
|
+
| `--with-cli` | Add CLI binary entry point | `false` |
|
|
189
|
+
| `--run-install` | Run package manager install after creation | `true` |
|
|
190
|
+
| `--no-run-install` | Skip the install step | — |
|
|
191
|
+
|
|
192
|
+
### Global Options
|
|
193
|
+
|
|
194
|
+
| Flag | Description |
|
|
195
|
+
|------|-------------|
|
|
196
|
+
| `--dry-run`, `-d` | Preview without writing files |
|
|
197
|
+
| `--yes`, `-y` | Skip confirmation prompts |
|
|
198
|
+
| `--no-preview` | Skip the file preview step |
|
|
199
|
+
| `--help` | Show all options |
|
|
200
|
+
|
|
201
|
+
---
|
|
202
|
+
|
|
203
|
+
## Feature Details
|
|
204
|
+
|
|
205
|
+
### `--with-react`
|
|
206
|
+
|
|
207
|
+
Adds React as a peer dependency and configures JSX:
|
|
208
|
+
|
|
209
|
+
```json
|
|
210
|
+
{
|
|
211
|
+
"peerDependencies": {
|
|
212
|
+
"react": "^18.0.0 || ^19.0.0",
|
|
213
|
+
"react-dom": "^18.0.0 || ^19.0.0"
|
|
214
|
+
},
|
|
215
|
+
"devDependencies": {
|
|
216
|
+
"@types/react": "^18.0.0",
|
|
217
|
+
"@types/react-dom": "^18.0.0"
|
|
218
|
+
}
|
|
219
|
+
}
|
|
220
|
+
```
|
|
221
|
+
|
|
222
|
+
tsconfig.json:
|
|
223
|
+
|
|
224
|
+
```json
|
|
225
|
+
{
|
|
226
|
+
"compilerOptions": {
|
|
227
|
+
"jsx": "react-jsx"
|
|
228
|
+
}
|
|
229
|
+
}
|
|
230
|
+
```
|
|
231
|
+
|
|
232
|
+
### `--with-storybook`
|
|
233
|
+
|
|
234
|
+
Adds Storybook configuration files:
|
|
235
|
+
|
|
236
|
+
```
|
|
237
|
+
packages/my-lib/
|
|
238
|
+
└── .storybook/
|
|
239
|
+
├── main.ts
|
|
240
|
+
└── preview.ts
|
|
241
|
+
```
|
|
242
|
+
|
|
243
|
+
And adds scripts:
|
|
244
|
+
|
|
245
|
+
```json
|
|
246
|
+
{
|
|
247
|
+
"scripts": {
|
|
248
|
+
"storybook": "storybook dev -p 6006",
|
|
249
|
+
"build-storybook": "storybook build"
|
|
250
|
+
}
|
|
251
|
+
}
|
|
252
|
+
```
|
|
253
|
+
|
|
254
|
+
### `--with-cli`
|
|
255
|
+
|
|
256
|
+
Adds a CLI entry point with bin configuration:
|
|
257
|
+
|
|
258
|
+
```
|
|
259
|
+
packages/my-tool/
|
|
260
|
+
└── src/
|
|
261
|
+
├── index.ts
|
|
262
|
+
└── cli.ts # CLI entry point
|
|
263
|
+
```
|
|
264
|
+
|
|
265
|
+
package.json:
|
|
266
|
+
|
|
267
|
+
```json
|
|
268
|
+
{
|
|
269
|
+
"bin": {
|
|
270
|
+
"my-tool": "./src/cli.ts"
|
|
271
|
+
}
|
|
272
|
+
}
|
|
273
|
+
```
|
|
274
|
+
|
|
275
|
+
The CLI template includes a basic argument parser setup.
|
|
276
|
+
|
|
277
|
+
---
|
|
278
|
+
|
|
279
|
+
## Auto-Detection
|
|
280
|
+
|
|
281
|
+
The generator automatically detects:
|
|
282
|
+
|
|
283
|
+
### Monorepo Version
|
|
284
|
+
|
|
285
|
+
When running in the pragma monorepo, the version is read from `lerna.json`:
|
|
286
|
+
|
|
287
|
+
```json
|
|
288
|
+
{
|
|
289
|
+
"version": "0.1.0"
|
|
290
|
+
}
|
|
291
|
+
```
|
|
292
|
+
|
|
293
|
+
New packages inherit this version.
|
|
294
|
+
|
|
295
|
+
### Package Manager
|
|
296
|
+
|
|
297
|
+
Detects which package manager to use for the install step:
|
|
298
|
+
|
|
299
|
+
1. If `bun.lockb` or `bun.lock` exists → `bun install`
|
|
300
|
+
2. If `pnpm-lock.yaml` exists → `pnpm install`
|
|
301
|
+
3. If `yarn.lock` exists → `yarn install`
|
|
302
|
+
4. Otherwise → `npm install`
|
|
303
|
+
|
|
304
|
+
---
|
|
305
|
+
|
|
306
|
+
## Examples
|
|
307
|
+
|
|
308
|
+
### TypeScript Tool with CLI
|
|
309
|
+
|
|
310
|
+
```bash
|
|
311
|
+
summon package \
|
|
312
|
+
--name=@canonical/code-checker \
|
|
313
|
+
--type=tool-ts \
|
|
314
|
+
--with-cli \
|
|
315
|
+
--description="Code quality checker"
|
|
316
|
+
```
|
|
317
|
+
|
|
318
|
+
### React Component Library
|
|
319
|
+
|
|
320
|
+
```bash
|
|
321
|
+
summon package \
|
|
322
|
+
--name=@canonical/ui-components \
|
|
323
|
+
--type=library \
|
|
324
|
+
--with-react \
|
|
325
|
+
--with-storybook \
|
|
326
|
+
--description="Shared UI components"
|
|
327
|
+
```
|
|
328
|
+
|
|
329
|
+
### CSS Design Tokens
|
|
330
|
+
|
|
331
|
+
```bash
|
|
332
|
+
summon package \
|
|
333
|
+
--name=@canonical/design-tokens \
|
|
334
|
+
--type=css \
|
|
335
|
+
--description="Design system tokens"
|
|
336
|
+
```
|
|
337
|
+
|
|
338
|
+
### Skip Install (CI/Scripts)
|
|
339
|
+
|
|
340
|
+
```bash
|
|
341
|
+
summon package \
|
|
342
|
+
--name=@canonical/my-pkg \
|
|
343
|
+
--type=library \
|
|
344
|
+
--no-run-install \
|
|
345
|
+
--yes
|
|
346
|
+
```
|
|
347
|
+
|
|
348
|
+
---
|
|
349
|
+
|
|
350
|
+
## Generated Configuration
|
|
351
|
+
|
|
352
|
+
### tsconfig.json
|
|
353
|
+
|
|
354
|
+
Extends the workspace TypeScript config:
|
|
355
|
+
|
|
356
|
+
```json
|
|
357
|
+
{
|
|
358
|
+
"extends": "../../tsconfig.json",
|
|
359
|
+
"compilerOptions": {
|
|
360
|
+
"outDir": "dist",
|
|
361
|
+
"rootDir": "src"
|
|
362
|
+
},
|
|
363
|
+
"include": ["src"]
|
|
364
|
+
}
|
|
365
|
+
```
|
|
366
|
+
|
|
367
|
+
For `tool-ts` packages, `outDir` is omitted (no build step).
|
|
368
|
+
|
|
369
|
+
### biome.json
|
|
370
|
+
|
|
371
|
+
Extends the workspace Biome config:
|
|
372
|
+
|
|
373
|
+
```json
|
|
374
|
+
{
|
|
375
|
+
"extends": ["../../biome.json"]
|
|
376
|
+
}
|
|
377
|
+
```
|
|
378
|
+
|
|
379
|
+
### Package Scripts
|
|
380
|
+
|
|
381
|
+
Standard scripts across all package types:
|
|
382
|
+
|
|
383
|
+
```json
|
|
384
|
+
{
|
|
385
|
+
"scripts": {
|
|
386
|
+
"check": "biome check .",
|
|
387
|
+
"check:fix": "biome check --write ."
|
|
388
|
+
}
|
|
389
|
+
}
|
|
390
|
+
```
|
|
391
|
+
|
|
392
|
+
Library packages add:
|
|
393
|
+
|
|
394
|
+
```json
|
|
395
|
+
{
|
|
396
|
+
"scripts": {
|
|
397
|
+
"build": "tsc"
|
|
398
|
+
}
|
|
399
|
+
}
|
|
400
|
+
```
|
|
401
|
+
|
|
402
|
+
---
|
|
403
|
+
|
|
404
|
+
## Customization
|
|
405
|
+
|
|
406
|
+
### Override with Local Generator
|
|
407
|
+
|
|
408
|
+
Create a local generator to customize behavior:
|
|
409
|
+
|
|
410
|
+
```
|
|
411
|
+
your-project/
|
|
412
|
+
└── generators/
|
|
413
|
+
└── package/
|
|
414
|
+
└── index.ts # Your custom package generator
|
|
415
|
+
```
|
|
416
|
+
|
|
417
|
+
### Extend the Base Generator
|
|
418
|
+
|
|
419
|
+
```typescript
|
|
420
|
+
import { generators } from "@canonical/summon-package";
|
|
421
|
+
import { sequence_ } from "@canonical/summon";
|
|
422
|
+
|
|
423
|
+
const baseGenerator = generators["package"];
|
|
424
|
+
|
|
425
|
+
export const generator = {
|
|
426
|
+
...baseGenerator,
|
|
427
|
+
|
|
428
|
+
prompts: [
|
|
429
|
+
...baseGenerator.prompts,
|
|
430
|
+
{
|
|
431
|
+
name: "withGraphQL",
|
|
432
|
+
type: "confirm",
|
|
433
|
+
message: "Include GraphQL setup?",
|
|
434
|
+
default: false,
|
|
435
|
+
},
|
|
436
|
+
],
|
|
437
|
+
|
|
438
|
+
generate: (answers) => sequence_([
|
|
439
|
+
baseGenerator.generate(answers),
|
|
440
|
+
// Add GraphQL config if requested
|
|
441
|
+
answers.withGraphQL && addGraphQLSetup(answers),
|
|
442
|
+
].filter(Boolean)),
|
|
443
|
+
};
|
|
444
|
+
```
|
|
445
|
+
|
|
446
|
+
---
|
|
447
|
+
|
|
448
|
+
## Troubleshooting
|
|
449
|
+
|
|
450
|
+
### "Package name must be scoped"
|
|
451
|
+
|
|
452
|
+
The generator expects scoped package names:
|
|
453
|
+
|
|
454
|
+
```bash
|
|
455
|
+
# Good
|
|
456
|
+
summon package --name=@canonical/my-tool
|
|
457
|
+
|
|
458
|
+
# Bad
|
|
459
|
+
summon package --name=my-tool
|
|
460
|
+
```
|
|
461
|
+
|
|
462
|
+
### Install fails
|
|
463
|
+
|
|
464
|
+
If the install step fails, you can skip it and run manually:
|
|
465
|
+
|
|
466
|
+
```bash
|
|
467
|
+
summon package --name=@canonical/my-tool --no-run-install
|
|
468
|
+
cd packages/my-tool
|
|
469
|
+
bun install
|
|
470
|
+
```
|
|
471
|
+
|
|
472
|
+
### TypeScript errors after creation
|
|
473
|
+
|
|
474
|
+
Ensure the workspace TypeScript config exists at `../../tsconfig.json` from the package location. The generated config extends it.
|
|
475
|
+
|
|
476
|
+
---
|
|
477
|
+
|
|
478
|
+
## Post-Creation Steps
|
|
479
|
+
|
|
480
|
+
After generating a package:
|
|
481
|
+
|
|
482
|
+
1. **Update workspace config** — If using Lerna or workspaces, verify the new package is included
|
|
483
|
+
2. **Run install** — If you used `--no-run-install`, run your package manager
|
|
484
|
+
3. **Start coding** — Edit `src/index.ts` to add your implementation
|
|
485
|
+
4. **Add to CI** — Ensure the new package is included in your CI pipeline
|
|
486
|
+
|
|
487
|
+
---
|
|
488
|
+
|
|
489
|
+
## Related
|
|
490
|
+
|
|
491
|
+
- **[@canonical/summon](../summon/)** — The generator framework (required peer dependency)
|
|
492
|
+
- **[@canonical/summon-component](../summon-component/)** — Component scaffolding
|
|
493
|
+
|
|
494
|
+
## License
|
|
495
|
+
|
|
496
|
+
GPL-3.0
|
package/biome.json
ADDED
package/package.json
ADDED
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@canonical/summon-package",
|
|
3
|
+
"description": "Package generator for Summon - scaffold new npm packages with proper configuration",
|
|
4
|
+
"version": "0.1.0",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"main": "src/index.ts",
|
|
7
|
+
"author": {
|
|
8
|
+
"email": "webteam@canonical.com",
|
|
9
|
+
"name": "Canonical Webteam"
|
|
10
|
+
},
|
|
11
|
+
"repository": {
|
|
12
|
+
"type": "git",
|
|
13
|
+
"url": "https://github.com/canonical/pragma"
|
|
14
|
+
},
|
|
15
|
+
"license": "GPL-3.0",
|
|
16
|
+
"bugs": {
|
|
17
|
+
"url": "https://github.com/canonical/pragma/issues"
|
|
18
|
+
},
|
|
19
|
+
"homepage": "https://github.com/canonical/pragma#readme",
|
|
20
|
+
"scripts": {
|
|
21
|
+
"build": "echo 'No build needed - runs directly from TypeScript'",
|
|
22
|
+
"build:all": "bun run build",
|
|
23
|
+
"check": "bun run check:biome && bun run check:ts && bun run check:webarchitect",
|
|
24
|
+
"check:fix": "bun run check:biome:fix && bun run check:ts",
|
|
25
|
+
"check:biome": "biome check",
|
|
26
|
+
"check:biome:fix": "biome check --write",
|
|
27
|
+
"check:ts": "tsc --noEmit",
|
|
28
|
+
"check:webarchitect": "webarchitect base",
|
|
29
|
+
"test": "vitest run"
|
|
30
|
+
},
|
|
31
|
+
"devDependencies": {
|
|
32
|
+
"@biomejs/biome": "2.3.11",
|
|
33
|
+
"@canonical/biome-config": "^0.11.0",
|
|
34
|
+
"@canonical/typescript-config-base": "^0.11.0",
|
|
35
|
+
"bun-types": "^1.0.0",
|
|
36
|
+
"typescript": "^5.9.3",
|
|
37
|
+
"vitest": "^3.2.4"
|
|
38
|
+
},
|
|
39
|
+
"peerDependencies": {
|
|
40
|
+
"@canonical/summon": "^0.1.0"
|
|
41
|
+
}
|
|
42
|
+
}
|