@jxsuite/starters 1.7.0 → 1.8.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 +32 -124
- package/package.json +4 -4
- package/sites/blog/document.schema.json +5050 -13
- package/sites/blog/package.json +3 -3
- package/sites/blog/project.schema.json +24 -3
- package/sites/course/document.schema.json +5050 -13
- package/sites/course/package.json +3 -3
- package/sites/course/project.schema.json +24 -3
- package/sites/event/document.schema.json +5050 -13
- package/sites/event/package.json +3 -3
- package/sites/event/project.schema.json +24 -3
- package/sites/fitness-studio/document.schema.json +5050 -13
- package/sites/fitness-studio/package.json +3 -3
- package/sites/fitness-studio/project.schema.json +24 -3
- package/sites/home-services/document.schema.json +5050 -13
- package/sites/home-services/package.json +3 -3
- package/sites/home-services/project.schema.json +24 -3
- package/sites/museum/document.schema.json +5050 -13
- package/sites/museum/package.json +3 -3
- package/sites/museum/project.schema.json +24 -3
- package/sites/nonprofit/document.schema.json +5050 -13
- package/sites/nonprofit/package.json +3 -3
- package/sites/nonprofit/project.schema.json +24 -3
- package/sites/portfolio/document.schema.json +5050 -13
- package/sites/portfolio/package.json +3 -3
- package/sites/portfolio/project.schema.json +24 -3
- package/sites/professional-firm/document.schema.json +5050 -13
- package/sites/professional-firm/package.json +3 -3
- package/sites/professional-firm/project.schema.json +24 -3
- package/sites/real-estate/document.schema.json +5050 -13
- package/sites/real-estate/package.json +3 -3
- package/sites/real-estate/project.schema.json +24 -3
- package/sites/restaurant/document.schema.json +5050 -13
- package/sites/restaurant/package.json +3 -3
- package/sites/restaurant/project.schema.json +24 -3
- package/sites/saas/document.schema.json +5050 -13
- package/sites/saas/package.json +3 -3
- package/sites/saas/project.schema.json +24 -3
- package/sites/shop/document.schema.json +5050 -13
- package/sites/shop/package.json +3 -3
- package/sites/shop/project.schema.json +24 -3
package/README.md
CHANGED
|
@@ -1,14 +1,8 @@
|
|
|
1
1
|
# @jxsuite/starters
|
|
2
2
|
|
|
3
|
-
The catalogue of ready-made **starter sites** a user can clone when creating a
|
|
4
|
-
new Jx project, either from Studio's New Project picker or with
|
|
5
|
-
`bun create @jxsuite <directory> --template <id>`. The package is two things:
|
|
6
|
-
`registry.json`, the picker metadata, and `sites/`, one complete buildable Jx
|
|
7
|
-
project tree per starter.
|
|
3
|
+
The catalogue of ready-made **starter sites** a user can clone when creating a new Jx project, either from Studio's New Project picker or with `bun create @jxsuite <directory> --template <id>`. The package is two things: `registry.json`, the picker metadata, and `sites/`, one complete buildable Jx project tree per starter.
|
|
8
4
|
|
|
9
|
-
The TypeScript module itself is metadata-only. It reads the registry and
|
|
10
|
-
resolves a starter's directory; the copy-and-rewrite of a clone happens in
|
|
11
|
-
[`@jxsuite/create`](../create/README.md)'s `generate.ts`.
|
|
5
|
+
The TypeScript module itself is metadata-only. It reads the registry and resolves a starter's directory; the copy-and-rewrite of a clone happens in [`@jxsuite/create`](../create/README.md)'s `generate.ts`.
|
|
12
6
|
|
|
13
7
|
## API
|
|
14
8
|
|
|
@@ -20,18 +14,11 @@ getStarter("restaurant"); // StarterMeta | undefined
|
|
|
20
14
|
getStarterDir("restaurant"); // <SITES_DIR>/restaurant; throws on an unknown id
|
|
21
15
|
```
|
|
22
16
|
|
|
23
|
-
`SITES_DIR` is `join(import.meta.dirname, "sites")`, so the same code resolves
|
|
24
|
-
from the monorepo and from the copy staged inside the packaged desktop app.
|
|
25
|
-
`getStarterDir` throws `Unknown starter: "<id>"` rather than handing back a path
|
|
26
|
-
that does not exist. The registry is also exported raw as
|
|
27
|
-
`@jxsuite/starters/registry.json`, for consumers that want the array without the
|
|
28
|
-
module. The package publishes raw TypeScript: `exports["."]` is `./index.ts`,
|
|
29
|
-
there is no build step, and the module imports only `node:fs` and `node:path`.
|
|
17
|
+
`SITES_DIR` is `join(import.meta.dirname, "sites")`, so the same code resolves from the monorepo and from the copy staged inside the packaged desktop app. `getStarterDir` throws `Unknown starter: "<id>"` rather than handing back a path that does not exist. The registry is also exported raw as `@jxsuite/starters/registry.json`, for consumers that want the array without the module. The package publishes raw TypeScript: `exports["."]` is `./index.ts`, there is no build step, and the module imports only `node:fs` and `node:path`.
|
|
30
18
|
|
|
31
19
|
## The registry contract
|
|
32
20
|
|
|
33
|
-
`registry.json` is a flat JSON array. Every entry carries all eight fields;
|
|
34
|
-
there are no optional keys and no defaults (`index.ts`, `StarterMeta`):
|
|
21
|
+
`registry.json` is a flat JSON array. Every entry carries all eight fields; there are no optional keys and no defaults (`index.ts`, `StarterMeta`):
|
|
35
22
|
|
|
36
23
|
| Field | Contract |
|
|
37
24
|
| ------------- | ------------------------------------------------------------ |
|
|
@@ -44,24 +31,13 @@ there are no optional keys and no defaults (`index.ts`, `StarterMeta`):
|
|
|
44
31
|
| `accent` | Hex colour, `/^#[0-9a-fA-F]{3,8}$/` |
|
|
45
32
|
| `thumbnail` | `data:image/…` URI (**generated**, see below) |
|
|
46
33
|
|
|
47
|
-
`tests/registry.test.ts` asserts each of those, that ids are unique, and that
|
|
48
|
-
every id maps to a `sites/<id>/project.json`. Never restate the number of
|
|
49
|
-
starters in prose: `scripts/docs/check-site-claims.ts` reads `registry.json` and
|
|
50
|
-
fails the root `README.md` or any `sites/jxsuite.com/pages/**` page claiming a
|
|
51
|
-
different count (digits and number words alike). The same gate holds the
|
|
52
|
-
templates page's `::starter-card` slugs to the registry ids, both directions, so
|
|
53
|
-
a starter added without a card is caught too. It does not scan this file, so
|
|
54
|
-
here the habit is the only guard.
|
|
34
|
+
`tests/registry.test.ts` asserts each of those, that ids are unique, and that every id maps to a `sites/<id>/project.json`. Never restate the number of starters in prose: `scripts/docs/check-site-claims.ts` reads `registry.json` and fails the root `README.md` or any `sites/jxsuite.com/pages/**` page claiming a different count (digits and number words alike). The same gate holds the templates page's `::starter-card` slugs to the registry ids, both directions, so a starter added without a card is caught too. It does not scan this file, so here the habit is the only guard.
|
|
55
35
|
|
|
56
|
-
The registry is the source several unrelated gates read by path: the docs
|
|
57
|
-
generator, the marketing-claims count check, the packaged-desktop bundle
|
|
58
|
-
verifier, and the screenshot lane's shot selector.
|
|
36
|
+
The registry is the source several unrelated gates read by path: the docs generator, the marketing-claims count check, the packaged-desktop bundle verifier, and the screenshot lane's shot selector.
|
|
59
37
|
|
|
60
38
|
## Layout of `sites/`
|
|
61
39
|
|
|
62
|
-
Each `sites/<id>/` is a complete, buildable Jx project. It contains
|
|
63
|
-
`components/`, `layouts/`, `pages/`, `content/`, `public/`, `project.json`, a
|
|
64
|
-
`package.json`, and two **committed generated** entry schemas:
|
|
40
|
+
Each `sites/<id>/` is a complete, buildable Jx project. It contains `components/`, `layouts/`, `pages/`, `content/`, `public/`, `project.json`, a `package.json`, and two **committed generated** entry schemas:
|
|
65
41
|
|
|
66
42
|
```
|
|
67
43
|
sites/restaurant/
|
|
@@ -74,123 +50,55 @@ sites/restaurant/
|
|
|
74
50
|
.gitignore # .cache, dist, node_modules
|
|
75
51
|
```
|
|
76
52
|
|
|
77
|
-
`tests/validate.test.ts` holds the tree to its schemas: the two committed
|
|
78
|
-
bundles must be self-contained (no relative `$ref`s survive), `project.json`
|
|
79
|
-
must satisfy both `parseProjectConfig` and its own `project.schema.json`, every
|
|
80
|
-
`{components,layouts,pages}/**/*.json` must validate against
|
|
81
|
-
`document.schema.json` (and at least one must exist), and every
|
|
82
|
-
`content/**/*.md` must start with frontmatter. `tests/validate-projects.test.ts`
|
|
83
|
-
runs each starter through `@jxsuite/schema`'s `validateProjectFile` as well.
|
|
53
|
+
`tests/validate.test.ts` holds the tree to its schemas: the two committed bundles must be self-contained (no relative `$ref`s survive), `project.json` must satisfy both `parseProjectConfig` and its own `project.schema.json`, every `{components,layouts,pages}/**/*.json` must validate against `document.schema.json` (and at least one must exist), and every `content/**/*.md` must start with frontmatter. `tests/validate-projects.test.ts` runs each starter through `@jxsuite/schema`'s `validateProjectFile` as well.
|
|
84
54
|
|
|
85
|
-
Starters are not uniform by design: the museum starter is the multilingual one
|
|
86
|
-
(`i18n.locales: ["en", "fr-CA", "ar"]` with `routing: "prefix-except-default"`),
|
|
87
|
-
and real-estate's `listings` collection uses `format: "Csv"` where the others
|
|
88
|
-
use Markdown.
|
|
55
|
+
Starters are not uniform by design: the museum starter is the multilingual one (`i18n.locales: ["en", "fr-CA", "ar"]` with `routing: "prefix-except-default"`), and real-estate's `listings` collection uses `format: "Csv"` where the others use Markdown.
|
|
89
56
|
|
|
90
57
|
## Consumption: cloned, never depended on
|
|
91
58
|
|
|
92
|
-
Nothing a user ships depends on this package. `@jxsuite/create` imports
|
|
93
|
-
`getStarterDir` lazily (so blank projects never load the large starters
|
|
94
|
-
package), copies the tree, and then re-stamps identity:
|
|
59
|
+
Nothing a user ships depends on this package. `@jxsuite/create` imports `getStarterDir` lazily (so blank projects never load the large starters package), copies the tree, and then re-stamps identity:
|
|
95
60
|
|
|
96
61
|
```sh
|
|
97
62
|
bun create @jxsuite my-site --template restaurant
|
|
98
63
|
```
|
|
99
64
|
|
|
100
|
-
- **Excluded from the copy**: `node_modules`, `dist`, `.cache`, `.jx-cache`,
|
|
101
|
-
|
|
102
|
-
- **`
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
a clone never inherits whatever the in-repo starter pinned.
|
|
107
|
-
- `--template` resolves built-in template ids first, then registry starter ids;
|
|
108
|
-
an unknown id falls back to `blank`.
|
|
109
|
-
|
|
110
|
-
Two other consumers read the registry live: the dev server exposes it to
|
|
111
|
-
Studio's picker at `GET /__studio/starters`, returning `listStarters()` verbatim
|
|
112
|
-
(specs/server.md §4.1), and the desktop app imports `listStarters` directly in
|
|
113
|
-
both its Electrobun and Chromium window layers.
|
|
65
|
+
- **Excluded from the copy**: `node_modules`, `dist`, `.cache`, `.jx-cache`, `.git`, and `images.json` (`packages/create/generate.ts`).
|
|
66
|
+
- **`project.json` is preserved**, with only `name` / `url` / `description` / `build.adapter` re-stamped (plus design tokens when the quickstart supplies them). Content, components, layouts and public assets are copied verbatim.
|
|
67
|
+
- **`package.json` is rebuilt from scratch** with current dependency ranges, so a clone never inherits whatever the in-repo starter pinned.
|
|
68
|
+
- `--template` resolves built-in template ids first, then registry starter ids; an unknown id falls back to `blank`.
|
|
69
|
+
|
|
70
|
+
Two other consumers read the registry live: the dev server exposes it to Studio's picker at `GET /__studio/starters`, returning `listStarters()` verbatim (specs/server.md §4.1), and the desktop app imports `listStarters` directly in both its Electrobun and Chromium window layers.
|
|
114
71
|
|
|
115
72
|
## Authoring or modifying a starter
|
|
116
73
|
|
|
117
74
|
1. Add the `sites/<id>/` tree and a `registry.json` entry with all eight fields.
|
|
118
|
-
2. `bun run schema:generate-all` regenerates every `project.schema.json` and
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
result in CI, so a stale entry schema is a red build.
|
|
122
|
-
`.github/workflows/schemas.yml` also regenerates it and pushes the fix to
|
|
123
|
-
your branch, with a comment naming the JSON Pointers that moved.
|
|
124
|
-
3. `bun run docs:generate`, because `docs/studio/projects/starters.md` is
|
|
125
|
-
rendered from `registry.json` by `scripts/docs/generators/starters.ts`.
|
|
126
|
-
Hand-editing it is a bug; CI diffs the page.
|
|
127
|
-
4. `bun run screenshots:thumbnails`. The `thumbnail` data URI is not
|
|
128
|
-
hand-authored. The script builds the starter with image optimization off,
|
|
129
|
-
serves `dist/`, screenshots the hero viewport in headless Chromium, and
|
|
130
|
-
writes the small JPEG into `registry.json` plus a full-res JPEG into
|
|
131
|
-
`sites/jxsuite.com/public/starters/<id>.jpg`. (This is why `registry.json` is
|
|
132
|
-
large.)
|
|
75
|
+
2. `bun run schema:generate-all` regenerates every `project.schema.json` and `document.schema.json`. **Always via this script**, never by hand: it runs `schema:clean-roots` first (see below). `bun run schema:verify` proves the result in CI, so a stale entry schema is a red build. `.github/workflows/schemas.yml` also regenerates it and pushes the fix to your branch, with a comment naming the JSON Pointers that moved.
|
|
76
|
+
3. Nothing for the docs: `docs/studio/projects/starters.md` is rendered from `registry.json` by `scripts/docs/generators/starters.ts` when the site builds, and is never committed (`bun run docs:generate` previews it).
|
|
77
|
+
4. `bun run screenshots:thumbnails`. The `thumbnail` data URI is not hand-authored. The script builds the starter with image optimization off, serves `dist/`, screenshots the hero viewport in headless Chromium, and writes the small JPEG into `registry.json` plus a full-res JPEG into `sites/jxsuite.com/public/starters/<id>.jpg`. (This is why `registry.json` is large.)
|
|
133
78
|
5. Photos, if the starter ships any:
|
|
134
79
|
|
|
135
80
|
```sh
|
|
136
81
|
PEXELS_API_KEY=… bun packages/starters/scripts/fetch-photos.ts <site-id> [--force]
|
|
137
82
|
```
|
|
138
83
|
|
|
139
|
-
`images.json` holds `{ site, thumbnail?, images }`, where each image is
|
|
140
|
-
`{ role, query, orientation?, photoId? }`. The pinned `photoId` makes re-runs
|
|
141
|
-
fetch the _same_ images; `--force` re-picks even pinned ones. The script
|
|
142
|
-
upserts a per-site block in `CREDITS.md` between `<!-- site:<id>:start -->`
|
|
143
|
-
and `<!-- site:<id>:end -->`.
|
|
144
|
-
Committed output is plain image files, so scaffolded projects have no Pexels
|
|
145
|
-
or network dependency.
|
|
84
|
+
`images.json` holds `{ site, thumbnail?, images }`, where each image is `{ role, query, orientation?, photoId? }`. The pinned `photoId` makes re-runs fetch the _same_ images; `--force` re-picks even pinned ones. The script upserts a per-site block in `CREDITS.md` between `<!-- site:<id>:start -->` and `<!-- site:<id>:end -->`. Committed output is plain image files, so scaffolded projects have no Pexels or network dependency.
|
|
146
85
|
|
|
147
|
-
6. `bun test --isolate` from `packages/starters`. Per-file coverage is gated at
|
|
148
|
-
99% lines / 99% functions (`bunfig.toml`); `sites/`, `scripts/` and `tests/`
|
|
149
|
-
are excluded from coverage.
|
|
86
|
+
6. `bun test --isolate` from `packages/starters`. Per-file coverage is gated at 99% lines / 99% functions (`bunfig.toml`); `sites/`, `scripts/` and `tests/` are excluded from coverage.
|
|
150
87
|
|
|
151
|
-
Adding a starter needs **no** desktop config change:
|
|
152
|
-
`packages/desktop/scripts/verify-bundle.ts` derives its checklist from the
|
|
153
|
-
staged registry, so every new id is covered automatically.
|
|
88
|
+
Adding a starter needs **no** desktop config change: `packages/desktop/scripts/verify-bundle.ts` derives its checklist from the staged registry, so every new id is covered automatically.
|
|
154
89
|
|
|
155
90
|
## Hazards
|
|
156
91
|
|
|
157
|
-
**The shadowed core.** A starter's `package.json` pins _published_ `@jxsuite/*`
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
`@jxsuite
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
`node_modules/@jxsuite/*` and a stray lockfile. Third-party dependencies stay,
|
|
167
|
-
because the install is what makes the starter preview, and a workspace
|
|
168
|
-
_symlink_ is never removed.
|
|
169
|
-
|
|
170
|
-
**Never put that cleanup in a starter's `package.json`.** This package publishes
|
|
171
|
-
`sites/`, so those manifests ship to end users; a `postinstall` or `preschema`
|
|
172
|
-
hook there would run on their machine and delete the dependencies they just
|
|
173
|
-
installed. The monorepo has the workspace being shadowed, so the monorepo owns
|
|
174
|
-
the cleanup.
|
|
175
|
-
|
|
176
|
-
**Do not hand-edit the `@jxsuite/*` ranges in `sites/*/package.json`.**
|
|
177
|
-
release-please rewrites them inside its release commit via `extra-files`; the
|
|
178
|
-
gate is `bun run templates:check` (`templates:sync` to repair).
|
|
179
|
-
|
|
180
|
-
**Packaged-desktop path contract.** ElectroBun inlines the bun-side JS graph, so
|
|
181
|
-
`import.meta.dirname` resolves to `app/bun/` at runtime. `registry.json` and
|
|
182
|
-
`sites/` must therefore be staged to `bun/registry.json` and `bun/sites` by
|
|
183
|
-
`build.copy` in `packages/desktop/electrobun.config.ts` (specs/desktop.md §7.4).
|
|
184
|
-
|
|
185
|
-
**The screenshot lane ignores this package's source.** It watches only
|
|
186
|
-
`registry.json` and the six starter roots a shot actually opens
|
|
187
|
-
(`.github/workflows/screenshots.yml`); a registry change arms exactly one shot,
|
|
188
|
-
`new-project`, because that modal's gallery _is_ `listStarters()`.
|
|
92
|
+
**The shadowed core.** A starter's `package.json` pins _published_ `@jxsuite/*` ranges. It must, because it is a template a user scaffolds from, and starters are not bun workspace members, so `workspace:^` is unavailable. Iterating a starter in Studio runs `bun install` in that root, which materialises a real `@jxsuite/schema` beside a workspace far ahead of it. That has already produced a starter document schema narrower than the starter's own content, unnoticed for six weeks (`scripts/check-shadowed-core.ts` carries the full post-mortem). `bun run schema:generate-all` therefore runs `schema:clean-roots` (`bun scripts/check-shadowed-core.ts --fix`) first, removing only `node_modules/@jxsuite/*` and a stray lockfile. Third-party dependencies stay, because the install is what makes the starter preview, and a workspace _symlink_ is never removed.
|
|
93
|
+
|
|
94
|
+
**Never put that cleanup in a starter's `package.json`.** This package publishes `sites/`, so those manifests ship to end users; a `postinstall` or `preschema` hook there would run on their machine and delete the dependencies they just installed. The monorepo has the workspace being shadowed, so the monorepo owns the cleanup.
|
|
95
|
+
|
|
96
|
+
**Do not hand-edit the `@jxsuite/*` ranges in `sites/*/package.json`.** release-please rewrites them inside its release commit via `extra-files`; the gate is `bun run templates:check` (`templates:sync` to repair).
|
|
97
|
+
|
|
98
|
+
**Packaged-desktop path contract.** ElectroBun inlines the bun-side JS graph, so `import.meta.dirname` resolves to `app/bun/` at runtime. `registry.json` and `sites/` must therefore be staged to `bun/registry.json` and `bun/sites` by `build.copy` in `packages/desktop/electrobun.config.ts` (specs/desktop.md §7.4).
|
|
99
|
+
|
|
100
|
+
**The screenshot lane ignores this package's source.** It watches only `registry.json` and the six starter roots a shot actually opens (`.github/workflows/screenshots.yml`); a registry change arms exactly one shot, `new-project`, because that modal's gallery _is_ `listStarters()`.
|
|
189
101
|
|
|
190
102
|
## Versioning
|
|
191
103
|
|
|
192
|
-
Published to npm as `@jxsuite/starters`. Like every `@jxsuite` package, it ships
|
|
193
|
-
TypeScript source and follows the monorepo's release train (the `starters`
|
|
194
|
-
release-please component). Within the monorepo, `@jxsuite/create` depends on it
|
|
195
|
-
via `workspace:^`. Because consumption is a one-time clone, publishing a new
|
|
196
|
-
version never changes an existing project.
|
|
104
|
+
Published to npm as `@jxsuite/starters`. Like every `@jxsuite` package, it ships TypeScript source and follows the monorepo's release train (the `starters` release-please component). Within the monorepo, `@jxsuite/create` depends on it via `workspace:^`. Because consumption is a one-time clone, publishing a new version never changes an existing project.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@jxsuite/starters",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.8.0",
|
|
4
4
|
"description": "Starter site templates for new Jx projects",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"repository": {
|
|
@@ -26,9 +26,9 @@
|
|
|
26
26
|
"test:coverage": "bun test --isolate --coverage"
|
|
27
27
|
},
|
|
28
28
|
"devDependencies": {
|
|
29
|
-
"@jxsuite/parser": "^1.
|
|
30
|
-
"@jxsuite/runtime": "^
|
|
31
|
-
"@jxsuite/schema": "^2.
|
|
29
|
+
"@jxsuite/parser": "^1.8.0",
|
|
30
|
+
"@jxsuite/runtime": "^4.0.0",
|
|
31
|
+
"@jxsuite/schema": "^2.2.0",
|
|
32
32
|
"ajv": "^8.20.0",
|
|
33
33
|
"ajv-formats": "^3.0.1"
|
|
34
34
|
}
|