@regardio/dev 2.4.0 → 2.4.1
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/dist/bin/ship/hotfix.bin.mjs +7 -9
- package/dist/bin/ship/production.bin.mjs +14 -16
- package/dist/playwright/index.d.mts +3 -3
- package/dist/vitest/node.d.mts +4 -4
- package/dist/vitest/react.d.mts +4 -4
- package/docs/en/tools/releases.md +16 -13
- package/docs/en/tools/typescript.md +41 -14
- package/package.json +5 -5
- package/src/typescript/base.json +0 -2
- package/src/typescript/library.json +8 -0
- package/src/typescript/react-library.json +8 -0
|
@@ -72,15 +72,13 @@ function runShipHotfix(subcommand, subArgs, cwd = process.cwd()) {
|
|
|
72
72
|
process.exit(0);
|
|
73
73
|
}
|
|
74
74
|
console.log("\nBumping versions and updating CHANGELOGs...");
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
}
|
|
83
|
-
process.chdir(originalCwd);
|
|
75
|
+
const hasMajor = bumps.some((b) => b.bump === "major");
|
|
76
|
+
const hasMinor = bumps.some((b) => b.bump === "minor");
|
|
77
|
+
const highestBump = hasMajor ? "major" : hasMinor ? "minor" : "patch";
|
|
78
|
+
try {
|
|
79
|
+
runScript(`release:${highestBump}`);
|
|
80
|
+
} catch {
|
|
81
|
+
console.log("No release script found - skipping versioning (non-publishing repo)");
|
|
84
82
|
}
|
|
85
83
|
console.log("\nFetching latest state from origin...");
|
|
86
84
|
git("fetch", "origin");
|
|
@@ -42,6 +42,14 @@ function runShipProduction(cwd = process.cwd()) {
|
|
|
42
42
|
}
|
|
43
43
|
console.log("\nCommits to be shipped to production:");
|
|
44
44
|
console.log(ahead);
|
|
45
|
+
console.log("\nRunning quality checks on main...");
|
|
46
|
+
try {
|
|
47
|
+
runQualityChecks();
|
|
48
|
+
} catch {
|
|
49
|
+
console.error("\nQuality checks failed on main. Fix issues before shipping.");
|
|
50
|
+
process.exit(1);
|
|
51
|
+
}
|
|
52
|
+
console.log("✅ Quality checks passed");
|
|
45
53
|
const packages = getWorkspacePackages(cwd);
|
|
46
54
|
if (packages.length === 0) {
|
|
47
55
|
console.error("No publishable workspace packages found.");
|
|
@@ -57,24 +65,14 @@ function runShipProduction(cwd = process.cwd()) {
|
|
|
57
65
|
console.log("Aborted.");
|
|
58
66
|
process.exit(0);
|
|
59
67
|
}
|
|
60
|
-
console.log("\
|
|
68
|
+
console.log("\nBumping versions and updating CHANGELOGs...");
|
|
69
|
+
const hasMajor = bumps.some((b) => b.bump === "major");
|
|
70
|
+
const hasMinor = bumps.some((b) => b.bump === "minor");
|
|
71
|
+
const highestBump = hasMajor ? "major" : hasMinor ? "minor" : "patch";
|
|
61
72
|
try {
|
|
62
|
-
|
|
73
|
+
runScript(`release:${highestBump}`);
|
|
63
74
|
} catch {
|
|
64
|
-
console.
|
|
65
|
-
process.exit(1);
|
|
66
|
-
}
|
|
67
|
-
console.log("✅ Quality checks passed");
|
|
68
|
-
console.log("\nBumping versions and updating CHANGELOGs...");
|
|
69
|
-
for (const { package: pkg, bump } of bumps) {
|
|
70
|
-
const originalCwd = process.cwd();
|
|
71
|
-
process.chdir(pkg.path);
|
|
72
|
-
try {
|
|
73
|
-
runScript(`--filter-root release:${bump}`);
|
|
74
|
-
} catch {
|
|
75
|
-
runScript(`commit-and-tag-version ${bump === "patch" ? "" : `--release-as ${bump}`}`);
|
|
76
|
-
}
|
|
77
|
-
process.chdir(originalCwd);
|
|
75
|
+
console.log("No release script found - skipping versioning (non-publishing repo)");
|
|
78
76
|
}
|
|
79
77
|
console.log("\nMerging main into production...");
|
|
80
78
|
git("checkout", "production");
|
|
@@ -10,9 +10,9 @@ interface BuildPlaywrightBaseConfigParams {
|
|
|
10
10
|
webServerCommand: string;
|
|
11
11
|
}
|
|
12
12
|
/**
|
|
13
|
-
* Build a base Playwright config object with Regardio defaults.
|
|
14
|
-
* Consumers should wrap with defineConfig() in their local playwright.config.ts
|
|
15
|
-
*/
|
|
13
|
+
* Build a base Playwright config object with Regardio defaults.
|
|
14
|
+
* Consumers should wrap with defineConfig() in their local playwright.config.ts
|
|
15
|
+
*/
|
|
16
16
|
declare function buildPlaywrightBaseConfig({
|
|
17
17
|
appUrl,
|
|
18
18
|
appPort,
|
package/dist/vitest/node.d.mts
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
//#region src/vitest/node.d.ts
|
|
2
2
|
/**
|
|
3
|
-
* Base Vitest configuration for Node.js packages.
|
|
4
|
-
* Use with defineConfig() in your vitest.config.ts
|
|
5
|
-
*/
|
|
3
|
+
* Base Vitest configuration for Node.js packages.
|
|
4
|
+
* Use with defineConfig() in your vitest.config.ts
|
|
5
|
+
*/
|
|
6
6
|
declare const vitestNodeConfig: {
|
|
7
7
|
coverage: {
|
|
8
|
-
provider:
|
|
8
|
+
provider: 'v8';
|
|
9
9
|
thresholds: {
|
|
10
10
|
branches: number;
|
|
11
11
|
functions: number;
|
package/dist/vitest/react.d.mts
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
//#region src/vitest/react.d.ts
|
|
2
2
|
/**
|
|
3
|
-
* Vitest configuration for React packages with jsdom environment.
|
|
4
|
-
* Use with defineConfig() in your vitest.config.ts
|
|
5
|
-
*/
|
|
3
|
+
* Vitest configuration for React packages with jsdom environment.
|
|
4
|
+
* Use with defineConfig() in your vitest.config.ts
|
|
5
|
+
*/
|
|
6
6
|
declare const vitestReactConfig: {
|
|
7
7
|
coverage: {
|
|
8
|
-
provider:
|
|
8
|
+
provider: 'v8';
|
|
9
9
|
thresholds: {
|
|
10
10
|
branches: number;
|
|
11
11
|
functions: number;
|
|
@@ -25,7 +25,7 @@ main → staging (optional) → production
|
|
|
25
25
|
- **`staging`** — optional validation environment. No versioning happens here.
|
|
26
26
|
- **`production`** — versioned, published code only.
|
|
27
27
|
|
|
28
|
-
When `ship-production` runs, it discovers all publishable workspace packages and asks you to assign a bump type — `0` (skip), `1` (patch), `2` (minor), or `3` (major) — to each one individually. Packages you skip are left untouched.
|
|
28
|
+
When `ship-production` runs, it discovers all publishable workspace packages and asks you to assign a bump type — `0` (skip), `1` (patch), `2` (minor), or `3` (major) — to each one individually. Packages you skip are left untouched. It determines the highest bump type across all selected packages and runs `pnpm release:<type>` at the root, which bumps versions, rewrites `CHANGELOG.md`, and commits on `main`. If no release script exists (non-publishing repos like channels), versioning is skipped entirely and only the git merges happen. The branches merge once after all bumps are applied. CI on `production` publishes only the packages whose version changed.
|
|
29
29
|
|
|
30
30
|
## How It Works
|
|
31
31
|
|
|
@@ -53,7 +53,8 @@ main ───────────┤ quality checks pass ├──►
|
|
|
53
53
|
ship-production
|
|
54
54
|
┌──────────────────────────┐
|
|
55
55
|
│ quality checks on main │
|
|
56
|
-
│
|
|
56
|
+
│ select packages/bumps │
|
|
57
|
+
│ pnpm release:<type>* │
|
|
57
58
|
main ───────────┤ bumps version + ├──► production
|
|
58
59
|
│ rewrites CHANGELOG.md │
|
|
59
60
|
│ ff-merge main → prod │
|
|
@@ -76,7 +77,7 @@ production ─────┤ create hotfix/fix-name ├──► hotfix/fix-n
|
|
|
76
77
|
ship-hotfix finish
|
|
77
78
|
┌──────────────────────────┐
|
|
78
79
|
│ quality checks │
|
|
79
|
-
│ pnpm release
|
|
80
|
+
│ pnpm release:<type>* │
|
|
80
81
|
hotfix/fix-name ┤ bumps version + ├──► production → staging → main
|
|
81
82
|
│ rewrites CHANGELOG.md │
|
|
82
83
|
│ merge to production │
|
|
@@ -137,10 +138,10 @@ This will:
|
|
|
137
138
|
1. Guard: must be on `main`, working tree clean
|
|
138
139
|
2. Fetch and verify `staging` + `production` branches exist
|
|
139
140
|
3. Show commits to be shipped
|
|
140
|
-
4.
|
|
141
|
-
5.
|
|
142
|
-
6.
|
|
143
|
-
7.
|
|
141
|
+
4. Run full quality suite on `main` — aborts on failure
|
|
142
|
+
5. For each publishable package: choose `0 (skip) / 1 (patch) / 2 (minor) / 3 (major)`
|
|
143
|
+
6. Confirm the planned bumps — abort if declined or all skipped
|
|
144
|
+
7. Run `pnpm release:<type>` at the root (highest bump type) — bumps versions, rewrites `CHANGELOG.md`, commits. If no release script exists, skip versioning.
|
|
144
145
|
8. Fast-forward merge `main` into `production` and push
|
|
145
146
|
9. Sync `staging` with `production`
|
|
146
147
|
10. Push `main` with `--follow-tags` to push all new version tags
|
|
@@ -167,15 +168,15 @@ git add . && git commit -m "fix: ..."
|
|
|
167
168
|
pnpm ship:hotfix finish
|
|
168
169
|
```
|
|
169
170
|
|
|
170
|
-
`finish` asks you to assign a bump type (`0` (skip), `1` (patch), `2` (minor), or `3` (major)) to each publishable package, runs
|
|
171
|
+
`finish` asks you to assign a bump type (`0` (skip), `1` (patch), `2` (minor), or `3` (major)) to each publishable package, runs `pnpm release:<type>` at the root (highest bump type) to bump versions and update `CHANGELOG.md`. If no release script exists, versioning is skipped. Then it merges `hotfix → production → staging → main` and deletes the hotfix branch. CI publishes from `production`.
|
|
171
172
|
|
|
172
173
|
## Adoption
|
|
173
174
|
|
|
174
175
|
Install `@regardio/dev` and:
|
|
175
176
|
|
|
176
|
-
1. **Add the scripts to `package.json`** (optional, for
|
|
177
|
+
1. **Add the scripts to `package.json`** (optional, for publishing repos):
|
|
177
178
|
|
|
178
|
-
|
|
179
|
+
For repos that publish to npm, add release scripts to the root `package.json`:
|
|
179
180
|
|
|
180
181
|
```json
|
|
181
182
|
{
|
|
@@ -191,7 +192,7 @@ Install `@regardio/dev` and:
|
|
|
191
192
|
}
|
|
192
193
|
```
|
|
193
194
|
|
|
194
|
-
For
|
|
195
|
+
For non-publishing repos (e.g., channels that deploy to servers), omit the release scripts — the ship commands will skip versioning and only perform the git merges. This makes the tools reusable across both publishing and non-publishing repositories.
|
|
195
196
|
|
|
196
197
|
2. **Add a `.versionrc.json` to each publishable package** with a scoped `tagPrefix` so tags and changelogs stay isolated per package:
|
|
197
198
|
|
|
@@ -238,9 +239,11 @@ pnpm typecheck # Must succeed
|
|
|
238
239
|
pnpm test # Must succeed
|
|
239
240
|
```
|
|
240
241
|
|
|
241
|
-
## Private Packages
|
|
242
|
+
## Private Packages and Non-Publishing Repos
|
|
242
243
|
|
|
243
|
-
Packages that should never be published to npm must set `"private": true` in `package.json`. `pnpm -r publish` skips them automatically.
|
|
244
|
+
Packages that should never be published to npm must set `"private": true` in `package.json`. `pnpm -r publish` skips them automatically.
|
|
245
|
+
|
|
246
|
+
For non-publishing repos (e.g., channels that deploy directly to servers instead of npm), omit the `release:*` scripts from `package.json`. The ship tools will skip versioning entirely and only perform the git merges. CI can then handle deployment to servers based on the `production` branch.
|
|
244
247
|
|
|
245
248
|
## Related
|
|
246
249
|
|
|
@@ -17,33 +17,62 @@ Strict, shared TypeScript presets for Regardio projects. Extending from `@regard
|
|
|
17
17
|
|
|
18
18
|
| Preset | Use case |
|
|
19
19
|
|--------|----------|
|
|
20
|
-
| `@regardio/dev/typescript/base` |
|
|
21
|
-
| `@regardio/dev/typescript/
|
|
22
|
-
| `@regardio/dev/typescript/
|
|
20
|
+
| `@regardio/dev/typescript/base` | Non-publishing packages and meta-configs (e.g. the workspace root) |
|
|
21
|
+
| `@regardio/dev/typescript/library` | Published Node.js packages — adds declaration enforcement |
|
|
22
|
+
| `@regardio/dev/typescript/react` | React apps and channels — adds JSX and DOM libs |
|
|
23
|
+
| `@regardio/dev/typescript/react-library` | Published React packages — JSX, DOM libs, and declaration enforcement |
|
|
24
|
+
| `@regardio/dev/typescript/build` | Build-time emission settings (pair with any of the above) |
|
|
25
|
+
|
|
26
|
+
### Choosing a preset
|
|
27
|
+
|
|
28
|
+
The guiding question is whether the package **publishes type declarations** to consumers.
|
|
29
|
+
|
|
30
|
+
- **App or channel** (`private: true`) → `react` (or `base` for non-React)
|
|
31
|
+
- **Published library without React** → `library`
|
|
32
|
+
- **Published library with React** → `react-library`
|
|
33
|
+
|
|
34
|
+
The `library` and `react-library` presets add two settings on top of the base:
|
|
35
|
+
|
|
36
|
+
- `declaration: true` — validates that `.d.ts` files can be generated (even when `noEmit: true` during typecheck)
|
|
37
|
+
- `isolatedDeclarations: true` — enforces that every exported declaration carries an explicit type annotation, enabling per-file parallel declaration generation
|
|
38
|
+
|
|
39
|
+
`isolatedDeclarations` is a library-authoring constraint. It requires explicit return types on exported functions and explicit annotations on exported variables. Applying it to app code is unnecessarily strict — especially with frameworks like TanStack Router whose `Route` objects carry deeply inferred generics that cannot be spelled out without extraordinary verbosity.
|
|
23
40
|
|
|
24
41
|
## Configuration
|
|
25
42
|
|
|
26
|
-
###
|
|
43
|
+
### App or channel
|
|
27
44
|
|
|
28
45
|
```json
|
|
29
46
|
{
|
|
30
|
-
"
|
|
47
|
+
"compilerOptions": {
|
|
48
|
+
"paths": { "#/*": ["./src/*"] }
|
|
49
|
+
},
|
|
50
|
+
"extends": "@regardio/dev/typescript/react",
|
|
51
|
+
"include": ["**/*.ts", "**/*.tsx", "**/*.d.ts"]
|
|
52
|
+
}
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
### Published Node.js library
|
|
56
|
+
|
|
57
|
+
```json
|
|
58
|
+
{
|
|
59
|
+
"extends": "@regardio/dev/typescript/library",
|
|
31
60
|
"include": ["src/**/*.ts"]
|
|
32
61
|
}
|
|
33
62
|
```
|
|
34
63
|
|
|
35
|
-
|
|
64
|
+
### Published React library
|
|
36
65
|
|
|
37
66
|
```json
|
|
38
67
|
{
|
|
39
|
-
"extends": "@regardio/dev/typescript/react",
|
|
68
|
+
"extends": "@regardio/dev/typescript/react-library",
|
|
40
69
|
"include": ["src/**/*.ts", "src/**/*.tsx"]
|
|
41
70
|
}
|
|
42
71
|
```
|
|
43
72
|
|
|
44
73
|
### `tsconfig.build.json`
|
|
45
74
|
|
|
46
|
-
|
|
75
|
+
Pair any preset with `build` for production output:
|
|
47
76
|
|
|
48
77
|
```json
|
|
49
78
|
{
|
|
@@ -51,28 +80,26 @@ A separate build config for production output:
|
|
|
51
80
|
"outDir": "./dist",
|
|
52
81
|
"rootDir": "./src"
|
|
53
82
|
},
|
|
54
|
-
"extends": ["./tsconfig.json", "@regardio/dev/typescript/build"]
|
|
55
|
-
"include": ["src/**/*.ts"]
|
|
83
|
+
"extends": ["./tsconfig.json", "@regardio/dev/typescript/build"]
|
|
56
84
|
}
|
|
57
85
|
```
|
|
58
86
|
|
|
59
87
|
## Strict settings
|
|
60
88
|
|
|
61
|
-
|
|
89
|
+
All presets share the same strict type-checking baseline:
|
|
62
90
|
|
|
63
91
|
- `strict: true` — every strict type-checking option
|
|
64
92
|
- `noUncheckedIndexedAccess: true` — adds `undefined` to index signatures
|
|
65
|
-
- `exactOptionalPropertyTypes: true` — distinguishes `undefined` from missing
|
|
66
93
|
- `noImplicitReturns: true` — every code path returns a value
|
|
67
94
|
- `noFallthroughCasesInSwitch: true` — prevents switch-fallthrough surprises
|
|
95
|
+
- `verbatimModuleSyntax: true` — `import type` vs. `import` must be explicit
|
|
68
96
|
|
|
69
97
|
## Scripts
|
|
70
98
|
|
|
71
99
|
```json
|
|
72
100
|
{
|
|
73
101
|
"scripts": {
|
|
74
|
-
"
|
|
75
|
-
"typecheck": "exec-tsc --noEmit"
|
|
102
|
+
"typecheck": "tsc --noEmit"
|
|
76
103
|
}
|
|
77
104
|
}
|
|
78
105
|
```
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"$schema": "https://www.schemastore.org/package.json",
|
|
3
3
|
"name": "@regardio/dev",
|
|
4
|
-
"version": "2.4.
|
|
4
|
+
"version": "2.4.1",
|
|
5
5
|
"private": false,
|
|
6
6
|
"description": "Regardio development presets: biome, typescript, commitlint, markdownlint, vitest, playwright, sqlfluff, husky, and GitLab-flow ship tooling",
|
|
7
7
|
"keywords": [
|
|
@@ -44,7 +44,9 @@
|
|
|
44
44
|
},
|
|
45
45
|
"./typescript/base": "./src/typescript/base.json",
|
|
46
46
|
"./typescript/build": "./src/typescript/build.json",
|
|
47
|
+
"./typescript/library": "./src/typescript/library.json",
|
|
47
48
|
"./typescript/react": "./src/typescript/react.json",
|
|
49
|
+
"./typescript/react-library": "./src/typescript/react-library.json",
|
|
48
50
|
"./vitest/node": {
|
|
49
51
|
"import": "./dist/vitest/node.mjs",
|
|
50
52
|
"types": "./dist/vitest/node.d.mts"
|
|
@@ -61,6 +63,7 @@
|
|
|
61
63
|
},
|
|
62
64
|
"files": [
|
|
63
65
|
"dist",
|
|
66
|
+
"LICENSE",
|
|
64
67
|
"src/biome",
|
|
65
68
|
"src/commitlint",
|
|
66
69
|
"src/markdownlint",
|
|
@@ -73,7 +76,7 @@
|
|
|
73
76
|
"@total-typescript/ts-reset": "0.6.1",
|
|
74
77
|
"@types/node": "25.6.0",
|
|
75
78
|
"@vitest/coverage-v8": "4.1.5",
|
|
76
|
-
"tsdown": "0.
|
|
79
|
+
"tsdown": "0.22.0",
|
|
77
80
|
"vitest": "4.1.5"
|
|
78
81
|
},
|
|
79
82
|
"peerDependencies": {
|
|
@@ -90,9 +93,6 @@
|
|
|
90
93
|
"typescript": ">=6",
|
|
91
94
|
"vitest": ">=4"
|
|
92
95
|
},
|
|
93
|
-
"engines": {
|
|
94
|
-
"node": ">=24"
|
|
95
|
-
},
|
|
96
96
|
"scripts": {
|
|
97
97
|
"build": "tsdown",
|
|
98
98
|
"clean": "rimraf .turbo dist",
|
package/src/typescript/base.json
CHANGED
|
@@ -7,13 +7,11 @@
|
|
|
7
7
|
"allowUnusedLabels": false,
|
|
8
8
|
"alwaysStrict": true,
|
|
9
9
|
"checkJs": false,
|
|
10
|
-
"declaration": true,
|
|
11
10
|
"esModuleInterop": true,
|
|
12
11
|
"exactOptionalPropertyTypes": false,
|
|
13
12
|
"forceConsistentCasingInFileNames": true,
|
|
14
13
|
"incremental": false,
|
|
15
14
|
"inlineSources": false,
|
|
16
|
-
"isolatedDeclarations": true,
|
|
17
15
|
"isolatedModules": true,
|
|
18
16
|
"module": "ESNext",
|
|
19
17
|
"moduleDetection": "force",
|