pattern-dump 0.1.0-alpha.4 → 0.2.0-alpha.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/CHANGELOG.md +84 -1
- package/LICENSE +16 -3
- package/README.md +2 -2
- package/THIRD-PARTY-NOTICES.md +130 -0
- package/dist/chunks/{chunk-NXGPZL5L.js → chunk-ESMZAOP2.js} +125 -2
- package/dist/dev-ui/main.js +215 -77
- package/dist/index.js +1 -1
- package/dist/pd.js +5624 -881
- package/dist/types/config/index.d.ts +86 -1
- package/dist/types/config/validate.d.ts +12 -0
- package/dist/types/contracts/dev-protocol.d.ts +106 -4
- package/dist/types/contracts/iframe-fit.d.ts +33 -0
- package/dist/types/contracts/index.d.ts +36 -0
- package/package.json +9 -3
- package/templates/base/README.md +1 -0
- package/templates/base/_gitignore +1 -0
- package/templates/base/pattern-dump.config.ts +1 -0
- package/templates/base/src/styles/base/document.scss +5 -1
- package/templates/storefront/.github/workflows/pages.yml +53 -0
- package/templates/storefront/assets/icon.svg +2 -0
- package/templates/storefront/pages/about.md +15 -0
- package/templates/storefront/pages/index.md +24 -0
- package/templates/storefront/src/patterns/components/note/note.hbs +4 -0
- package/templates/storefront/src/patterns/components/note/note.json +4 -0
- package/templates/storefront/src/patterns/components/note/note.md +11 -0
- package/templates/storefront/src/patterns/components/note/note.schema.json +13 -0
- package/templates/storefront/src/patterns/components/note/note~warning.json +4 -0
- package/templates/storefront/src/patterns/layouts/page/page.hbs +8 -0
- package/templates/storefront/src/patterns/layouts/page/page.json +8 -0
- package/templates/storefront/src/patterns/layouts/page/page.md +6 -0
- package/templates/storefront/src/patterns/layouts/page/page.schema.json +19 -0
- package/templates/storefront/src/patterns/partials/base/base.hbs +17 -0
- package/templates/storefront/src/patterns/partials/base/base.json +4 -0
- package/templates/storefront/src/patterns/partials/base/base.md +6 -0
- package/templates/storefront/src/patterns/partials/base/base.schema.json +18 -0
- package/templates/storefront/src/patterns/partials/head/head.hbs +1 -0
- package/templates/storefront/src/patterns/partials/head/head.md +6 -0
- package/templates/storefront/src/styles/components/note.scss +8 -0
- package/templates/storefront/src/styles/layouts/page.scss +6 -0
- package/templates/storefront/src/styles/partials/base.scss +13 -0
- package/templates/storefront-fills/config.txt +14 -0
- package/templates/storefront-fills/gitignore.txt +2 -0
- package/templates/storefront-fills/readme.md +60 -0
package/CHANGELOG.md
CHANGED
|
@@ -1,8 +1,91 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 0.2.0-alpha.0
|
|
4
|
+
|
|
5
|
+
The storefront: a website written as markdown pages, dressed by a skin made of ordinary components, served by
|
|
6
|
+
`pd dev` on a host of its own and built by `pd build` next to the workbench. With it come responsive images, link
|
|
7
|
+
and image checks, and live examples of your components on the site's pages.
|
|
8
|
+
|
|
9
|
+
Pattern Dump now needs Node.js 22.22 or later (it was 20.10).
|
|
10
|
+
|
|
11
|
+
### Workbench
|
|
12
|
+
|
|
13
|
+
- Pattern packages linked into a project (a `file:` dependency or a workspace) are watched like the project's own
|
|
14
|
+
files, and each is read from its real folder. Global data, assets and helper modules reload while `pd dev` runs.
|
|
15
|
+
- A pattern package's TypeScript helpers are refused with a message naming them, and diagnostics name files by
|
|
16
|
+
project or package path, never by an absolute path.
|
|
17
|
+
- Live reload is dependable: changes are handled one at a time, in the order they happen; a page or preview that
|
|
18
|
+
missed a change fetches it again and never shows an older one; a save the file watcher drops is still handled; a
|
|
19
|
+
folder added while `pd dev` runs (as `git checkout` or `git pull` does) is seen with every file in it.
|
|
20
|
+
- A component added while `pd dev` runs gets its own stylesheet even when the stylesheet is saved before the
|
|
21
|
+
template.
|
|
22
|
+
- A variant reached by its own id (`/preview/atoms/toggle-demo~alt`) is the same document as `?variant=alt`, with
|
|
23
|
+
its base's behaviour scripts, layout and CSS.
|
|
24
|
+
- An overview tile picks up a stylesheet that was still empty when it rendered.
|
|
25
|
+
- Behaviour scripts are stamped with their content hash, so a browser fetches a script again exactly when it
|
|
26
|
+
changed.
|
|
27
|
+
- Every base-layer file whose rules no component owns and no `documentBase` entry lists is named in
|
|
28
|
+
`BASE-LAYER.generated.md`, with its rule count.
|
|
29
|
+
|
|
30
|
+
### Storefront
|
|
31
|
+
|
|
32
|
+
- Pages: every markdown file in `storefront.pagesDir` is a page, rendered with a layout from your patterns. Its
|
|
33
|
+
frontmatter is checked against the layout's schema, `storefront.site` against `partials/base`'s, and every
|
|
34
|
+
problem names its file and line. `pd dev` serves the site at `http://live.localhost:4000/`, `pd build` writes it
|
|
35
|
+
to `storefront.outDir`.
|
|
36
|
+
- Live examples: a `pattern` fence shows a component's own preview in a frame, with links to its variants. A
|
|
37
|
+
component can declare the height its example starts at (`x-pd-example-height`), and `pd dev` warns when that
|
|
38
|
+
height is too tall.
|
|
39
|
+
- Placing components with values: `<pd-…>` tags in a page's markdown, checked against the component's schema at
|
|
40
|
+
every level (`x-pd-component`, `x-pd-content`, `text/markdown` properties), with the file, line and column of any
|
|
41
|
+
problem.
|
|
42
|
+
- What a page knows about itself, for layouts that ask for it: its headings (with GitHub's anchors), section,
|
|
43
|
+
breadcrumbs, previous and next pages, dates from git, and declared navigations.
|
|
44
|
+
- Search engines and link previews: canonical URLs, Open Graph, the site's language, JSON-LD, `sitemap.xml`,
|
|
45
|
+
`robots.txt`, a 404 page, `redirectFrom` for old routes, `index: false`, and a link-preview image per page or site.
|
|
46
|
+
- A skin can add to every page's `<head>` through a `partials/head` component, and can be a pattern package.
|
|
47
|
+
- `pd init --storefront` starts a project with a website: pages, a plain skin, the workbench under `/workbench/`
|
|
48
|
+
on the same host, and a GitHub Pages workflow.
|
|
49
|
+
- Every file a page references (stylesheets, scripts, fonts, images) carries the content hash of the file as
|
|
50
|
+
served, so a visitor's browser fetches it again exactly when it changed.
|
|
51
|
+
|
|
52
|
+
### Images
|
|
53
|
+
|
|
54
|
+
- Every raster image is served as WebP variants of the widths it is shown at, encoded with sharp on first use and
|
|
55
|
+
cached in `node_modules/.cache/pattern-dump/images/`. `images` (quality, effort) sets the encoding, and
|
|
56
|
+
`storefront.images` overrides it for the site.
|
|
57
|
+
- Image slots: a component declares where an image goes and how wide it is shown (`x-pd-image`), and its template
|
|
58
|
+
writes it with `{{pd-image field alt=…}}`. Alt text is required; `alt=""` marks a decorative image.
|
|
59
|
+
- Images in a page's markdown get their variants in the slot the page's layout declares (`x-pd-prose-images`),
|
|
60
|
+
with `sizes="auto"`, and the first ones can load at once (`eager`).
|
|
61
|
+
- Every `<img>` carries its width and height, so the page doesn't shift as images load. Photos are turned upright
|
|
62
|
+
by their EXIF orientation.
|
|
63
|
+
|
|
64
|
+
### Checks
|
|
65
|
+
|
|
66
|
+
- `pd build` checks every link on every page of the site before it writes anything: pages, files, `#` anchors (a
|
|
67
|
+
heading's too), the site's own address and links into the workbench. A broken link stops the build; links to other
|
|
68
|
+
sites are listed in the build's notes. `pd dev` warns about a page's links to pages that don't exist.
|
|
69
|
+
- `pd build` refuses a page with an `<img>` that has no width and height, or a raster image served without its WebP
|
|
70
|
+
variants, and names the fix; `pd dev` shows the same as warnings.
|
|
71
|
+
- A schema field named like a registered helper is an error, and so is an unknown `x-pd-` key in a schema.
|
|
72
|
+
- The shape check tells a list from an object (an array property was reported as a mismatch).
|
|
73
|
+
|
|
74
|
+
### Fixes
|
|
75
|
+
|
|
76
|
+
- `pd dev` answers only requests addressed to its own host names, accepts live-reload connections only from its own
|
|
77
|
+
pages, binds its live-reload socket to 127.0.0.1 like its HTTP server, and serves files only from inside each
|
|
78
|
+
route's folder.
|
|
79
|
+
- The starter's body defaults no longer override a pattern package's document styles (hTWOo's dark themes showed
|
|
80
|
+
dark text on a white page).
|
|
81
|
+
- Two config loads in the same millisecond no longer share a temporary file.
|
|
82
|
+
- The audit reuses a cached result only when it was made by the same version of the check.
|
|
83
|
+
- The live-reload socket reports the port it is actually bound to.
|
|
84
|
+
- A code example on a page that quotes `<img src="/assets/…">` is shown as written, not with a cache stamp added.
|
|
85
|
+
|
|
3
86
|
## 0.1.0-alpha.4
|
|
4
87
|
|
|
5
|
-
Fixes found while moving a third PatternLab styleguide
|
|
88
|
+
Fixes found while moving a third PatternLab styleguide to Pattern Dump with hTWOo consumed only as
|
|
6
89
|
pattern packages: its templates, data, scripts and CSS all come from `@n8d/htwoo-patterns` and
|
|
7
90
|
`@n8d/htwoo-core`, and the project compiles only its own SCSS.
|
|
8
91
|
|
package/LICENSE
CHANGED
|
@@ -1,8 +1,21 @@
|
|
|
1
1
|
MIT License
|
|
2
2
|
|
|
3
|
-
Copyright (c) 2026
|
|
3
|
+
Copyright (c) 2026 Stefan Bauer (N8D e.U.)
|
|
4
4
|
|
|
5
5
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
6
|
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
-
in the Software without restriction,
|
|
8
|
-
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
CHANGED
|
@@ -4,7 +4,7 @@ A workbench for HTML and CSS design systems, and a successor to PatternLab. Writ
|
|
|
4
4
|
Handlebars templates with SCSS, data and Markdown docs; Pattern Dump shows them live, checks them, maps
|
|
5
5
|
how they relate, and publishes the result as a static site.
|
|
6
6
|
|
|
7
|
-
> **Alpha (0.
|
|
7
|
+
> **Alpha (0.2.0-alpha.0).** Published under the `alpha` tag. Options and file conventions can still change
|
|
8
8
|
> between releases.
|
|
9
9
|
|
|
10
10
|
## Requirements
|
|
@@ -102,4 +102,4 @@ export default defineConfig({
|
|
|
102
102
|
|
|
103
103
|
## License
|
|
104
104
|
|
|
105
|
-
[MIT](https://github.com/n8design/pattern-dump/blob/main/LICENSE) © 2026
|
|
105
|
+
[MIT](https://github.com/n8design/pattern-dump/blob/main/LICENSE) © 2026 Stefan Bauer (N8D e.U.)
|
|
@@ -0,0 +1,130 @@
|
|
|
1
|
+
# Third-party notices
|
|
2
|
+
|
|
3
|
+
Pattern Dump is MIT-licensed (see `LICENSE`). It includes code from the projects below, under their own
|
|
4
|
+
licences.
|
|
5
|
+
|
|
6
|
+
## github-slugger 2.0.0
|
|
7
|
+
|
|
8
|
+
- **Source:** https://github.com/Flet/github-slugger
|
|
9
|
+
- **Used in:** `packages/dev-server/src/storefront/slug.ts` (the slugger and its generated regex, ported
|
|
10
|
+
unchanged) and `packages/dev-server/test/fixtures/github-slugger-2.0.0.json` (its test fixtures, copied
|
|
11
|
+
unchanged).
|
|
12
|
+
- **Licence:** ISC
|
|
13
|
+
|
|
14
|
+
```
|
|
15
|
+
Copyright (c) 2015, Dan Flettre <fletd01@yahoo.com>
|
|
16
|
+
|
|
17
|
+
Permission to use, copy, modify, and/or distribute this software for any purpose with or without fee is
|
|
18
|
+
hereby granted, provided that the above copyright notice and this permission notice appear in all copies.
|
|
19
|
+
|
|
20
|
+
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE
|
|
21
|
+
INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
|
22
|
+
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF
|
|
23
|
+
USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
|
|
24
|
+
OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
## Fonts in the repository
|
|
28
|
+
|
|
29
|
+
- **Mr Bedfort**, Alejandro Paul (Sudtipos), version 1.000, with Reserved Font Name "Mr Bedfort".
|
|
30
|
+
- **Used in:** `test-bench/assets/fonts/pd-test.woff2`, unmodified; its licence text is
|
|
31
|
+
`test-bench/licenses/pd-test-OFL.txt`, and `test-bench/README.md` says what the file is. Not part of the npm package.
|
|
32
|
+
- **Licence:** SIL Open Font License 1.1.
|
|
33
|
+
|
|
34
|
+
The experimental skin's fonts (Montserrat, Source Serif 4, IBM Plex Mono) are listed, with their sources and
|
|
35
|
+
licences, in `skins/experimental/assets/skin-experimental/fonts/README.md`.
|
|
36
|
+
|
|
37
|
+
## Images in the repository
|
|
38
|
+
|
|
39
|
+
These files are in the git repository, in test fixtures and benches. They are not part of the npm package.
|
|
40
|
+
|
|
41
|
+
### Photographs from Unsplash
|
|
42
|
+
|
|
43
|
+
- **Space Shuttle Challenger**, NASA: https://unsplash.com/photos/dCgbRAQmTQA
|
|
44
|
+
- **Used in:** `packages/build/test/fixtures/images/` (`photo.jpg`, `portrait-exif6.jpg` and `alpha.png`, cut from
|
|
45
|
+
it; how, in the README beside them).
|
|
46
|
+
- **Licence:** [Unsplash License](https://unsplash.com/license). This is not the MIT licence and not an open-source
|
|
47
|
+
licence: it covers these images only, and the repository's MIT licence does not cover them.
|
|
48
|
+
|
|
49
|
+
- **Cable cars**, Cody Hiscox: https://unsplash.com/photos/kzb0Mo0YQDw
|
|
50
|
+
- **Used in:** `storefront-bench/src/assets/images/cable-cars.jpg` (cropped and scaled; how, in the README beside it).
|
|
51
|
+
- **Licence:** [Unsplash License](https://unsplash.com/license), as above: not the MIT licence.
|
|
52
|
+
|
|
53
|
+
## Phosphor Icons
|
|
54
|
+
|
|
55
|
+
- **Phosphor Icons**: https://github.com/phosphor-icons/core
|
|
56
|
+
- **Used in:** `apps/dev-ui/src/icons/index.ts`: twenty icons of the workbench (regular and fill weights, the
|
|
57
|
+
SVG paths unchanged), which are in the npm package as part of `dist/dev-ui/main.js`. The registry's two other
|
|
58
|
+
icons (the disclosure chevron and the open-in-new-window mark) are not Phosphor's.
|
|
59
|
+
- **Also used in:** `test-bench/assets/images/symbols.svg`: the `star` and `check` icons (regular weight, paths
|
|
60
|
+
unchanged), for the sprite and `<use>` specs. Not part of the npm package.
|
|
61
|
+
- **Licence:** MIT
|
|
62
|
+
|
|
63
|
+
```
|
|
64
|
+
MIT License
|
|
65
|
+
|
|
66
|
+
Copyright (c) 2023 Phosphor Icons
|
|
67
|
+
|
|
68
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated
|
|
69
|
+
documentation files (the "Software"), to deal in the Software without restriction, including without limitation
|
|
70
|
+
the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and
|
|
71
|
+
to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
|
72
|
+
|
|
73
|
+
The above copyright notice and this permission notice shall be included in all copies or substantial portions of
|
|
74
|
+
the Software.
|
|
75
|
+
|
|
76
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO
|
|
77
|
+
THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
78
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
|
|
79
|
+
CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
|
80
|
+
IN THE SOFTWARE.
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
## Monokai Light
|
|
84
|
+
|
|
85
|
+
- **Monokai Light**, Velichko Konstantin: https://github.com/zoxon/vscode-theme-monokai-light
|
|
86
|
+
- **Used in:** `packages/renderer/src/themes/monokai-light.ts`: the syntax theme `pd-monokai-light` takes its
|
|
87
|
+
token colours from the theme's JSON, with two deliberate changes (listed in the file). It is part of the npm
|
|
88
|
+
package (`dist/pd.js`).
|
|
89
|
+
- **Licence:** MIT
|
|
90
|
+
|
|
91
|
+
```
|
|
92
|
+
MIT License
|
|
93
|
+
|
|
94
|
+
Copyright (c) 2017 Velichko Konstantin
|
|
95
|
+
|
|
96
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated
|
|
97
|
+
documentation files (the "Software"), to deal in the Software without restriction, including without limitation
|
|
98
|
+
the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and
|
|
99
|
+
to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
|
100
|
+
|
|
101
|
+
The above copyright notice and this permission notice shall be included in all copies or substantial portions of
|
|
102
|
+
the Software.
|
|
103
|
+
|
|
104
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO
|
|
105
|
+
THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
106
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
|
|
107
|
+
CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
|
108
|
+
IN THE SOFTWARE.
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
## Colour vision deficiency matrices
|
|
112
|
+
|
|
113
|
+
- **Machado, G. M., Oliveira, M. M., Fernandes, L. (2009).** "A Physiologically-based Model for Simulation of Color
|
|
114
|
+
Vision Deficiency". *IEEE Transactions on Visualization and Computer Graphics* 15(6), 1291-1298.
|
|
115
|
+
https://doi.org/10.1109/TVCG.2009.113
|
|
116
|
+
- **Used in:** `apps/dev-ui/src/core/cvd-math.ts`: the matrices of the workbench's colour-vision simulation (protanopia,
|
|
117
|
+
deuteranopia, tritanopia, eleven severities each). They are numbers published in that paper: data, not code. The
|
|
118
|
+
achromatopsia table is not from the paper.
|
|
119
|
+
- **Licence:** none applies to published data; the paper is cited as its source.
|
|
120
|
+
|
|
121
|
+
## Dependencies with other licences
|
|
122
|
+
|
|
123
|
+
The npm package declares its dependencies, and npm installs them with their own licence files; none is bundled into
|
|
124
|
+
`dist/` or modified. Almost all are MIT, ISC, BSD or Apache-2.0. Two have terms worth naming:
|
|
125
|
+
|
|
126
|
+
- **axe-core** (Deque Systems), **MPL-2.0**: https://github.com/dequelabs/axe-core. Used by the accessibility checks
|
|
127
|
+
(`packages/a11y`), as installed.
|
|
128
|
+
- **libvips** binaries (`@img/sharp-libvips-*`), **LGPL-3.0-or-later**: https://github.com/lovell/sharp-libvips. Optional
|
|
129
|
+
dependencies of **sharp** (Apache-2.0), which encodes the storefront's images; installed as prebuilt binaries, not
|
|
130
|
+
linked into or copied into this package. An install with `--omit=optional` leaves them out.
|
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
// packages/config/src/validate.ts
|
|
2
|
+
import { relative, resolve, sep } from "node:path";
|
|
3
|
+
var IMAGES = { keys: { quality: "quality", effort: "effort" } };
|
|
2
4
|
var SHAPE = {
|
|
3
5
|
$schema: "string",
|
|
4
6
|
sourceDir: "string",
|
|
@@ -39,9 +41,26 @@ var SHAPE = {
|
|
|
39
41
|
},
|
|
40
42
|
packages: "packages",
|
|
41
43
|
exclude: "strings",
|
|
42
|
-
build: { keys: { outDir: "string", basePath: "string", audit: "boolean" } }
|
|
44
|
+
build: { keys: { outDir: "string", basePath: "string", audit: "boolean" } },
|
|
45
|
+
images: IMAGES,
|
|
46
|
+
storefront: {
|
|
47
|
+
keys: {
|
|
48
|
+
pagesDir: "string",
|
|
49
|
+
outDir: "string",
|
|
50
|
+
host: "host",
|
|
51
|
+
workbenchUrl: "workbench-url",
|
|
52
|
+
site: "plain-object",
|
|
53
|
+
url: "site-url",
|
|
54
|
+
lang: "lang",
|
|
55
|
+
index: "boolean",
|
|
56
|
+
image: "asset-path",
|
|
57
|
+
images: IMAGES
|
|
58
|
+
},
|
|
59
|
+
required: ["pagesDir", "outDir"]
|
|
60
|
+
}
|
|
43
61
|
};
|
|
44
62
|
var REQUIRED = ["sourceDir", "patternsDir", "outDir", "styles"];
|
|
63
|
+
var WORKBENCH_PATH = /^\/(?:(?!\.{1,2}(?:\/|$))[a-z0-9._~-]+\/?)+$/i;
|
|
45
64
|
var isObject = (v) => typeof v === "object" && v !== null && !Array.isArray(v);
|
|
46
65
|
var isStrings = (v) => Array.isArray(v) && v.every((x) => typeof x === "string");
|
|
47
66
|
function distance(a, b) {
|
|
@@ -116,6 +135,63 @@ function checkValue(value, rule, at, problems) {
|
|
|
116
135
|
if (!ok) fail(`a path or { light, dark }`);
|
|
117
136
|
return;
|
|
118
137
|
}
|
|
138
|
+
if (rule === "workbench-url") {
|
|
139
|
+
let ok = false;
|
|
140
|
+
if (typeof value === "string" && WORKBENCH_PATH.test(value)) ok = true;
|
|
141
|
+
else if (typeof value === "string") {
|
|
142
|
+
try {
|
|
143
|
+
const url = new URL(value);
|
|
144
|
+
ok = /^https?:$/.test(url.protocol) && url.search === "" && url.hash === "" && !/[?#]/.test(value);
|
|
145
|
+
} catch {
|
|
146
|
+
ok = false;
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
if (!ok) fail(`an absolute http(s) URL for a workbench on its own host, such as "https://workbench.example.com/", or a path for one on the storefront's host, such as "/workbench/"`);
|
|
150
|
+
return;
|
|
151
|
+
}
|
|
152
|
+
if (rule === "site-url") {
|
|
153
|
+
let ok = false;
|
|
154
|
+
if (typeof value === "string") {
|
|
155
|
+
try {
|
|
156
|
+
const url = new URL(value);
|
|
157
|
+
ok = /^https?:$/.test(url.protocol) && url.pathname === "/" && url.search === "" && url.hash === "" && !/[?#]/.test(value);
|
|
158
|
+
} catch {
|
|
159
|
+
ok = false;
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
if (!ok) fail(`the site's absolute http(s) address, with no path, query or fragment, such as "https://example.com/"`);
|
|
163
|
+
return;
|
|
164
|
+
}
|
|
165
|
+
if (rule === "lang") {
|
|
166
|
+
if (typeof value !== "string" || !/^[a-z]{2,3}(?:-[a-z]{4})?(?:-(?:[a-z]{2}|\d{3}))?(?:-(?:[a-z\d]{5,8}|\d[a-z\d]{3}))*$/i.test(value)) {
|
|
167
|
+
fail(`a language tag, such as "en", "de-AT" or "zh-Hant-TW"`);
|
|
168
|
+
}
|
|
169
|
+
return;
|
|
170
|
+
}
|
|
171
|
+
if (rule === "asset-path") {
|
|
172
|
+
if (typeof value !== "string" || !/^\/assets\/[^?#]+[^/?#]$/.test(value)) {
|
|
173
|
+
fail(`a path to a file in the assets, such as "/assets/images/share.png"`);
|
|
174
|
+
}
|
|
175
|
+
return;
|
|
176
|
+
}
|
|
177
|
+
if (rule === "quality") {
|
|
178
|
+
if (typeof value !== "number" || !Number.isInteger(value) || value < 1 || value > 100) fail("a whole number from 1 to 100 (WebP quality)");
|
|
179
|
+
return;
|
|
180
|
+
}
|
|
181
|
+
if (rule === "effort") {
|
|
182
|
+
if (typeof value !== "number" || !Number.isInteger(value) || value < 0 || value > 6) fail("a whole number from 0 to 6 (WebP effort: 0 fastest, 6 smallest)");
|
|
183
|
+
return;
|
|
184
|
+
}
|
|
185
|
+
if (rule === "plain-object") {
|
|
186
|
+
if (!isObject(value)) fail(`an object of the site's values, such as { title: "My site" }`);
|
|
187
|
+
return;
|
|
188
|
+
}
|
|
189
|
+
if (rule === "host") {
|
|
190
|
+
if (typeof value !== "string" || !/^[a-z0-9](?:[a-z0-9-]*[a-z0-9])?(?:\.[a-z0-9](?:[a-z0-9-]*[a-z0-9])?)*$/i.test(value)) {
|
|
191
|
+
fail(`a host name with no scheme, port or path, such as "live.localhost"`);
|
|
192
|
+
}
|
|
193
|
+
return;
|
|
194
|
+
}
|
|
119
195
|
if ("values" in rule) {
|
|
120
196
|
if (typeof value === "string" && rule.unsupported?.includes(value)) {
|
|
121
197
|
problems.push(`"${at}": "${value}" is not supported yet \u2014 use ${rule.values.map((v) => `"${v}"`).join(" or ")}, or leave it out`);
|
|
@@ -133,19 +209,64 @@ function checkValue(value, rule, at, problems) {
|
|
|
133
209
|
var ConfigError = class extends Error {
|
|
134
210
|
name = "ConfigError";
|
|
135
211
|
};
|
|
212
|
+
function checkRelations(raw, problems) {
|
|
213
|
+
const sf = raw.storefront;
|
|
214
|
+
if (!isObject(sf)) return;
|
|
215
|
+
const folders = [
|
|
216
|
+
["storefront.pagesDir", sf.pagesDir],
|
|
217
|
+
["patternsDir", raw.patternsDir],
|
|
218
|
+
["storefront.outDir", sf.outDir]
|
|
219
|
+
];
|
|
220
|
+
const root = resolve(sep, "pd-root");
|
|
221
|
+
const inside = (child, parent) => {
|
|
222
|
+
const rel = relative(parent, child);
|
|
223
|
+
return rel !== "" && !rel.startsWith("..") && !rel.startsWith(sep) && !/^[a-zA-Z]:/.test(rel);
|
|
224
|
+
};
|
|
225
|
+
for (let i = 0; i < folders.length; i++) {
|
|
226
|
+
for (let j = i + 1; j < folders.length; j++) {
|
|
227
|
+
const [a, va] = folders[i], [b, vb] = folders[j];
|
|
228
|
+
if (typeof va !== "string" || typeof vb !== "string") continue;
|
|
229
|
+
const pa = resolve(root, va), pb = resolve(root, vb);
|
|
230
|
+
const label = (name, value) => `"${name}" ("${value}")`;
|
|
231
|
+
if (pa === pb) problems.push(`${label(a, va)} and ${label(b, vb)} are the same folder \u2014 each needs a folder of its own`);
|
|
232
|
+
else if (inside(pa, pb)) problems.push(`${label(a, va)} is inside ${label(b, vb)} \u2014 each needs a folder of its own, outside the other`);
|
|
233
|
+
else if (inside(pb, pa)) problems.push(`${label(b, vb)} is inside ${label(a, va)} \u2014 each needs a folder of its own, outside the other`);
|
|
234
|
+
}
|
|
235
|
+
}
|
|
236
|
+
}
|
|
136
237
|
function configProblems(raw) {
|
|
137
238
|
if (!isObject(raw)) return ["the config must be an object (a .ts config must `export default defineConfig({ \u2026 })`)"];
|
|
138
239
|
const problems = [];
|
|
139
240
|
checkObject(raw, SHAPE, REQUIRED, "", problems);
|
|
241
|
+
if (problems.length === 0) checkRelations(raw, problems);
|
|
140
242
|
return problems;
|
|
141
243
|
}
|
|
244
|
+
var withOneTrailingSlash = (url) => `${url.replace(/\/+$/, "")}/`;
|
|
142
245
|
function validateConfig(raw, source) {
|
|
143
246
|
const problems = configProblems(raw);
|
|
144
247
|
if (problems.length > 0) {
|
|
145
248
|
throw new ConfigError(`${source}: invalid config
|
|
146
249
|
${problems.map((p) => ` - ${p}`).join("\n")}`);
|
|
147
250
|
}
|
|
148
|
-
|
|
251
|
+
const config = raw;
|
|
252
|
+
const sf = config.storefront;
|
|
253
|
+
if (!sf) return config;
|
|
254
|
+
const workbenchUrl = sf.workbenchUrl !== void 0 ? withOneTrailingSlash(sf.workbenchUrl) : void 0;
|
|
255
|
+
const url = sf.url !== void 0 ? `${new URL(sf.url).origin}/` : void 0;
|
|
256
|
+
if (workbenchUrl === sf.workbenchUrl && url === sf.url) return config;
|
|
257
|
+
return { ...config, storefront: {
|
|
258
|
+
...sf,
|
|
259
|
+
...workbenchUrl !== void 0 ? { workbenchUrl } : {},
|
|
260
|
+
...url !== void 0 ? { url } : {}
|
|
261
|
+
} };
|
|
262
|
+
}
|
|
263
|
+
function sameHostWorkbenchPath(storefront) {
|
|
264
|
+
const w = storefront?.workbenchUrl;
|
|
265
|
+
if (w === void 0) return void 0;
|
|
266
|
+
if (w.startsWith("/")) return w;
|
|
267
|
+
if (storefront?.url === void 0) return void 0;
|
|
268
|
+
const u = new URL(w);
|
|
269
|
+
return `${u.origin}/` === storefront.url ? u.pathname : void 0;
|
|
149
270
|
}
|
|
150
271
|
|
|
151
272
|
// packages/config/src/index.ts
|
|
@@ -154,7 +275,9 @@ function defineConfig(config) {
|
|
|
154
275
|
}
|
|
155
276
|
|
|
156
277
|
export {
|
|
278
|
+
suggest,
|
|
157
279
|
ConfigError,
|
|
158
280
|
validateConfig,
|
|
281
|
+
sameHostWorkbenchPath,
|
|
159
282
|
defineConfig
|
|
160
283
|
};
|