pattern-dump 0.1.0-alpha.4 → 0.3.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 +106 -1
- package/LICENSE +16 -3
- package/README.md +7 -7
- package/THIRD-PARTY-NOTICES.md +130 -0
- package/dist/chunks/chunk-5WFBNPXB.js +294 -0
- package/dist/dev-ui/main.js +215 -77
- package/dist/index.js +1 -1
- package/dist/pd.js +5833 -881
- package/dist/types/config/index.d.ts +93 -2
- package/dist/types/config/validate.d.ts +19 -1
- 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/dist/chunks/chunk-NXGPZL5L.js +0 -160
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
|
3
|
+
"title": "Note",
|
|
4
|
+
"description": "A short aside. On a page: <pd-components-note heading=\"…\">text</pd-components-note>.",
|
|
5
|
+
"type": "object",
|
|
6
|
+
"required": ["heading", "text"],
|
|
7
|
+
"x-pd-content": "text",
|
|
8
|
+
"properties": {
|
|
9
|
+
"heading": { "type": "string", "description": "One line, in bold" },
|
|
10
|
+
"text": { "type": "string", "contentMediaType": "text/markdown", "description": "The note itself: the tag's content, as markdown" },
|
|
11
|
+
"tone": { "type": "string", "enum": ["tip", "warning"], "description": "Its colour; a plain note without one" }
|
|
12
|
+
}
|
|
13
|
+
}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
{{#> partials-base }}
|
|
2
|
+
<article class="page">
|
|
3
|
+
<h1 class="page-title">{{title}}</h1>
|
|
4
|
+
{{#if description}}<p class="page-description">{{description}}</p>{{/if}}
|
|
5
|
+
<div class="page-body">{{{body}}}</div>
|
|
6
|
+
{{#if page.next}}<p class="page-next"><a rel="next" href="{{page.next.route}}">Next: {{page.next.title}}</a></p>{{/if}}
|
|
7
|
+
</article>
|
|
8
|
+
{{/partials-base}}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
{
|
|
2
|
+
"title": "A page",
|
|
3
|
+
"description": "Its one-sentence description.",
|
|
4
|
+
"body": "<p>The page's markdown, rendered.</p>",
|
|
5
|
+
"site": { "title": __PD_BRAND_JSON__, "footer": "Made with Pattern Dump." },
|
|
6
|
+
"nav": [{ "route": "/", "title": "Home", "current": true }, { "route": "/about/", "title": "About" }],
|
|
7
|
+
"page": { "next": { "route": "/about/", "title": "About" } }
|
|
8
|
+
}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
|
3
|
+
"title": "Page",
|
|
4
|
+
"description": "The layout every page renders with. Its properties are what a page's frontmatter may set.",
|
|
5
|
+
"type": "object",
|
|
6
|
+
"x-pd-prose-images": { "widths": [480, 672, 1344], "sizes": "(min-width: 44rem) 42rem, calc(100vw - 2rem)" },
|
|
7
|
+
"required": ["title"],
|
|
8
|
+
"properties": {
|
|
9
|
+
"title": { "type": "string", "description": "The page's heading, its title in the navigation and in search results" },
|
|
10
|
+
"description": { "type": "string", "description": "One sentence under the heading, and the page's description for search results" },
|
|
11
|
+
"page": {
|
|
12
|
+
"type": "object",
|
|
13
|
+
"description": "What the storefront works out for the page",
|
|
14
|
+
"properties": {
|
|
15
|
+
"next": { "description": "The page after this one in the navigation" }
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
<div class="site">
|
|
2
|
+
<a class="site-skip" href="#main">Skip to the content</a>
|
|
3
|
+
<header class="site-header">
|
|
4
|
+
<a class="site-title" href="/">{{site.title}}</a>
|
|
5
|
+
<nav class="site-nav" aria-label="Site">
|
|
6
|
+
<ul>
|
|
7
|
+
{{#each nav}}<li><a href="{{route}}"{{#if current}} aria-current="page"{{/if}}>{{title}}</a></li>{{/each}}
|
|
8
|
+
</ul>
|
|
9
|
+
</nav>
|
|
10
|
+
</header>
|
|
11
|
+
<main class="site-main" id="main">
|
|
12
|
+
{{> @partial-block }}
|
|
13
|
+
</main>
|
|
14
|
+
<footer class="site-footer">
|
|
15
|
+
<p>{{site.footer}}</p>
|
|
16
|
+
</footer>
|
|
17
|
+
</div>
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
|
3
|
+
"title": "Base",
|
|
4
|
+
"description": "The frame every layout is built on. Its site property declares what storefront.site may hold.",
|
|
5
|
+
"type": "object",
|
|
6
|
+
"required": ["site"],
|
|
7
|
+
"properties": {
|
|
8
|
+
"site": {
|
|
9
|
+
"type": "object",
|
|
10
|
+
"description": "Values every page shares: storefront.site in the config",
|
|
11
|
+
"required": ["title"],
|
|
12
|
+
"properties": {
|
|
13
|
+
"title": { "type": "string", "description": "The site's name, in the header" },
|
|
14
|
+
"footer": { "type": "string", "description": "The line at the bottom of every page" }
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
<link rel="icon" href="/assets/icon.svg">
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
@use "../base/tokens";
|
|
2
|
+
|
|
3
|
+
.note { margin-block: tokens.$space-md; padding: tokens.$space-md; border-left: 4px solid var(--color-border, #6b7280); border-radius: tokens.$radius; background: #f3f4f6; }
|
|
4
|
+
.note-tip { border-left-color: #0b7a3e; background: #ecf8f1; }
|
|
5
|
+
.note-warning { border-left-color: #a15c00; background: #fdf4e7; }
|
|
6
|
+
.note-heading { margin: 0 0 tokens.$space-xs; font-weight: 700; }
|
|
7
|
+
.note-text > :first-child { margin-top: 0; }
|
|
8
|
+
.note-text > :last-child { margin-bottom: 0; }
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
@use "../base/tokens";
|
|
2
|
+
|
|
3
|
+
.page-title { margin-block: 0 tokens.$space-sm; line-height: 1.2; }
|
|
4
|
+
.page-description { margin-block: 0 tokens.$space-lg; color: var(--color-text-muted, #4b5563); }
|
|
5
|
+
.page-body iframe { width: 100%; border: 0; }
|
|
6
|
+
.page-next { margin-top: tokens.$space-lg; }
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
@use "../base/tokens";
|
|
2
|
+
|
|
3
|
+
.site { max-width: 44rem; margin: 0 auto; padding: tokens.$space-lg tokens.$space-md; }
|
|
4
|
+
.site-skip { position: absolute; left: -100vw; }
|
|
5
|
+
.site-skip:focus { left: tokens.$space-md; }
|
|
6
|
+
.site-header { display: flex; flex-wrap: wrap; gap: tokens.$space-md; align-items: baseline; justify-content: space-between; }
|
|
7
|
+
.site-title { font-weight: 700; color: inherit; text-decoration: none; }
|
|
8
|
+
.site-nav ul { display: flex; gap: tokens.$space-md; margin: 0; padding: 0; list-style: none; }
|
|
9
|
+
.site-nav a[aria-current="page"] { font-weight: 700; }
|
|
10
|
+
.site-main { margin-block: tokens.$space-lg; }
|
|
11
|
+
// An image never overflows the column: with its width and height it keeps its aspect ratio as it scales down.
|
|
12
|
+
.site img { max-inline-size: 100%; block-size: auto; }
|
|
13
|
+
.site-footer { border-top: 1px solid var(--color-border, #6b7280); color: var(--color-text-muted, #4b5563); }
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
// The website: every markdown file in pages/ is a page, rendered with the skin in src/patterns/layouts
|
|
2
|
+
// and src/patterns/partials. `npm run dev` prints its address, http://live.localhost:4000/.
|
|
3
|
+
storefront: {
|
|
4
|
+
pagesDir: "./pages",
|
|
5
|
+
outDir: "./site",
|
|
6
|
+
// The workbench is published on the website's own host, under /workbench/ (and built for that path,
|
|
7
|
+
// build.basePath below).
|
|
8
|
+
workbenchUrl: "/workbench/",
|
|
9
|
+
// Your domain, once you have one: canonical URLs, link previews and the sitemap are built from it.
|
|
10
|
+
// url: "https://www.example.com/",
|
|
11
|
+
site: { title: __PD_BRAND_JSON__, footer: "Made with Pattern Dump." },
|
|
12
|
+
},
|
|
13
|
+
build: { basePath: "/workbench/" },
|
|
14
|
+
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
|
|
2
|
+
## The website
|
|
3
|
+
|
|
4
|
+
`pages/` is a website: every markdown file in it is a page, at the address its path names
|
|
5
|
+
(`pages/about.md` is `/about/`). `npm run dev` serves it next to the workbench:
|
|
6
|
+
|
|
7
|
+
| Address | Serves |
|
|
8
|
+
|---|---|
|
|
9
|
+
| http://live.localhost:4000/ | the website |
|
|
10
|
+
| http://pd.localhost:4000/ | the workbench |
|
|
11
|
+
|
|
12
|
+
If Safari can't open them, add this line to `/etc/hosts`: `127.0.0.1 live.localhost pd.localhost`.
|
|
13
|
+
|
|
14
|
+
### Try breaking it
|
|
15
|
+
|
|
16
|
+
`pages/index.md` places the note component with a `pd-` tag, and its values are checked against the
|
|
17
|
+
component's schema before the page is shown. With the website open, change `tone="tip"` to `tone="tips"`
|
|
18
|
+
and save: the page shows what is wrong, with the file, line and column. Change it back and the page
|
|
19
|
+
returns by itself. How `pd-` tags work:
|
|
20
|
+
[placing components](https://github.com/n8design/pattern-dump/blob/main/docs/guide/storefront.md#placing-components).
|
|
21
|
+
|
|
22
|
+
### Where it lives
|
|
23
|
+
|
|
24
|
+
| Path | What lives there |
|
|
25
|
+
|---|---|
|
|
26
|
+
| `pages/` | the pages, in markdown (`pages/` is the website; `src/patterns/pages/`, if you have it, holds page-sized components) |
|
|
27
|
+
| `src/patterns/layouts/page/` | the layout every page renders with; its schema is what a page's frontmatter may set |
|
|
28
|
+
| `src/patterns/partials/base/` | the frame around every page: header, navigation, footer |
|
|
29
|
+
| `src/patterns/partials/head/` | what the skin adds to every page's `<head>` (the icon) |
|
|
30
|
+
| `src/patterns/components/note/` | the component the home page shows |
|
|
31
|
+
| `pattern-dump.config.ts` | `storefront`: the website's name and footer (`site`), and where it is published |
|
|
32
|
+
|
|
33
|
+
A page that doesn't exist shows a built-in 404 page; write `pages/404.md` to change it. A page that moved
|
|
34
|
+
can forward from its old address (`redirectFrom: [/old/]`), and `index: false` keeps a page out of search
|
|
35
|
+
engines. All of it is in the [storefront guide](https://github.com/n8design/pattern-dump/blob/main/docs/guide/storefront.md).
|
|
36
|
+
|
|
37
|
+
### Build it
|
|
38
|
+
|
|
39
|
+
`npm run build` writes the website to `site/` and the workbench to `dist/`, built for `/workbench/`. The
|
|
40
|
+
website is served from the root of its host, with the workbench copied into it at `/workbench/`, which is
|
|
41
|
+
what the GitHub Pages workflow does.
|
|
42
|
+
|
|
43
|
+
### Publish it
|
|
44
|
+
|
|
45
|
+
`.github/workflows/pages.yml` publishes both to GitHub Pages on every push to `main`. The website lives at
|
|
46
|
+
the root of its host, so it needs a custom domain (a project page under `/<repository>/` can't host it).
|
|
47
|
+
Once, in the repository on GitHub:
|
|
48
|
+
|
|
49
|
+
1. **Settings → Pages → Source:** "GitHub Actions".
|
|
50
|
+
2. **Settings → Pages → Custom domain:** your domain, then Save. GitHub recommends verifying the domain in
|
|
51
|
+
your account settings first.
|
|
52
|
+
3. **DNS:** for an apex domain (`example.com`), `A` records to `185.199.108.153`, `185.199.109.153`,
|
|
53
|
+
`185.199.110.153` and `185.199.111.153`; for a subdomain (`www.example.com`), a `CNAME` record to
|
|
54
|
+
`<your-user>.github.io`, without the repository name.
|
|
55
|
+
4. **Enforce HTTPS** in the same settings, once GitHub offers it (it can take up to a day).
|
|
56
|
+
5. **`storefront.url`** in `pattern-dump.config.ts`: the same address, for canonical URLs, link previews and
|
|
57
|
+
the sitemap.
|
|
58
|
+
|
|
59
|
+
The workflow writes no `CNAME` file: with a GitHub Actions deploy, the custom domain is the setting in
|
|
60
|
+
step 2. It installs with `npm ci`, so `pattern-dump` must come from the npm registry, not a local file.
|
|
@@ -1,160 +0,0 @@
|
|
|
1
|
-
// packages/config/src/validate.ts
|
|
2
|
-
var SHAPE = {
|
|
3
|
-
$schema: "string",
|
|
4
|
-
sourceDir: "string",
|
|
5
|
-
patternsDir: "string",
|
|
6
|
-
outDir: "string",
|
|
7
|
-
styles: {
|
|
8
|
-
keys: {
|
|
9
|
-
strategy: { values: ["parallel"], unsupported: ["co-located"] },
|
|
10
|
-
dir: "string",
|
|
11
|
-
entry: "string-or-strings"
|
|
12
|
-
},
|
|
13
|
-
required: ["dir"]
|
|
14
|
-
},
|
|
15
|
-
themes: {
|
|
16
|
-
keys: {
|
|
17
|
-
dir: "string",
|
|
18
|
-
default: "string",
|
|
19
|
-
switch: { values: ["attribute", "stylesheet"] },
|
|
20
|
-
swatch: { keys: { slots: "strings" }, required: ["slots"] }
|
|
21
|
-
},
|
|
22
|
-
required: ["default"]
|
|
23
|
-
},
|
|
24
|
-
assets: {
|
|
25
|
-
keys: {
|
|
26
|
-
strategy: { values: ["central"], unsupported: ["component-relative"] },
|
|
27
|
-
dir: "string-or-strings",
|
|
28
|
-
css: "strings"
|
|
29
|
-
}
|
|
30
|
-
},
|
|
31
|
-
scriptsDir: "string",
|
|
32
|
-
globalScripts: "strings",
|
|
33
|
-
dataDir: "string",
|
|
34
|
-
helpers: "string",
|
|
35
|
-
documentBase: "strings",
|
|
36
|
-
overviews: "boolean",
|
|
37
|
-
shell: {
|
|
38
|
-
keys: { brand: { keys: { title: "string", logo: "logo", logoAlt: "string", href: "string" } } }
|
|
39
|
-
},
|
|
40
|
-
packages: "packages",
|
|
41
|
-
exclude: "strings",
|
|
42
|
-
build: { keys: { outDir: "string", basePath: "string", audit: "boolean" } }
|
|
43
|
-
};
|
|
44
|
-
var REQUIRED = ["sourceDir", "patternsDir", "outDir", "styles"];
|
|
45
|
-
var isObject = (v) => typeof v === "object" && v !== null && !Array.isArray(v);
|
|
46
|
-
var isStrings = (v) => Array.isArray(v) && v.every((x) => typeof x === "string");
|
|
47
|
-
function distance(a, b) {
|
|
48
|
-
const row = Array.from({ length: b.length + 1 }, (_, i) => i);
|
|
49
|
-
for (let i = 1; i <= a.length; i++) {
|
|
50
|
-
let prev = row[0];
|
|
51
|
-
row[0] = i;
|
|
52
|
-
for (let j = 1; j <= b.length; j++) {
|
|
53
|
-
const cur = row[j];
|
|
54
|
-
row[j] = Math.min(row[j] + 1, row[j - 1] + 1, prev + (a[i - 1].toLowerCase() === b[j - 1].toLowerCase() ? 0 : 1));
|
|
55
|
-
prev = cur;
|
|
56
|
-
}
|
|
57
|
-
}
|
|
58
|
-
return row[b.length];
|
|
59
|
-
}
|
|
60
|
-
function suggest(key, known) {
|
|
61
|
-
let best;
|
|
62
|
-
let bestD = Infinity;
|
|
63
|
-
for (const k of known) {
|
|
64
|
-
const d = distance(key, k);
|
|
65
|
-
if (d < bestD) {
|
|
66
|
-
best = k;
|
|
67
|
-
bestD = d;
|
|
68
|
-
}
|
|
69
|
-
}
|
|
70
|
-
if (best === void 0) return void 0;
|
|
71
|
-
const sameStart = key.slice(0, 3).toLowerCase() === best.slice(0, 3).toLowerCase();
|
|
72
|
-
return bestD <= 2 || bestD <= 3 && sameStart ? best : void 0;
|
|
73
|
-
}
|
|
74
|
-
function checkObject(value, shape, required, at, problems) {
|
|
75
|
-
const known = Object.keys(shape);
|
|
76
|
-
const unknown = Object.keys(value).filter((k) => !(k in shape));
|
|
77
|
-
for (const key of required) {
|
|
78
|
-
if (value[key] !== void 0) continue;
|
|
79
|
-
const near = unknown.find((u) => suggest(u, [key]) === key);
|
|
80
|
-
problems.push(near ? `missing required "${at}${key}" (found "${at}${near}" \u2014 did you mean "${at}${key}"?)` : `missing required "${at}${key}"`);
|
|
81
|
-
}
|
|
82
|
-
for (const key of unknown) {
|
|
83
|
-
const near = suggest(key, known);
|
|
84
|
-
if (near && required.includes(near) && value[near] === void 0) continue;
|
|
85
|
-
problems.push(`unknown key "${at}${key}"${near ? ` \u2014 did you mean "${at}${near}"?` : ""}`);
|
|
86
|
-
}
|
|
87
|
-
for (const key of known) {
|
|
88
|
-
if (value[key] !== void 0) checkValue(value[key], shape[key], `${at}${key}`, problems);
|
|
89
|
-
}
|
|
90
|
-
}
|
|
91
|
-
function checkValue(value, rule, at, problems) {
|
|
92
|
-
const fail = (expected) => problems.push(`"${at}" must be ${expected}`);
|
|
93
|
-
if (rule === "string") {
|
|
94
|
-
if (typeof value !== "string") fail("a string");
|
|
95
|
-
return;
|
|
96
|
-
}
|
|
97
|
-
if (rule === "boolean") {
|
|
98
|
-
if (typeof value !== "boolean") fail("true or false");
|
|
99
|
-
return;
|
|
100
|
-
}
|
|
101
|
-
if (rule === "strings") {
|
|
102
|
-
if (!isStrings(value)) fail("a list of strings");
|
|
103
|
-
return;
|
|
104
|
-
}
|
|
105
|
-
if (rule === "string-or-strings") {
|
|
106
|
-
if (typeof value !== "string" && !isStrings(value)) fail("a string or a list of strings");
|
|
107
|
-
return;
|
|
108
|
-
}
|
|
109
|
-
if (rule === "packages") {
|
|
110
|
-
const ok = Array.isArray(value) && value.every((p) => typeof p === "string" || isObject(p) && typeof p.name === "string" && (p.exclude === void 0 || isStrings(p.exclude)) && (p.styles === void 0 || typeof p.styles === "boolean"));
|
|
111
|
-
if (!ok) fail(`a list of package names or { name, exclude, styles } objects`);
|
|
112
|
-
return;
|
|
113
|
-
}
|
|
114
|
-
if (rule === "logo") {
|
|
115
|
-
const ok = typeof value === "string" || isObject(value) && typeof value.light === "string" && typeof value.dark === "string";
|
|
116
|
-
if (!ok) fail(`a path or { light, dark }`);
|
|
117
|
-
return;
|
|
118
|
-
}
|
|
119
|
-
if ("values" in rule) {
|
|
120
|
-
if (typeof value === "string" && rule.unsupported?.includes(value)) {
|
|
121
|
-
problems.push(`"${at}": "${value}" is not supported yet \u2014 use ${rule.values.map((v) => `"${v}"`).join(" or ")}, or leave it out`);
|
|
122
|
-
} else if (typeof value !== "string" || !rule.values.includes(value)) {
|
|
123
|
-
fail(rule.values.map((v) => `"${v}"`).join(" or "));
|
|
124
|
-
}
|
|
125
|
-
return;
|
|
126
|
-
}
|
|
127
|
-
if (!isObject(value)) {
|
|
128
|
-
fail("an object");
|
|
129
|
-
return;
|
|
130
|
-
}
|
|
131
|
-
checkObject(value, rule.keys, rule.required ?? [], `${at}.`, problems);
|
|
132
|
-
}
|
|
133
|
-
var ConfigError = class extends Error {
|
|
134
|
-
name = "ConfigError";
|
|
135
|
-
};
|
|
136
|
-
function configProblems(raw) {
|
|
137
|
-
if (!isObject(raw)) return ["the config must be an object (a .ts config must `export default defineConfig({ \u2026 })`)"];
|
|
138
|
-
const problems = [];
|
|
139
|
-
checkObject(raw, SHAPE, REQUIRED, "", problems);
|
|
140
|
-
return problems;
|
|
141
|
-
}
|
|
142
|
-
function validateConfig(raw, source) {
|
|
143
|
-
const problems = configProblems(raw);
|
|
144
|
-
if (problems.length > 0) {
|
|
145
|
-
throw new ConfigError(`${source}: invalid config
|
|
146
|
-
${problems.map((p) => ` - ${p}`).join("\n")}`);
|
|
147
|
-
}
|
|
148
|
-
return raw;
|
|
149
|
-
}
|
|
150
|
-
|
|
151
|
-
// packages/config/src/index.ts
|
|
152
|
-
function defineConfig(config) {
|
|
153
|
-
return config;
|
|
154
|
-
}
|
|
155
|
-
|
|
156
|
-
export {
|
|
157
|
-
ConfigError,
|
|
158
|
-
validateConfig,
|
|
159
|
-
defineConfig
|
|
160
|
-
};
|