@janga/norna 0.7.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.
Files changed (77) hide show
  1. package/LICENSE +674 -0
  2. package/README.md +109 -0
  3. package/astro.config.mjs +17 -0
  4. package/bin/norna.mjs +170 -0
  5. package/docs/README.md +48 -0
  6. package/docs/command-organization.md +402 -0
  7. package/docs/commands.md +152 -0
  8. package/docs/configuration.md +376 -0
  9. package/docs/content.md +384 -0
  10. package/docs/engine-development.md +164 -0
  11. package/docs/getting-started.md +96 -0
  12. package/docs/images-and-metadata.md +88 -0
  13. package/docs/local-development.md +61 -0
  14. package/docs/publishing.md +81 -0
  15. package/docs/site-examples-structure-note.md +105 -0
  16. package/docs/site-structure.md +81 -0
  17. package/fixtures/basic/site/.norna/generated-images.json +1 -0
  18. package/fixtures/basic/site/config.mjs +59 -0
  19. package/fixtures/basic/site/content.md +17 -0
  20. package/fixtures/basic/site/images/work/.gitkeep +1 -0
  21. package/fixtures/basic/site/public/robots.txt +2 -0
  22. package/fixtures/basic/site/theme.md +7 -0
  23. package/package.json +90 -0
  24. package/scripts/build-site.mjs +16 -0
  25. package/scripts/check-config.mjs +37 -0
  26. package/scripts/deploy-site.mjs +389 -0
  27. package/scripts/dev-local.mjs +313 -0
  28. package/scripts/doctor.mjs +38 -0
  29. package/scripts/engine-version.mjs +137 -0
  30. package/scripts/generate-images.mjs +369 -0
  31. package/scripts/init-site.mjs +249 -0
  32. package/scripts/lib/astro-command.mjs +34 -0
  33. package/scripts/lib/ci-lockfile.mjs +34 -0
  34. package/scripts/lib/image-dimensions.mjs +78 -0
  35. package/scripts/lib/presentation.mjs +72 -0
  36. package/scripts/lib/project-config.mjs +322 -0
  37. package/scripts/lib/run-command.mjs +21 -0
  38. package/scripts/lib/site-content.mjs +392 -0
  39. package/scripts/lib/site-paths.mjs +127 -0
  40. package/scripts/lib/typography.mjs +166 -0
  41. package/scripts/release.mjs +77 -0
  42. package/scripts/show-typography.mjs +210 -0
  43. package/scripts/sync-content-sections.mjs +610 -0
  44. package/scripts/sync-site-public.mjs +42 -0
  45. package/scripts/test-ci-lockfile.mjs +65 -0
  46. package/scripts/test-content-check.mjs +364 -0
  47. package/scripts/test-engine-commands.mjs +128 -0
  48. package/scripts/test-navigation-preview.mjs +108 -0
  49. package/scripts/test-navigation.mjs +116 -0
  50. package/scripts/test-package-check.mjs +394 -0
  51. package/scripts/test-site-public.mjs +85 -0
  52. package/scripts/test-temporary-visibility.mjs +99 -0
  53. package/scripts/update-engine.mjs +127 -0
  54. package/scripts/watch-pages-deploy.mjs +430 -0
  55. package/src/components/GalleryGrid.astro +221 -0
  56. package/src/components/SiteNavigation.astro +410 -0
  57. package/src/components/SitePage.astro +69 -0
  58. package/src/components/SiteSection.astro +174 -0
  59. package/src/content.config.ts +171 -0
  60. package/src/layouts/BaseLayout.astro +90 -0
  61. package/src/lib/generatedImages.ts +63 -0
  62. package/src/lib/sectionContent.ts +125 -0
  63. package/src/lib/sitePages.ts +80 -0
  64. package/src/lib/sitePublicAssets.ts +39 -0
  65. package/src/lib/visibility.ts +35 -0
  66. package/src/pages/[slug].astro +31 -0
  67. package/src/pages/index.astro +16 -0
  68. package/src/styles/global.css +872 -0
  69. package/starters/basic/.github/workflows/deploy.yml +65 -0
  70. package/starters/basic/README.md +55 -0
  71. package/starters/basic/package.json +35 -0
  72. package/starters/basic/site/config.mjs +60 -0
  73. package/starters/basic/site/content.md +21 -0
  74. package/starters/basic/site/images/work/.gitkeep +1 -0
  75. package/starters/basic/site/public/robots.txt +2 -0
  76. package/starters/basic/site/theme.md +53 -0
  77. package/tsconfig.json +5 -0
@@ -0,0 +1,402 @@
1
+ # Command Organization
2
+
3
+ This document defines the naming principles for commands in `norna`,
4
+ gallery site repositories, and GitHub projects that embed a gallery.
5
+
6
+ The goal is that command names reveal both the action and the scope they affect.
7
+ This matters because the same repository can contain a gallery, an app, tests,
8
+ and a publishing workflow that should not accidentally share ambiguous command
9
+ names.
10
+
11
+ ## Situations
12
+
13
+ `norna` commands must be understandable in three situations:
14
+
15
+ - Pure gallery project: the repository exists only to publish one
16
+ `norna` site.
17
+ - Mixed gallery project: the repository contains another project, such as an
18
+ app or library, and includes a `norna` presentation as one part of its
19
+ GitHub Pages output.
20
+ - Engine development: the repository is `norna` itself.
21
+
22
+ ## Namespaces
23
+
24
+ Use these namespaces consistently.
25
+
26
+ ### `norna:*`
27
+
28
+ Use `norna:*` npm scripts in repositories that consume `norna`.
29
+
30
+ These scripts operate on a selected gallery source directory. In a pure gallery
31
+ project that directory is normally `site/`. In a mixed project it may be a more
32
+ specific directory such as `presentation/`, with the script setting
33
+ `NORNA_SITE_DIR` or passing `norna --site-dir`.
34
+
35
+ Examples:
36
+
37
+ ```sh
38
+ npm run norna:dev
39
+ npm run norna:check
40
+ npm run norna:sync
41
+ npm run norna:build
42
+ ```
43
+
44
+ Mixed projects must use `norna:*` for gallery work so names such as `build`,
45
+ `test`, and `deploy` can remain under the containing project's control.
46
+
47
+ Pure gallery projects should also use `norna:*` as the primary documented
48
+ interface. They may provide unprefixed aliases when the alias means the same
49
+ thing for the whole repository, for example `npm run build` as an alias for
50
+ `npm run norna:build`.
51
+
52
+ ### Project Commands That Call Gallery Commands
53
+
54
+ `norna` does not define a consuming project's unprefixed commands. Names
55
+ such as `build`, `test`, and `deploy` belong to the project that consumes the
56
+ gallery engine.
57
+
58
+ Examples:
59
+
60
+ ```sh
61
+ npm run build
62
+ npm run test
63
+ npm run deploy
64
+ ```
65
+
66
+ When those project commands need the gallery, they should call `norna:*`
67
+ scripts instead of calling `norna` directly. That keeps the selected
68
+ gallery source directory and other project-specific wrapper behavior in one
69
+ place.
70
+
71
+ In a mixed project, if `npm run build` exists, it should build the project's
72
+ complete publishable artifact, not only the gallery. If the project publishes a
73
+ GitHub Pages artifact containing both a gallery and an app, `build` should
74
+ produce that full artifact and may call `npm run norna:build` internally.
75
+
76
+ In a pure gallery project, project commands may be aliases to `norna:*`
77
+ commands because the gallery is the whole project.
78
+
79
+ ### `release:*`
80
+
81
+ Use `release:*` only in the engine repository.
82
+
83
+ Examples:
84
+
85
+ ```sh
86
+ npm run release:patch
87
+ npm run release:minor
88
+ npm run release:major
89
+ npm run release:publish
90
+ ```
91
+
92
+ These commands change or publish the reusable `@janga/norna` package.
93
+ They must not be part of ordinary site repositories.
94
+
95
+ ### Direct CLI Commands
96
+
97
+ The `norna` binary is the stable low-level command surface.
98
+
99
+ Examples:
100
+
101
+ ```sh
102
+ norna content:check
103
+ norna content:sync
104
+ norna build
105
+ norna deploy
106
+ ```
107
+
108
+ Npm scripts in site repositories are convenience wrappers around this binary.
109
+ Documentation for ordinary site work should prefer the npm scripts because they
110
+ can set the correct site directory for the repository.
111
+
112
+ ## Functional Groups
113
+
114
+ ### Install Gallery Software
115
+
116
+ Creating a new pure gallery project starts outside the target project because
117
+ the target does not have a `package.json` yet:
118
+
119
+ ```sh
120
+ npx @janga/norna@latest init my-gallery
121
+ cd my-gallery
122
+ npm install
123
+ ```
124
+
125
+ A mixed project already has its own repository and may have its own
126
+ `package.json`. In that situation the gallery dependency should be installed as
127
+ part of the existing project setup:
128
+
129
+ ```sh
130
+ npm install --save-exact @janga/norna
131
+ ```
132
+
133
+ The mixed project should then add `norna:*` scripts that point at the chosen
134
+ gallery source directory.
135
+
136
+ Engine development uses ordinary package installation in the engine repository:
137
+
138
+ ```sh
139
+ npm install
140
+ ```
141
+
142
+ ### Upgrade Or Inspect Gallery Software
143
+
144
+ In a consuming repository, upgrading or inspecting the installed gallery engine
145
+ is norna maintenance, so the preferred namespace is `norna:*`:
146
+
147
+ ```sh
148
+ npm run norna:engine:version
149
+ npm run norna:engine:update
150
+ npm run norna:engine:update -- 0.2.0
151
+ ```
152
+
153
+ These commands update the `@janga/norna` dependency and lockfile used by
154
+ the repository. They do not release the engine package.
155
+
156
+ In the engine repository, version changes belong to `release:*`:
157
+
158
+ ```sh
159
+ npm run release:minor
160
+ npm run release:publish
161
+ ```
162
+
163
+ ### Initialize A Gallery Project Directory
164
+
165
+ Initialization is a direct CLI operation because it usually happens before a
166
+ project has npm scripts:
167
+
168
+ ```sh
169
+ npx @janga/norna@latest init my-gallery
170
+ ```
171
+
172
+ The initializer should support two setup modes that share the same `norna:*`
173
+ command vocabulary.
174
+
175
+ #### Pure Setup
176
+
177
+ Pure setup creates a new project where the gallery is the whole repository:
178
+
179
+ ```sh
180
+ npx @janga/norna@latest init my-gallery --type pure
181
+ ```
182
+
183
+ This should be the default when the target is a new or empty directory.
184
+
185
+ Pure setup should create:
186
+
187
+ - a normal gallery source directory, normally `site/`;
188
+ - a `package.json` with `norna:*` scripts;
189
+ - unprefixed convenience aliases only when they mean the same thing as the
190
+ whole project, for example `build` as an alias for `norna:build`;
191
+ - the standard GitHub Pages workflow for publishing the gallery.
192
+
193
+ #### Embedded Setup
194
+
195
+ Embedded setup adds a gallery to an existing project without taking ownership
196
+ of that project's root commands:
197
+
198
+ ```sh
199
+ npx @janga/norna@latest init . --type embedded --site-dir presentation
200
+ ```
201
+
202
+ Embedded setup should be selected explicitly, or suggested when the target
203
+ already contains a `package.json`.
204
+
205
+ Embedded setup should create or update only the gallery-owned parts:
206
+
207
+ - the chosen gallery source directory, for example `presentation/`;
208
+ - `@janga/norna` as a project dependency;
209
+ - `norna:*` scripts that set the selected site directory;
210
+ - no unprefixed aliases such as `build`, `test`, `dev`, or `deploy`;
211
+ - no project publishing workflow unless the caller explicitly asks for one.
212
+
213
+ Embedded setup must not overwrite existing npm scripts without explicit user
214
+ confirmation. If a needed `norna:*` script already exists, the initializer
215
+ should report the conflict and let the user decide whether to replace it.
216
+
217
+ ### Control The Dev Server
218
+
219
+ Norna dev-server commands belong under `norna:dev:*` in consuming
220
+ repositories:
221
+
222
+ ```sh
223
+ npm run norna:dev
224
+ npm run norna:dev:lan
225
+ npm run norna:dev:restart
226
+ npm run norna:dev:status
227
+ npm run norna:dev:logs
228
+ npm run norna:dev:stop
229
+ ```
230
+
231
+ The shorter `norna:dev` starts the normal local server. Subcommands manage
232
+ the same server.
233
+
234
+ In the engine repository, engine/demo development may use the engine's own
235
+ unprefixed commands:
236
+
237
+ ```sh
238
+ npm run dev:local
239
+ npm run dev:lan
240
+ ```
241
+
242
+ ### Test Configuration And Content
243
+
244
+ Norna validation should use `norna:check` for the normal full check and
245
+ more specific commands when a caller needs one part:
246
+
247
+ ```sh
248
+ npm run norna:check
249
+ npm run norna:config:check
250
+ npm run norna:content:check
251
+ ```
252
+
253
+ `norna:check` should run configuration and content checks in the order needed
254
+ by the engine.
255
+
256
+ Project-level tests remain project-owned commands:
257
+
258
+ ```sh
259
+ npm run test
260
+ ```
261
+
262
+ If a mixed project defines `test`, that command should cover the whole project.
263
+ It may call `norna:check`, but it should not be a hidden synonym for only
264
+ gallery validation.
265
+
266
+ ### Inspect Gallery Presentation
267
+
268
+ Commands that inspect gallery presentation without changing source files use
269
+ `norna:*` in consuming repositories:
270
+
271
+ ```sh
272
+ npm run norna:typography:presets
273
+ npm run norna:typography:show
274
+ ```
275
+
276
+ `norna:typography:presets` shows the built-in typography presets from the
277
+ installed engine. `norna:typography:show` shows the effective typography for
278
+ the selected gallery after presets and overrides have been applied.
279
+
280
+ ### Correct Content And Configuration
281
+
282
+ Commands that modify gallery-owned source files use `norna:*`:
283
+
284
+ ```sh
285
+ npm run norna:sync
286
+ npm run norna:public
287
+ npm run norna:images
288
+ ```
289
+
290
+ `norna:sync` is the preferred npm wrapper for `norna content:sync`.
291
+ Messages emitted by the engine should mention the direct CLI command and the
292
+ starter-style npm wrapper when suggesting a fix.
293
+
294
+ Configuration edits are normally manual edits to the selected gallery
295
+ `config.mjs`, followed by:
296
+
297
+ ```sh
298
+ npm run norna:config:check
299
+ ```
300
+
301
+ ### Build
302
+
303
+ In a pure gallery project:
304
+
305
+ ```sh
306
+ npm run norna:build
307
+ npm run norna:build:local
308
+ npm run build
309
+ ```
310
+
311
+ `norna:build:local` builds and restarts the local dev server. `build` may
312
+ alias `norna:build` because the gallery is the whole project.
313
+
314
+ In a mixed project:
315
+
316
+ ```sh
317
+ npm run norna:build
318
+ npm run norna:build:local
319
+ npm run build
320
+ ```
321
+
322
+ `norna:build` builds only the gallery. `norna:build:local` builds the
323
+ gallery and restarts the local gallery dev server. If the mixed project defines
324
+ `build`, that project command should build the complete publishable artifact,
325
+ such as a GitHub Pages output that combines the gallery with an app. It may call
326
+ `norna:build` internally.
327
+
328
+ In the engine repository:
329
+
330
+ ```sh
331
+ npm run build
332
+ npm run demo:build
333
+ npm run test:fixture:build
334
+ ```
335
+
336
+ Engine build commands verify the reusable package, fixtures, or demo site.
337
+
338
+ ### Publish
339
+
340
+ Norna deploy helpers belong under `norna:deploy*` in consuming
341
+ repositories:
342
+
343
+ ```sh
344
+ npm run norna:deploy
345
+ npm run norna:deploy:commit
346
+ ```
347
+
348
+ Use these only when the gallery is the deployable site or when the containing
349
+ project deliberately delegates deployment to the gallery engine.
350
+
351
+ Mixed projects may instead have project-owned deploy commands:
352
+
353
+ ```sh
354
+ npm run deploy
355
+ ```
356
+
357
+ Those commands should publish the complete project artifact. If they need the
358
+ gallery, they should call `norna:*` scripts internally.
359
+
360
+ Engine publishing uses `release:*`, not `norna:*`:
361
+
362
+ ```sh
363
+ npm run release:publish
364
+ ```
365
+
366
+ ### Monitor Publishing
367
+
368
+ Gallery Pages monitoring belongs under:
369
+
370
+ ```sh
371
+ npm run norna:deploy:watch
372
+ ```
373
+
374
+ Mixed projects may provide a project-owned monitoring command when monitoring
375
+ is not specific to the gallery:
376
+
377
+ ```sh
378
+ npm run deploy:watch
379
+ ```
380
+
381
+ That command should monitor the whole project's publishing workflow. If it needs
382
+ norna-specific deploy settings, it should call `norna:deploy:watch`.
383
+
384
+ ## Naming Rules
385
+
386
+ - Use `norna:*` for every npm script in a consuming repository whose direct
387
+ object is the gallery, its source files, its generated images, its dev server,
388
+ or its engine dependency.
389
+ - `norna` does not define unprefixed project commands such as `build`,
390
+ `test`, and `deploy` in consuming repositories.
391
+ - If project commands need gallery behavior, they should call `norna:*`
392
+ scripts.
393
+ - In pure gallery projects, unprefixed project commands may alias `norna:*`
394
+ commands.
395
+ - In mixed projects, unprefixed project commands must not be aliases for only
396
+ the gallery unless the command name makes that scope explicit.
397
+ - Use `release:*` only for publishing the reusable engine package.
398
+ - Prefer direct `norna ...` commands in engine docs and diagnostics;
399
+ prefer npm scripts in site-repository docs.
400
+ - Do not create separate namespaces for every internal concept. If a command is
401
+ about maintaining the gallery dependency in a consuming repository, keep it
402
+ under `norna:*`.
@@ -0,0 +1,152 @@
1
+ # Commands
2
+
3
+ The `norna` binary is the stable command surface. The starter's npm
4
+ scripts are thin aliases around these commands.
5
+
6
+ ## CLI Commands
7
+
8
+ ```sh
9
+ norna dev:local
10
+ norna dev:lan
11
+ norna dev:restart
12
+ norna dev:status
13
+ norna dev:logs
14
+ norna dev:stop
15
+ norna config:check
16
+ norna content:check
17
+ norna content:sync
18
+ norna typography:presets
19
+ norna typography:show
20
+ norna site:public
21
+ norna images
22
+ norna engine:update [version|latest]
23
+ norna engine:version [--latest]
24
+ norna init <target-dir> [--type pure|embedded] [--site-dir <path>]
25
+ norna build
26
+ norna build:local
27
+ norna deploy
28
+ norna deploy:commit
29
+ norna deploy:watch
30
+ norna preview
31
+ norna astro
32
+ norna doctor
33
+ ```
34
+
35
+ Global options:
36
+
37
+ ```sh
38
+ norna --site-dir <path> <command>
39
+ norna --help
40
+ ```
41
+
42
+ `norna dev` is accepted as an alias for `dev:local`. `help`, `-h`, and
43
+ `--help` print usage.
44
+
45
+ ## Starter npm Scripts
46
+
47
+ The starter uses `norna:*` for norna-specific work. This avoids collisions
48
+ when a `norna` presentation is embedded inside a larger GitHub project
49
+ whose own `build`, `test`, or deploy scripts mean something different.
50
+
51
+ The starter defines:
52
+
53
+ ```sh
54
+ npm run dev
55
+ npm run norna:dev
56
+ npm run norna:dev:lan
57
+ npm run norna:dev:restart
58
+ npm run norna:dev:status
59
+ npm run norna:dev:logs
60
+ npm run norna:dev:stop
61
+ npm run norna:check
62
+ npm run norna:config:check
63
+ npm run norna:content:check
64
+ npm run norna:sync
65
+ npm run norna:typography:presets
66
+ npm run norna:typography:show
67
+ npm run norna:public
68
+ npm run norna:images
69
+ npm run norna:build
70
+ npm run norna:build:local
71
+ npm run norna:deploy
72
+ npm run norna:deploy:commit
73
+ npm run norna:deploy:watch
74
+ npm run norna:doctor
75
+ npm run norna:preview
76
+ npm run norna:engine:update
77
+ npm run norna:engine:version
78
+ npm run build
79
+ ```
80
+
81
+ `npm run dev` calls `npm run norna:dev`. In the pure starter,
82
+ `npm run build` aliases `npm run norna:build`. In mixed repositories, such as
83
+ a GitHub project that embeds a gallery presentation next to an app, `build`
84
+ should normally mean the repository's complete publishable artifact, while
85
+ `norna:build` builds only the `norna` part.
86
+
87
+ ## Command Summary
88
+
89
+ - `doctor`: prints resolved engine root, site project root, site directory,
90
+ content/config/image/public paths, generated manifest, Astro output paths, and
91
+ cache path.
92
+ - `config:check`: validates `site/config.mjs` against the runtime config
93
+ reader.
94
+ - `content:check`: validates section structure and gallery references, then
95
+ runs `astro sync`.
96
+ - `content:sync` / `norna:sync`: rewrites Markdown section order and moves misplaced referenced
97
+ image files after confirmation.
98
+ - `typography:presets`: prints the exact built-in values for every typography
99
+ preset.
100
+ - `typography:show`: prints the selected site's resolved typography after
101
+ applying theme, page, and section presentation.
102
+ - `site:public`: copies `site/public/` into `site/.norna/public/` and
103
+ removes stale copied static files.
104
+ - `images`: generates WebP variants and writes
105
+ `site/.norna/generated-images.json`.
106
+ - `engine:update [version|latest]`: updates the site repository's
107
+ `@janga/norna` dependency with `npm install --save-exact`, normalizes
108
+ `package-lock.json` for the pinned GitHub Actions Linux/npm environment, and
109
+ verifies it with `npm ci --dry-run` before running config/content/build checks.
110
+ Use `--skip-checks` to skip only the site checks; lockfile normalization and
111
+ CI verification still run. Unless npm already has a cache configured, it uses
112
+ `node_modules/.cache/norna-npm` in the site project.
113
+ - `engine:version [--latest]`: prints the declared site dependency, installed
114
+ engine version, engine root, Astro dependency, and installed Astro version.
115
+ With `--latest`, it also asks npm for the latest published engine version.
116
+ - `init <target-dir> [--type pure|embedded] [--site-dir <path>]`: creates a
117
+ pure gallery project from the packaged starter, or adds a gallery source
118
+ directory plus `norna:*` scripts to an existing project in embedded mode.
119
+ Pure setup pins `@janga/norna` to the version that created it.
120
+ - `build`: runs config check, content check, public sync, image generation, and
121
+ Astro build.
122
+ - `build:local`: runs `build` and restarts `dev:local`.
123
+ - `dev:local`: starts Astro dev in background mode on `localhost:4321`.
124
+ - `dev:lan`: starts the same server on all local network interfaces and prints
125
+ the IPv4 URL to open from another device on the same network. Stop it after
126
+ testing because it is accessible to that local network.
127
+ - `dev:restart`, `dev:status`, `dev:logs`, `dev:stop`: manage the local dev
128
+ server tracked under `.astro/`.
129
+ - `preview`: runs Astro preview with the `norna` Astro config.
130
+ - `astro`: runs Astro with the `norna` Astro config.
131
+ - `deploy`: builds and publishes an already committed deploy branch.
132
+ - `deploy:commit`: older convenience flow that builds, stages allowed site
133
+ changes, commits, pushes, and checks Pages.
134
+ - `deploy:watch`: follows a GitHub Pages workflow run.
135
+
136
+ ## Deploy Watch Options
137
+
138
+ `deploy:watch` accepts:
139
+
140
+ ```sh
141
+ --repo <owner/name>
142
+ --workflow <name>
143
+ --branch <name>
144
+ --sha <sha>
145
+ --site-url <url>
146
+ --interval <duration>
147
+ --timeout <duration>
148
+ --limit <count>
149
+ ```
150
+
151
+ Durations may use `ms`, `s`, or `m`, for example `500ms`, `10s`, or `15m`.
152
+ Without `--sha`, the current `HEAD` is monitored.