@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.
- package/LICENSE +674 -0
- package/README.md +109 -0
- package/astro.config.mjs +17 -0
- package/bin/norna.mjs +170 -0
- package/docs/README.md +48 -0
- package/docs/command-organization.md +402 -0
- package/docs/commands.md +152 -0
- package/docs/configuration.md +376 -0
- package/docs/content.md +384 -0
- package/docs/engine-development.md +164 -0
- package/docs/getting-started.md +96 -0
- package/docs/images-and-metadata.md +88 -0
- package/docs/local-development.md +61 -0
- package/docs/publishing.md +81 -0
- package/docs/site-examples-structure-note.md +105 -0
- package/docs/site-structure.md +81 -0
- package/fixtures/basic/site/.norna/generated-images.json +1 -0
- package/fixtures/basic/site/config.mjs +59 -0
- package/fixtures/basic/site/content.md +17 -0
- package/fixtures/basic/site/images/work/.gitkeep +1 -0
- package/fixtures/basic/site/public/robots.txt +2 -0
- package/fixtures/basic/site/theme.md +7 -0
- package/package.json +90 -0
- package/scripts/build-site.mjs +16 -0
- package/scripts/check-config.mjs +37 -0
- package/scripts/deploy-site.mjs +389 -0
- package/scripts/dev-local.mjs +313 -0
- package/scripts/doctor.mjs +38 -0
- package/scripts/engine-version.mjs +137 -0
- package/scripts/generate-images.mjs +369 -0
- package/scripts/init-site.mjs +249 -0
- package/scripts/lib/astro-command.mjs +34 -0
- package/scripts/lib/ci-lockfile.mjs +34 -0
- package/scripts/lib/image-dimensions.mjs +78 -0
- package/scripts/lib/presentation.mjs +72 -0
- package/scripts/lib/project-config.mjs +322 -0
- package/scripts/lib/run-command.mjs +21 -0
- package/scripts/lib/site-content.mjs +392 -0
- package/scripts/lib/site-paths.mjs +127 -0
- package/scripts/lib/typography.mjs +166 -0
- package/scripts/release.mjs +77 -0
- package/scripts/show-typography.mjs +210 -0
- package/scripts/sync-content-sections.mjs +610 -0
- package/scripts/sync-site-public.mjs +42 -0
- package/scripts/test-ci-lockfile.mjs +65 -0
- package/scripts/test-content-check.mjs +364 -0
- package/scripts/test-engine-commands.mjs +128 -0
- package/scripts/test-navigation-preview.mjs +108 -0
- package/scripts/test-navigation.mjs +116 -0
- package/scripts/test-package-check.mjs +394 -0
- package/scripts/test-site-public.mjs +85 -0
- package/scripts/test-temporary-visibility.mjs +99 -0
- package/scripts/update-engine.mjs +127 -0
- package/scripts/watch-pages-deploy.mjs +430 -0
- package/src/components/GalleryGrid.astro +221 -0
- package/src/components/SiteNavigation.astro +410 -0
- package/src/components/SitePage.astro +69 -0
- package/src/components/SiteSection.astro +174 -0
- package/src/content.config.ts +171 -0
- package/src/layouts/BaseLayout.astro +90 -0
- package/src/lib/generatedImages.ts +63 -0
- package/src/lib/sectionContent.ts +125 -0
- package/src/lib/sitePages.ts +80 -0
- package/src/lib/sitePublicAssets.ts +39 -0
- package/src/lib/visibility.ts +35 -0
- package/src/pages/[slug].astro +31 -0
- package/src/pages/index.astro +16 -0
- package/src/styles/global.css +872 -0
- package/starters/basic/.github/workflows/deploy.yml +65 -0
- package/starters/basic/README.md +55 -0
- package/starters/basic/package.json +35 -0
- package/starters/basic/site/config.mjs +60 -0
- package/starters/basic/site/content.md +21 -0
- package/starters/basic/site/images/work/.gitkeep +1 -0
- package/starters/basic/site/public/robots.txt +2 -0
- package/starters/basic/site/theme.md +53 -0
- package/tsconfig.json +5 -0
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
# Images And Metadata
|
|
2
|
+
|
|
3
|
+
This document describes the generic image pipeline. Site repositories own their
|
|
4
|
+
source images and any copyright or licensing policy for those images.
|
|
5
|
+
|
|
6
|
+
## Source Images
|
|
7
|
+
|
|
8
|
+
Source images live under `site/images/<section-id>/` and are referenced from
|
|
9
|
+
`site/content.md` by filename only.
|
|
10
|
+
|
|
11
|
+
Supported source extensions:
|
|
12
|
+
|
|
13
|
+
- `.jpg`
|
|
14
|
+
- `.jpeg`
|
|
15
|
+
- `.png`
|
|
16
|
+
|
|
17
|
+
Image filenames must be globally unique under `site/images/`. The content and
|
|
18
|
+
image scripts reject duplicate filenames because gallery rows identify images by
|
|
19
|
+
filename only.
|
|
20
|
+
|
|
21
|
+
## Generated Variants
|
|
22
|
+
|
|
23
|
+
`npm run norna:images` and `npm run norna:build` generate WebP files in:
|
|
24
|
+
|
|
25
|
+
```text
|
|
26
|
+
site/.norna/public/images/generated/
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
The normal display widths are:
|
|
30
|
+
|
|
31
|
+
```text
|
|
32
|
+
480, 768, 1080, 1440, 1920
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
Widths larger than the source image are skipped. If the source image is wider
|
|
36
|
+
than all normal display widths, the pipeline also creates one variant at the
|
|
37
|
+
source width.
|
|
38
|
+
|
|
39
|
+
Generated filenames include the first eight characters of the source SHA-256
|
|
40
|
+
hash:
|
|
41
|
+
|
|
42
|
+
```text
|
|
43
|
+
example-work-1a2b3c4d-1440.webp
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
When a source image changes, the generated URL changes too. This avoids stale
|
|
47
|
+
browser, CDN, and GitHub Actions cache entries at the old URL.
|
|
48
|
+
|
|
49
|
+
## Manifest
|
|
50
|
+
|
|
51
|
+
The generated image manifest is:
|
|
52
|
+
|
|
53
|
+
```text
|
|
54
|
+
site/.norna/generated-images.json
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
It is versioned site state. It stores source hashes, original dimensions,
|
|
58
|
+
output version, and generated variant paths. The image pipeline reuses generated
|
|
59
|
+
files only when the manifest entry matches the current source hash and output
|
|
60
|
+
version, and all expected variant files exist.
|
|
61
|
+
|
|
62
|
+
Generated files under `site/.norna/public/` are build-preparation output
|
|
63
|
+
and should not be versioned.
|
|
64
|
+
|
|
65
|
+
## Metadata Behavior
|
|
66
|
+
|
|
67
|
+
The current engine does not inspect, require, warn about, or write source image
|
|
68
|
+
copyright metadata.
|
|
69
|
+
|
|
70
|
+
Generated WebP files are created with ImageMagick using `-strip`, so embedded
|
|
71
|
+
metadata is not a publication mechanism for generated variants. Keep licensing,
|
|
72
|
+
credits, copyright notices, alt text, and captions in site-owned files such as
|
|
73
|
+
`site/content.md`, `COPYRIGHT.md`, or other site documentation.
|
|
74
|
+
|
|
75
|
+
If a site wants embedded metadata in original source files, that process is
|
|
76
|
+
outside the current `norna` command surface.
|
|
77
|
+
|
|
78
|
+
## GitHub Actions Cache
|
|
79
|
+
|
|
80
|
+
The starter workflow caches:
|
|
81
|
+
|
|
82
|
+
```text
|
|
83
|
+
site/.norna/public/images/generated
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
The cache key should include `site/.norna/generated-images.json` so
|
|
87
|
+
unchanged generated variants can be restored during deploy. With a cache miss or
|
|
88
|
+
a changed source hash, variants are rebuilt from source images.
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
# Local Development
|
|
2
|
+
|
|
3
|
+
Use the local preview commands when editing a site or the engine demo.
|
|
4
|
+
|
|
5
|
+
## Start Preview
|
|
6
|
+
|
|
7
|
+
```sh
|
|
8
|
+
npm run norna:dev
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
The wrapper:
|
|
12
|
+
|
|
13
|
+
1. syncs `site/public/` into `site/.norna/public/`,
|
|
14
|
+
2. starts Astro in background mode,
|
|
15
|
+
3. waits until the site responds,
|
|
16
|
+
4. opens `http://localhost:4321/` unless `WALDE_NO_OPEN=1` is set.
|
|
17
|
+
|
|
18
|
+
The host and port are currently fixed in the script:
|
|
19
|
+
|
|
20
|
+
```text
|
|
21
|
+
localhost:4321
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
If the port is already in use, the command fails and asks you to stop the
|
|
25
|
+
process using it.
|
|
26
|
+
|
|
27
|
+
## Test On A Phone
|
|
28
|
+
|
|
29
|
+
To make the local dev server available to devices on the same Wi-Fi network:
|
|
30
|
+
|
|
31
|
+
```sh
|
|
32
|
+
npm run norna:dev:lan
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
The command prints one or more local IPv4 URLs. Open one of them on the phone.
|
|
36
|
+
The phone and computer must use the same network, and macOS may ask to allow
|
|
37
|
+
incoming connections for Node. Stop the server after testing with
|
|
38
|
+
`npm run norna:dev:stop` because it is accessible from the local network.
|
|
39
|
+
|
|
40
|
+
## Manage Preview
|
|
41
|
+
|
|
42
|
+
```sh
|
|
43
|
+
npm run norna:dev:status
|
|
44
|
+
npm run norna:dev:logs
|
|
45
|
+
npm run norna:dev:logs -- --follow
|
|
46
|
+
npm run norna:dev:restart
|
|
47
|
+
npm run norna:dev:stop
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
The local server state and logs live under `.astro/`.
|
|
51
|
+
|
|
52
|
+
## Rebuild Stale Preview
|
|
53
|
+
|
|
54
|
+
Use this when generated content or image state looks stale:
|
|
55
|
+
|
|
56
|
+
```sh
|
|
57
|
+
npm run norna:build:local
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
It runs the full build and restarts the local dev server without opening a new
|
|
61
|
+
browser window.
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
# Publishing
|
|
2
|
+
|
|
3
|
+
Publishing is site-specific. The generic deploy commands read repository,
|
|
4
|
+
branch, workflow, watch, and public URL settings from the selected site's
|
|
5
|
+
`site/config.mjs`.
|
|
6
|
+
|
|
7
|
+
Do not run deploy commands from the engine repository unless you deliberately
|
|
8
|
+
want to test the demo configuration.
|
|
9
|
+
|
|
10
|
+
## GitHub Pages Workflow
|
|
11
|
+
|
|
12
|
+
Each site repository should own its `.github/workflows/deploy.yml`. The starter
|
|
13
|
+
workflow:
|
|
14
|
+
|
|
15
|
+
1. checks out the site repository,
|
|
16
|
+
2. sets up Node,
|
|
17
|
+
3. installs image tools,
|
|
18
|
+
4. restores the generated image cache,
|
|
19
|
+
5. runs `npm ci`,
|
|
20
|
+
6. runs `npm run build` in the starter, which aliases
|
|
21
|
+
`npm run norna:build`,
|
|
22
|
+
7. uploads `dist/`,
|
|
23
|
+
8. deploys to GitHub Pages.
|
|
24
|
+
|
|
25
|
+
Site-specific static files such as `site/public/CNAME`, `robots.txt`, and
|
|
26
|
+
`sitemap.xml` belong in the site repository.
|
|
27
|
+
|
|
28
|
+
## Deploy An Already Committed Branch
|
|
29
|
+
|
|
30
|
+
Use:
|
|
31
|
+
|
|
32
|
+
```sh
|
|
33
|
+
npm run norna:deploy
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
The deploy command:
|
|
37
|
+
|
|
38
|
+
- requires the current branch to equal `github.branch`,
|
|
39
|
+
- requires a clean worktree before build,
|
|
40
|
+
- fetches `origin`,
|
|
41
|
+
- refuses to proceed when the branch is behind or diverged,
|
|
42
|
+
- runs the full build,
|
|
43
|
+
- requires the build to leave the worktree clean,
|
|
44
|
+
- pushes only when the local branch is ahead of `origin/<branch>`,
|
|
45
|
+
- checks the configured GitHub Pages workflow.
|
|
46
|
+
|
|
47
|
+
It does not create commits or push uncommitted changes.
|
|
48
|
+
|
|
49
|
+
## Deploy With A Generated Commit
|
|
50
|
+
|
|
51
|
+
The older convenience flow remains available:
|
|
52
|
+
|
|
53
|
+
```sh
|
|
54
|
+
npm run norna:deploy:commit -- "Commit message"
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
It builds, stages only allowed site changes, commits, pushes, and checks Pages.
|
|
58
|
+
The allowlist is implemented in `scripts/deploy-site.mjs` and includes the
|
|
59
|
+
site content file, selected config/static files, expected gallery images,
|
|
60
|
+
generated image manifest, package files, `tsconfig.json`, `astro.config.mjs`,
|
|
61
|
+
and `src/` changes.
|
|
62
|
+
|
|
63
|
+
## Watch A Deploy
|
|
64
|
+
|
|
65
|
+
Use:
|
|
66
|
+
|
|
67
|
+
```sh
|
|
68
|
+
npm run norna:deploy:watch
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
By default it monitors the workflow run for the current `HEAD` on the configured
|
|
72
|
+
branch and repository. Useful one-run overrides include:
|
|
73
|
+
|
|
74
|
+
```sh
|
|
75
|
+
npm run norna:deploy:watch -- --timeout 20m --interval 5s
|
|
76
|
+
npm run norna:deploy:watch -- --sha <commit-sha>
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
The monitor prints the run id, run URL, Actions URL, branch, commit SHA, status,
|
|
80
|
+
and configured public site URL. On failures it fetches failed job details and a
|
|
81
|
+
log excerpt.
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
# Site Examples Structure Note
|
|
2
|
+
|
|
3
|
+
This note defines the intended repository vocabulary before reorganizing
|
|
4
|
+
starter files, demo sites, fixtures, and documentation sites. It is a design
|
|
5
|
+
note, not an implementation record.
|
|
6
|
+
|
|
7
|
+
## Goal
|
|
8
|
+
|
|
9
|
+
`norna` should make it easy to find runnable examples and understand which
|
|
10
|
+
files are product documentation, which files are examples, and which files are
|
|
11
|
+
test fixtures.
|
|
12
|
+
|
|
13
|
+
The current repository grew from one local demo, one starter, and a set of
|
|
14
|
+
tests. A future structure should keep those roles separate.
|
|
15
|
+
|
|
16
|
+
## Terms
|
|
17
|
+
|
|
18
|
+
### Starter
|
|
19
|
+
|
|
20
|
+
A starter is a template copied by `norna init`.
|
|
21
|
+
|
|
22
|
+
It should be small, conservative, and suitable as the first commit in a real
|
|
23
|
+
site repository. It should not be a showcase for every feature.
|
|
24
|
+
|
|
25
|
+
### Example Site
|
|
26
|
+
|
|
27
|
+
An example site is a runnable site that demonstrates one or more features.
|
|
28
|
+
|
|
29
|
+
Examples can be richer than the starter. They may show routes, navigation,
|
|
30
|
+
typography presets, galleries, image carousels, inline styles, and site-specific
|
|
31
|
+
configuration choices.
|
|
32
|
+
|
|
33
|
+
### Documentation Site
|
|
34
|
+
|
|
35
|
+
A documentation site is a runnable `norna` site that explains the product
|
|
36
|
+
visually.
|
|
37
|
+
|
|
38
|
+
It can use images, diagrams, screenshots, and route pages to explain concepts
|
|
39
|
+
such as file structure, presentation inheritance, route navigation, and image
|
|
40
|
+
handling.
|
|
41
|
+
|
|
42
|
+
### Reference Documentation
|
|
43
|
+
|
|
44
|
+
Reference documentation is GitHub-readable Markdown for exact interfaces and
|
|
45
|
+
workflows.
|
|
46
|
+
|
|
47
|
+
It belongs in `docs/` and should remain useful without building a site. It is
|
|
48
|
+
the right home for command reference, configuration reference, content schema,
|
|
49
|
+
publishing workflows, and engine development notes.
|
|
50
|
+
|
|
51
|
+
### Fixture
|
|
52
|
+
|
|
53
|
+
A fixture is test data.
|
|
54
|
+
|
|
55
|
+
It should be minimal, stable, and optimized for regression tests rather than
|
|
56
|
+
for human reading or visual appeal.
|
|
57
|
+
|
|
58
|
+
## Intended Direction
|
|
59
|
+
|
|
60
|
+
A future structure should collect runnable site examples in one place, for
|
|
61
|
+
example:
|
|
62
|
+
|
|
63
|
+
```text
|
|
64
|
+
sites/
|
|
65
|
+
starter-basic/
|
|
66
|
+
dog-gallery/
|
|
67
|
+
routes-demo/
|
|
68
|
+
typography-demo/
|
|
69
|
+
docs-site/
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
The exact names can change, but the roles should remain clear:
|
|
73
|
+
|
|
74
|
+
- `starter-basic/`: copied by `norna init`.
|
|
75
|
+
- `dog-gallery/`: local visual demo and manual inspection site.
|
|
76
|
+
- `routes-demo/`: focused route/navigation example if dog-gallery becomes too
|
|
77
|
+
broad.
|
|
78
|
+
- `typography-demo/`: focused typography preset and override example if needed.
|
|
79
|
+
- `docs-site/`: visual documentation built with `norna`.
|
|
80
|
+
|
|
81
|
+
`docs/` should remain for reference documentation. It should link to the
|
|
82
|
+
documentation site when visual explanation is more useful than reference text.
|
|
83
|
+
|
|
84
|
+
Fixtures may either stay under `fixtures/` or move under a clearly named test
|
|
85
|
+
area later. They should not be confused with examples.
|
|
86
|
+
|
|
87
|
+
## Constraints
|
|
88
|
+
|
|
89
|
+
- Do not remove the starter concept; it has a different purpose from examples.
|
|
90
|
+
- Do not make the documentation site the only documentation.
|
|
91
|
+
- Do not let examples become required input for production site repositories.
|
|
92
|
+
- Keep `norna init` deterministic and easy to test.
|
|
93
|
+
- Keep engine tests using stable fixtures, not visually evolving demo content.
|
|
94
|
+
|
|
95
|
+
## Open Decisions
|
|
96
|
+
|
|
97
|
+
- Exact top-level directory name: `sites/`, `examples/`, or another name.
|
|
98
|
+
- Whether `starter-basic/` belongs beside examples or in a separate template
|
|
99
|
+
area.
|
|
100
|
+
- Whether the current dog-gallery remains the primary manual test site or
|
|
101
|
+
becomes one example among several.
|
|
102
|
+
- Whether the documentation site should be published anywhere, or exist only as
|
|
103
|
+
a local/example build.
|
|
104
|
+
- How demo selection should work in npm scripts, for example
|
|
105
|
+
`npm run demo:dev -- dog-gallery`.
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
# Site Structure
|
|
2
|
+
|
|
3
|
+
A `norna` site repository owns the content and configuration for one
|
|
4
|
+
published site. The engine repository owns the reusable CLI and renderer.
|
|
5
|
+
|
|
6
|
+
## Default Layout
|
|
7
|
+
|
|
8
|
+
The selected site directory defaults to `site/`:
|
|
9
|
+
|
|
10
|
+
```text
|
|
11
|
+
site/
|
|
12
|
+
|-- config.mjs
|
|
13
|
+
|-- theme.md
|
|
14
|
+
|-- content.md
|
|
15
|
+
|-- images/
|
|
16
|
+
| `-- <section-id>/
|
|
17
|
+
|-- routes/
|
|
18
|
+
| `-- <route-folder>/
|
|
19
|
+
| |-- route-content.md
|
|
20
|
+
| `-- images/
|
|
21
|
+
| `-- <section-id>/
|
|
22
|
+
|-- public/
|
|
23
|
+
`-- .norna/
|
|
24
|
+
|-- generated-images.json
|
|
25
|
+
`-- public/
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
Use `NORNA_SITE_DIR` or `norna --site-dir <path>` to select another
|
|
29
|
+
site directory. Commands started from a subdirectory walk upward until they find
|
|
30
|
+
the selected site directory containing both `config.mjs` and `content.md`.
|
|
31
|
+
`theme.md` is optional; omit it to use the engine's built-in presentation
|
|
32
|
+
defaults.
|
|
33
|
+
|
|
34
|
+
## Versioned Source Files
|
|
35
|
+
|
|
36
|
+
Version these files in a site repository:
|
|
37
|
+
|
|
38
|
+
- `site/config.mjs`: technical site configuration.
|
|
39
|
+
- `site/theme.md`: optional site-wide visual theme, inline styles, and frame
|
|
40
|
+
defaults.
|
|
41
|
+
- `site/content.md`: homepage page file with editable content, section
|
|
42
|
+
definitions, gallery rows, alt text, and captions.
|
|
43
|
+
- `site/images/<section-id>/`: original source images.
|
|
44
|
+
- `site/routes/<route-folder>/route-content.md`: optional route page files.
|
|
45
|
+
- `site/routes/<route-folder>/images/<section-id>/`: original source images
|
|
46
|
+
for that route page.
|
|
47
|
+
- `site/public/`: site-specific static public files.
|
|
48
|
+
- `site/.norna/generated-images.json`: generated image manifest used to
|
|
49
|
+
decide whether WebP variants can be reused.
|
|
50
|
+
- `.github/workflows/deploy.yml`: site-owned GitHub Pages workflow.
|
|
51
|
+
- `package.json` and `package-lock.json`: scripts and pinned engine dependency.
|
|
52
|
+
|
|
53
|
+
## Generated Files
|
|
54
|
+
|
|
55
|
+
Do not edit these by hand:
|
|
56
|
+
|
|
57
|
+
- `site/.norna/public/`: build-preparation output copied from
|
|
58
|
+
`site/public/`, plus generated images.
|
|
59
|
+
- `dist/`: final static build output.
|
|
60
|
+
- `.astro/`: Astro cache, generated types, and dev-server state.
|
|
61
|
+
- `public/`: legacy generated public output from older engine versions.
|
|
62
|
+
|
|
63
|
+
`site:public` removes stale copied static files under
|
|
64
|
+
`site/.norna/public/` while preserving generated image output under
|
|
65
|
+
`site/.norna/public/images/`.
|
|
66
|
+
|
|
67
|
+
Favicons are convention-based. Put files such as `favicon.svg`, `favicon.ico`,
|
|
68
|
+
`favicon.png`, or `apple-touch-icon.png` in `site/public/`. The renderer emits
|
|
69
|
+
icon links only for files that exist.
|
|
70
|
+
|
|
71
|
+
## Engine Repository Layout
|
|
72
|
+
|
|
73
|
+
In this repository:
|
|
74
|
+
|
|
75
|
+
- `bin/norna.mjs` dispatches public CLI commands.
|
|
76
|
+
- `scripts/` contains validation, image, local preview, deploy, and test tools.
|
|
77
|
+
- `src/` contains the Astro renderer, components, styles, and content schema.
|
|
78
|
+
- `starters/basic/` is copied by `norna init <target-dir>` to create a
|
|
79
|
+
site repository.
|
|
80
|
+
- `fixtures/basic/site/` is used by engine regression tests.
|
|
81
|
+
- `site/` is the local dog-gallery demo used by default in this repository.
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{}
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
export default {
|
|
2
|
+
site: {
|
|
3
|
+
url: 'https://example.com/',
|
|
4
|
+
},
|
|
5
|
+
layout: {
|
|
6
|
+
pageWidth: '1180px',
|
|
7
|
+
gutter: {
|
|
8
|
+
desktop: 'clamp(1.25rem, 4vw, 3rem)',
|
|
9
|
+
mobile: '1rem',
|
|
10
|
+
},
|
|
11
|
+
},
|
|
12
|
+
gallery: {
|
|
13
|
+
maxAvailableWidthPercent: {
|
|
14
|
+
desktop: 100,
|
|
15
|
+
mobile: 100,
|
|
16
|
+
},
|
|
17
|
+
maxAvailableHeightPercent: {
|
|
18
|
+
desktop: 74,
|
|
19
|
+
mobile: 68,
|
|
20
|
+
},
|
|
21
|
+
},
|
|
22
|
+
typography: {
|
|
23
|
+
fontFamily: "Arial, 'Helvetica Neue', Helvetica, sans-serif",
|
|
24
|
+
},
|
|
25
|
+
navigation: {
|
|
26
|
+
smoothScroll: {
|
|
27
|
+
enabled: true,
|
|
28
|
+
minimumDurationMs: 600,
|
|
29
|
+
maximumDurationMs: 1_200,
|
|
30
|
+
durationPerPixelMs: 0.2,
|
|
31
|
+
},
|
|
32
|
+
},
|
|
33
|
+
locale: {
|
|
34
|
+
lang: 'en',
|
|
35
|
+
labels: {
|
|
36
|
+
skipToContent: 'Skip to content',
|
|
37
|
+
sectionNavigation: 'Sections',
|
|
38
|
+
gallery: 'Gallery',
|
|
39
|
+
},
|
|
40
|
+
},
|
|
41
|
+
footer: {
|
|
42
|
+
copyrightMessage: '(c) Fixture Artist.',
|
|
43
|
+
buildInfo: {
|
|
44
|
+
enabled: true,
|
|
45
|
+
text: 'Built',
|
|
46
|
+
dateTimeFormat: {
|
|
47
|
+
locale: 'en-GB',
|
|
48
|
+
timeZone: 'UTC',
|
|
49
|
+
dateStyle: 'short',
|
|
50
|
+
timeStyle: 'short',
|
|
51
|
+
},
|
|
52
|
+
},
|
|
53
|
+
},
|
|
54
|
+
github: {
|
|
55
|
+
repo: 'owner/fixture-gallery',
|
|
56
|
+
branch: 'main',
|
|
57
|
+
pagesWorkflow: 'Deploy to GitHub Pages',
|
|
58
|
+
},
|
|
59
|
+
};
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: Fixture Gallery
|
|
3
|
+
description: Minimal cli-gallery fixture site.
|
|
4
|
+
sections:
|
|
5
|
+
- id: intro
|
|
6
|
+
gallery: []
|
|
7
|
+
- id: work
|
|
8
|
+
gallery: []
|
|
9
|
+
|
|
10
|
+
---
|
|
11
|
+
## Intro {#intro}
|
|
12
|
+
|
|
13
|
+
This fixture validates the cli-gallery engine against a stable empty gallery.
|
|
14
|
+
|
|
15
|
+
## Work {#work}
|
|
16
|
+
|
|
17
|
+
Fixture section with no gallery images.
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
|
package/package.json
ADDED
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@janga/norna",
|
|
3
|
+
"description": "A command-line publishing workflow for simple static sites.",
|
|
4
|
+
"type": "module",
|
|
5
|
+
"version": "0.7.0",
|
|
6
|
+
"license": "GPL-3.0-only",
|
|
7
|
+
"repository": {
|
|
8
|
+
"type": "git",
|
|
9
|
+
"url": "git+https://github.com/janga/norna.git"
|
|
10
|
+
},
|
|
11
|
+
"bugs": {
|
|
12
|
+
"url": "https://github.com/janga/norna/issues"
|
|
13
|
+
},
|
|
14
|
+
"homepage": "https://github.com/janga/norna#readme",
|
|
15
|
+
"keywords": [
|
|
16
|
+
"astro",
|
|
17
|
+
"gallery",
|
|
18
|
+
"static-site",
|
|
19
|
+
"cli"
|
|
20
|
+
],
|
|
21
|
+
"bin": {
|
|
22
|
+
"norna": "bin/norna.mjs"
|
|
23
|
+
},
|
|
24
|
+
"files": [
|
|
25
|
+
"astro.config.mjs",
|
|
26
|
+
"bin/",
|
|
27
|
+
"docs/",
|
|
28
|
+
"fixtures/",
|
|
29
|
+
"scripts/",
|
|
30
|
+
"src/",
|
|
31
|
+
"starters/",
|
|
32
|
+
"!**/.norna/public/",
|
|
33
|
+
"tsconfig.json",
|
|
34
|
+
"README.md"
|
|
35
|
+
],
|
|
36
|
+
"publishConfig": {
|
|
37
|
+
"access": "public"
|
|
38
|
+
},
|
|
39
|
+
"engines": {
|
|
40
|
+
"node": ">=22.12.0"
|
|
41
|
+
},
|
|
42
|
+
"scripts": {
|
|
43
|
+
"dev": "npm run dev:local",
|
|
44
|
+
"dev:local": "npm run demo:dev",
|
|
45
|
+
"dev:lan": "node bin/norna.mjs dev:lan",
|
|
46
|
+
"dev:restart": "node bin/norna.mjs dev:restart",
|
|
47
|
+
"dev:status": "node bin/norna.mjs dev:status",
|
|
48
|
+
"dev:logs": "node bin/norna.mjs dev:logs",
|
|
49
|
+
"dev:stop": "node bin/norna.mjs dev:stop",
|
|
50
|
+
"config:check": "node bin/norna.mjs config:check",
|
|
51
|
+
"content:check": "node bin/norna.mjs content:check",
|
|
52
|
+
"content:sync": "node bin/norna.mjs content:sync",
|
|
53
|
+
"typography:presets": "node bin/norna.mjs typography:presets",
|
|
54
|
+
"typography:show": "node bin/norna.mjs typography:show",
|
|
55
|
+
"site:public": "node bin/norna.mjs site:public",
|
|
56
|
+
"images": "node bin/norna.mjs images",
|
|
57
|
+
"build": "npm run demo:build",
|
|
58
|
+
"build:local": "node bin/norna.mjs build:local",
|
|
59
|
+
"deploy": "node bin/norna.mjs deploy",
|
|
60
|
+
"deploy:commit": "node bin/norna.mjs deploy:commit",
|
|
61
|
+
"deploy:watch": "node bin/norna.mjs deploy:watch",
|
|
62
|
+
"doctor": "node bin/norna.mjs doctor",
|
|
63
|
+
"demo:dev": "node bin/norna.mjs dev:local",
|
|
64
|
+
"demo:build": "node bin/norna.mjs build",
|
|
65
|
+
"test": "npm run test:content-check && npm run test:site-public && npm run test:engine-commands && npm run test:ci-lockfile && npm run test:temporary-visibility && npm run test:fixture:build && npm run demo:build && npm run package:check",
|
|
66
|
+
"test:fixture:build": "node bin/norna.mjs --site-dir fixtures/basic/site build",
|
|
67
|
+
"test:content-check": "node scripts/test-content-check.mjs",
|
|
68
|
+
"test:site-public": "node scripts/test-site-public.mjs",
|
|
69
|
+
"test:engine-commands": "node scripts/test-engine-commands.mjs",
|
|
70
|
+
"test:ci-lockfile": "node scripts/test-ci-lockfile.mjs",
|
|
71
|
+
"test:temporary-visibility": "node scripts/test-temporary-visibility.mjs",
|
|
72
|
+
"test:navigation": "node scripts/test-navigation.mjs",
|
|
73
|
+
"test:navigation:stress": "node scripts/test-navigation.mjs tests/navigation-stress.spec.ts",
|
|
74
|
+
"test:navigation:preview": "node scripts/test-navigation-preview.mjs",
|
|
75
|
+
"package:check": "node scripts/test-package-check.mjs",
|
|
76
|
+
"release:publish": "npm publish --access public --registry=https://registry.npmjs.org/ --cache /private/tmp/norna-npm-cache",
|
|
77
|
+
"release:patch": "node scripts/release.mjs patch",
|
|
78
|
+
"release:minor": "node scripts/release.mjs minor",
|
|
79
|
+
"release:major": "node scripts/release.mjs major",
|
|
80
|
+
"preview": "node bin/norna.mjs preview",
|
|
81
|
+
"astro": "node bin/norna.mjs astro"
|
|
82
|
+
},
|
|
83
|
+
"dependencies": {
|
|
84
|
+
"astro": "^7.1.3",
|
|
85
|
+
"embla-carousel": "^8.6.0"
|
|
86
|
+
},
|
|
87
|
+
"devDependencies": {
|
|
88
|
+
"@playwright/test": "^1.61.1"
|
|
89
|
+
}
|
|
90
|
+
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import path from 'node:path';
|
|
2
|
+
import { engineRoot, siteProjectRoot } from './lib/site-paths.mjs';
|
|
3
|
+
import { runAstroInherit } from './lib/astro-command.mjs';
|
|
4
|
+
import { runInherit } from './lib/run-command.mjs';
|
|
5
|
+
|
|
6
|
+
const runScript = (relativePath, args = []) => runInherit(
|
|
7
|
+
process.execPath,
|
|
8
|
+
[path.join(engineRoot, relativePath), ...args],
|
|
9
|
+
{ cwd: siteProjectRoot },
|
|
10
|
+
);
|
|
11
|
+
|
|
12
|
+
await runScript('scripts/check-config.mjs');
|
|
13
|
+
await runScript('scripts/sync-content-sections.mjs', ['--check']);
|
|
14
|
+
await runScript('scripts/sync-site-public.mjs');
|
|
15
|
+
await runScript('scripts/generate-images.mjs');
|
|
16
|
+
await runAstroInherit(['build']);
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import { siteConfigLabel } from './lib/site-paths.mjs';
|
|
2
|
+
|
|
3
|
+
const formatErrorMessage = (error) => {
|
|
4
|
+
if (error instanceof SyntaxError) {
|
|
5
|
+
return [
|
|
6
|
+
`${siteConfigLabel} contains invalid JavaScript syntax.`,
|
|
7
|
+
error.message,
|
|
8
|
+
].join('\n');
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
if (error instanceof Error) {
|
|
12
|
+
return error.message;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
return String(error);
|
|
16
|
+
};
|
|
17
|
+
|
|
18
|
+
try {
|
|
19
|
+
const { projectConfig } = await import('./lib/project-config.mjs');
|
|
20
|
+
|
|
21
|
+
console.log('Config check passed.');
|
|
22
|
+
console.log(`Site URL: ${projectConfig.site.url}`);
|
|
23
|
+
console.log(`Page width: ${projectConfig.layout.pageWidth}`);
|
|
24
|
+
console.log(`Gutter: desktop ${projectConfig.layout.gutter.desktop}, mobile ${projectConfig.layout.gutter.mobile}`);
|
|
25
|
+
console.log(`Gallery width: ${projectConfig.gallery.width}`);
|
|
26
|
+
console.log(`Gallery max available width: desktop ${projectConfig.gallery.maxAvailableWidthPercent.desktop}%, mobile ${projectConfig.gallery.maxAvailableWidthPercent.mobile}%`);
|
|
27
|
+
console.log(`Gallery max available height: desktop ${projectConfig.gallery.maxAvailableHeightPercent.desktop}%, mobile ${projectConfig.gallery.maxAvailableHeightPercent.mobile}%`);
|
|
28
|
+
console.log(`Font family: ${projectConfig.typography.fontFamily}`);
|
|
29
|
+
console.log(`Language: ${projectConfig.locale.lang}`);
|
|
30
|
+
console.log(`GitHub repo: ${projectConfig.github.repo}`);
|
|
31
|
+
console.log(`Deploy branch: ${projectConfig.github.branch}`);
|
|
32
|
+
console.log(`Pages workflow: ${projectConfig.github.pagesWorkflow}`);
|
|
33
|
+
} catch (error) {
|
|
34
|
+
console.error('Config check failed.');
|
|
35
|
+
console.error(formatErrorMessage(error));
|
|
36
|
+
process.exit(1);
|
|
37
|
+
}
|