@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,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,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,2 @@
1
+ User-agent: *
2
+ Allow: /
@@ -0,0 +1,7 @@
1
+ ---
2
+ presentation:
3
+ typography:
4
+ preset: quiet-gallery
5
+ frame:
6
+ colors: presentation
7
+ ---
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
+ }