create-warlock 5.34.0 → 5.34.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/CHANGELOG.md CHANGED
@@ -4,6 +4,12 @@ All notable changes to `create-warlock` are documented in this file.
4
4
 
5
5
  The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/). `@warlock.js/*` packages are released in lockstep — every package shares the same version number, so a version below may list only the changes that affected this package.
6
6
 
7
+ ## 5.34.1 - 2026-10-19
8
+
9
+ ### Changed
10
+
11
+ - Document setup-file ownership in the Web starter and its code standards; retain metadata in `config.metadata` and cover UI/setup pairs in template integrity specs.
12
+
7
13
  ## 5.34.0 - 2026-10-19
8
14
 
9
15
  ### Removed
package/package.json CHANGED
@@ -13,7 +13,7 @@
13
13
  "dependencies": {
14
14
  "@clack/prompts": "^0.8.2",
15
15
  "@mongez/copper": "^2.1.3",
16
- "@warlock.js/fs": "5.34.0",
16
+ "@warlock.js/fs": "5.34.1",
17
17
  "@mongez/reinforcements": "^4.0.2",
18
18
  "cross-spawn": "^7.0.3",
19
19
  "rimraf": "^6.0.1",
@@ -22,7 +22,7 @@
22
22
  "engines": {
23
23
  "node": ">=22.15"
24
24
  },
25
- "version": "5.34.0",
25
+ "version": "5.34.1",
26
26
  "type": "module",
27
27
  "main": "./esm/index.mjs",
28
28
  "module": "./esm/index.mjs",
@@ -106,8 +106,9 @@ If you scaffolded with the web stack, `src/web` holds server-rendered React
106
106
  pages served by the same process as the API:
107
107
 
108
108
  - `src/web/root.tsx` — the HTML document every page renders inside
109
- - `src/web/home/index.page.tsx` — the page at `/`
110
- - `src/web/404.page.tsx` — the not-found page
109
+ - `src/web/home/index.page.tsx` — the UI at `/`; `index.setup.ts` owns its config (including `config.metadata`), loader, and registration
110
+ - `src/web/404.page.tsx` — the not-found UI; `404.setup.ts` owns its `config.metadata`
111
+ - `src/web/root.setup.ts` — document policy, paired with the `root.tsx` component
111
112
  - `*.page.tsx` files under `src/web` are pages; the folder path is the URL
112
113
 
113
114
  Styles live in imported CSS files (`src/web/app.css`). The API-only stack has no
@@ -53,19 +53,19 @@ make the feature harder to read.
53
53
 
54
54
  ## 1. Keep the page contract, make the implementation thin
55
55
 
56
- Warlock's file-routed modules have one policy export: `config`. A page's
57
- `route`, `cache`, `middleware`, `validation`, `metadata`, and `sitemap` all
58
- belong in that object; do not use legacy top-level policy exports. `loader`,
59
- `register`, `ErrorBoundary`, and the default component remain top-level
60
- exports. Layouts, registration files, `root.tsx`, `404.page.tsx`, and
61
- `error.page.tsx` also have framework-defined roles. These are intentional
62
- exceptions to the generic "one primary export per file" rule; do not split
63
- them merely to satisfy it.
56
+ Page logic lives in the matching `.setup.ts` file: `config`, `loader`,
57
+ `register`, and `action`/`actions`. UI files contain the default
58
+ component and named components such as `ErrorBoundary`. Pair `layout.tsx` with
59
+ `layout.setup.ts`, `root.tsx` with `root.setup.ts`, and `error.page.tsx` with
60
+ `error.setup.ts`. Use type-only imports from setup for loader/action inference.
61
+ The framework projects browser-safe `register()` code to the client. Put route,
62
+ cache, validation, middleware, metadata, and sitemap policy inside `config`;
63
+ metadata always belongs in `config.metadata`.
64
64
 
65
65
  Use the config type that matches the module. A page can preserve loader data
66
66
  inference for metadata by satisfying `PageConfig<typeof loader>`:
67
67
 
68
- ```tsx
68
+ ```ts title="src/web/posts.setup.ts"
69
69
  import type { PageConfig } from "@warlock.js/web";
70
70
 
71
71
  export async function loader() {
@@ -79,7 +79,9 @@ export const config = {
79
79
  metadata: ({ data }) => ({ title: data.title }),
80
80
  sitemap: { changefreq: "daily" },
81
81
  } satisfies PageConfig<typeof loader>;
82
+ ```
82
83
 
84
+ ```tsx title="src/web/posts.page.tsx"
83
85
  export default function PostsPage() {
84
86
  return <main>Posts</main>;
85
87
  }
@@ -93,21 +95,22 @@ route-name and parameter types are not available in 5.17.
93
95
  Layouts use one `config satisfies LayoutConfig` object for `prefix`,
94
96
  `middleware`, `metadata`, and a sitemap default. Roots use one
95
97
  `config satisfies RootConfig` object for `middleware` and the static `strictMode`
96
- flag: root modules do
97
- not declare routes, prefixes, metadata, validation, cache, or sitemap policy.
98
-
99
- ```tsx
100
- import type { LayoutConfig, RootConfig } from "@warlock.js/web";
98
+ flag, plus metadata defaults. Root modules do not declare routes, prefixes,
99
+ validation, cache, or sitemap policy.
101
100
 
102
- // src/web/account/layout.tsx
101
+ ```ts title="src/web/account/layout.setup.ts"
102
+ import type { LayoutConfig } from "@warlock.js/web";
103
103
  export const config = {
104
104
  prefix: "/account",
105
105
  middleware: [requireUser],
106
106
  metadata: { robots: "noindex" },
107
107
  sitemap: false,
108
108
  } satisfies LayoutConfig;
109
+ ```
110
+
111
+ ```ts title="src/web/root.setup.ts"
112
+ import type { RootConfig } from "@warlock.js/web";
109
113
 
110
- // src/web/root.tsx
111
114
  export const config = {
112
115
  middleware: [loadRequestContext],
113
116
  } satisfies RootConfig;
@@ -119,8 +122,8 @@ let TypeScript infer its return. Use
119
122
  `LayoutLoaderContext` for a layout, and `AppLoaderContext` for the root. Do not
120
123
  annotate the whole function as `PageLoader`, use `satisfies` on a loader,
121
124
  duplicate its payload shape, or cast an unknown return.
122
- A page file declares its route contract, coordinates a controller-like loader,
123
- and composes presentational components. The loader validates input, calls
125
+ A setup file declares the route contract and coordinates a controller-like
126
+ loader; its UI file composes presentational components. The loader validates input, calls
124
127
  named services under `src/app/<domain>/services/`, converts results through
125
128
  their resources, and returns the page data. **Every model/repository read and
126
129
  every business rule belongs in an app service, even when the loader would need
@@ -134,7 +137,7 @@ Extract substantive view sections into cohesive components. A component
134
137
  that needs any behavior gets a separate feature-named custom-hook file; a
135
138
  component with no behavior stays presentational and needs no hook. Split by
136
139
  responsibility, not by a mechanical line-count limit. Framework exports
137
- remain in the page file even when their work is delegated elsewhere.
140
+ for logic remain in the setup file even when their work is delegated elsewhere.
138
141
 
139
142
  Preserve the framework's rendering boundary: `root.tsx` owns the document,
140
143
  `#vessel` and `<Scripts />`; the loader runs on the server, while the rendered