livemark 0.2.0 → 0.7.1
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.md +9 -0
- package/README.md +5 -1
- package/build/actions/changelog/build.d.ts +14 -0
- package/build/actions/changelog/build.js +158 -0
- package/build/actions/changelog/build.unit.js +66 -0
- package/build/actions/config/define.d.ts +6 -0
- package/build/actions/config/define.js +8 -0
- package/build/actions/config/define.unit.js +29 -0
- package/build/actions/config/load.d.ts +5 -0
- package/build/actions/config/load.js +25 -0
- package/build/actions/config/load.unit.js +23 -0
- package/build/commands/build.d.ts +5 -0
- package/build/commands/build.js +14 -0
- package/build/commands/escape.d.ts +9 -0
- package/build/commands/escape.js +56 -0
- package/build/commands/preview.d.ts +5 -0
- package/build/commands/preview.js +18 -0
- package/build/commands/start.d.ts +5 -0
- package/build/commands/start.js +19 -0
- package/build/docs/markdown/includes/example.d.ts +58 -0
- package/build/docs/markdown/includes/example.js +5 -0
- package/build/entrypoints/main.d.ts +2 -0
- package/build/entrypoints/main.js +12 -0
- package/build/helpers/program.d.ts +2 -0
- package/build/helpers/program.js +5 -0
- package/build/index.d.ts +1 -4
- package/build/index.js +2 -5
- package/build/livemark.config.d.ts +58 -0
- package/build/livemark.config.js +25 -0
- package/build/models/config.d.ts +340 -0
- package/build/models/config.js +34 -0
- package/build/models/link.d.ts +13 -0
- package/build/models/link.js +9 -0
- package/build/models/patch.d.ts +21 -0
- package/build/models/patch.js +7 -0
- package/build/models/section.d.ts +75 -0
- package/build/models/section.js +26 -0
- package/build/models/theme.d.ts +72 -0
- package/build/models/theme.js +73 -0
- package/build/program.d.ts +2 -0
- package/build/program.js +16 -0
- package/build/vite.config.d.ts +2 -0
- package/build/vite.config.js +48 -0
- package/build/website/assets/logo.svg +117 -0
- package/build/website/client.tsx +10 -0
- package/build/website/components/Abbr.tsx +17 -0
- package/build/website/components/AnsiCode.tsx +15 -0
- package/build/website/components/Article.tsx +172 -0
- package/build/website/components/BackToTop.tsx +32 -0
- package/build/website/components/Banner.tsx +32 -0
- package/build/website/components/BlogIndex.tsx +121 -0
- package/build/website/components/BlogSidebar.tsx +162 -0
- package/build/website/components/Breadcrumbs.tsx +22 -0
- package/build/website/components/Callout.tsx +72 -0
- package/build/website/components/Card.tsx +48 -0
- package/build/website/components/Cards.tsx +8 -0
- package/build/website/components/ChangelogIndex.tsx +111 -0
- package/build/website/components/ChangelogSidebar.tsx +120 -0
- package/build/website/components/CodeBlock.tsx +135 -0
- package/build/website/components/CodeTabs.tsx +83 -0
- package/build/website/components/Column.tsx +4 -0
- package/build/website/components/Columns.tsx +12 -0
- package/build/website/components/Content.tsx +7 -0
- package/build/website/components/ContentTab.tsx +7 -0
- package/build/website/components/ContentTabs.tsx +82 -0
- package/build/website/components/DefaultCatchBoundary.tsx +54 -0
- package/build/website/components/DefinitionList.tsx +21 -0
- package/build/website/components/Details.tsx +30 -0
- package/build/website/components/FileTree.tsx +52 -0
- package/build/website/components/Footer.tsx +16 -0
- package/build/website/components/FootnoteRef.tsx +52 -0
- package/build/website/components/Heading.tsx +20 -0
- package/build/website/components/InlineBadge.tsx +9 -0
- package/build/website/components/InlineIcon.tsx +10 -0
- package/build/website/components/InlineToc.tsx +31 -0
- package/build/website/components/Layout.tsx +190 -0
- package/build/website/components/LinkButton.tsx +31 -0
- package/build/website/components/Mermaid.tsx +18 -0
- package/build/website/components/MermaidRenderer.tsx +37 -0
- package/build/website/components/MiniSidebar.tsx +49 -0
- package/build/website/components/NotFound.tsx +27 -0
- package/build/website/components/PackageTabs.tsx +74 -0
- package/build/website/components/PageToolbar.tsx +75 -0
- package/build/website/components/PrevNext.tsx +60 -0
- package/build/website/components/Search.tsx +28 -0
- package/build/website/components/SearchDialog.tsx +245 -0
- package/build/website/components/Section.tsx +24 -0
- package/build/website/components/SectionHeader.tsx +35 -0
- package/build/website/components/Sidebar.tsx +160 -0
- package/build/website/components/SidebarLinks.tsx +70 -0
- package/build/website/components/SidebarSections.tsx +71 -0
- package/build/website/components/SiteTitle.tsx +21 -0
- package/build/website/components/SortableTable.tsx +81 -0
- package/build/website/components/SoundCloud.tsx +16 -0
- package/build/website/components/TagIndex.tsx +120 -0
- package/build/website/components/Theme.tsx +39 -0
- package/build/website/components/Toc.tsx +226 -0
- package/build/website/components/YouTube.tsx +16 -0
- package/build/website/components/ZoomImage.tsx +25 -0
- package/build/website/content/article.ts +78 -0
- package/build/website/content/tag.ts +29 -0
- package/build/website/content-collections.ts +208 -0
- package/build/website/elements/accordion.tsx +78 -0
- package/build/website/elements/alert-dialog.tsx +185 -0
- package/build/website/elements/alert.tsx +74 -0
- package/build/website/elements/aspect-ratio.tsx +22 -0
- package/build/website/elements/avatar.tsx +107 -0
- package/build/website/elements/badge.tsx +51 -0
- package/build/website/elements/breadcrumb.tsx +120 -0
- package/build/website/elements/button-group.tsx +87 -0
- package/build/website/elements/button.tsx +57 -0
- package/build/website/elements/calendar.tsx +229 -0
- package/build/website/elements/card.tsx +102 -0
- package/build/website/elements/carousel.tsx +240 -0
- package/build/website/elements/chart.tsx +372 -0
- package/build/website/elements/checkbox.tsx +26 -0
- package/build/website/elements/collapsible.tsx +19 -0
- package/build/website/elements/command.tsx +210 -0
- package/build/website/elements/context-menu.tsx +270 -0
- package/build/website/elements/dialog.tsx +152 -0
- package/build/website/elements/direction.tsx +4 -0
- package/build/website/elements/drawer.tsx +127 -0
- package/build/website/elements/dropdown-menu.tsx +260 -0
- package/build/website/elements/empty.tsx +104 -0
- package/build/website/elements/field.tsx +235 -0
- package/build/website/elements/hover-card.tsx +49 -0
- package/build/website/elements/input-group.tsx +171 -0
- package/build/website/elements/input-otp.tsx +84 -0
- package/build/website/elements/input.tsx +18 -0
- package/build/website/elements/item.tsx +199 -0
- package/build/website/elements/kbd.tsx +26 -0
- package/build/website/elements/label.tsx +17 -0
- package/build/website/elements/menubar.tsx +282 -0
- package/build/website/elements/native-select.tsx +56 -0
- package/build/website/elements/navigation-menu.tsx +171 -0
- package/build/website/elements/pagination.tsx +133 -0
- package/build/website/elements/popover.tsx +88 -0
- package/build/website/elements/progress.tsx +81 -0
- package/build/website/elements/radio-group.tsx +36 -0
- package/build/website/elements/resizable.tsx +48 -0
- package/build/website/elements/scroll-area.tsx +51 -0
- package/build/website/elements/select.tsx +200 -0
- package/build/website/elements/separator.tsx +22 -0
- package/build/website/elements/sheet.tsx +130 -0
- package/build/website/elements/sidebar.tsx +717 -0
- package/build/website/elements/skeleton.tsx +13 -0
- package/build/website/elements/slider.tsx +57 -0
- package/build/website/elements/sonner.tsx +40 -0
- package/build/website/elements/spinner.tsx +16 -0
- package/build/website/elements/switch.tsx +30 -0
- package/build/website/elements/table.tsx +112 -0
- package/build/website/elements/tabs.tsx +79 -0
- package/build/website/elements/textarea.tsx +16 -0
- package/build/website/elements/toggle-group.tsx +87 -0
- package/build/website/elements/toggle.tsx +43 -0
- package/build/website/elements/tooltip.tsx +67 -0
- package/build/website/env.d.ts +14 -0
- package/build/website/helpers/article-icon.ts +61 -0
- package/build/website/helpers/article.ts +90 -0
- package/build/website/helpers/changelog-source.ts +16 -0
- package/build/website/helpers/changelog-source.unit.ts +38 -0
- package/build/website/helpers/dynamic-icon-resolver.tsx +19 -0
- package/build/website/helpers/dynamic-icon.tsx +12 -0
- package/build/website/helpers/favicon.ts +7 -0
- package/build/website/helpers/model.ts +4 -0
- package/build/website/helpers/resolve-asset-path.ts +9 -0
- package/build/website/helpers/resolve-includes.ts +131 -0
- package/build/website/helpers/resolve-includes.unit.ts +126 -0
- package/build/website/helpers/search-text.ts +15 -0
- package/build/website/helpers/section.ts +50 -0
- package/build/website/helpers/section.unit.ts +71 -0
- package/build/website/helpers/style.ts +6 -0
- package/build/website/helpers/theme.ts +27 -0
- package/build/website/helpers/toc-context.ts +10 -0
- package/build/website/helpers/toc.ts +46 -0
- package/build/website/helpers/toc.unit.ts +74 -0
- package/build/website/hooks/in-view.ts +30 -0
- package/build/website/hooks/media.ts +19 -0
- package/build/website/models/article.ts +55 -0
- package/build/website/models/toc.ts +5 -0
- package/build/website/plugins/rehype-inline-code.ts +107 -0
- package/build/website/plugins/rehype-task-list-a11y.ts +33 -0
- package/build/website/plugins/remark-abbr.ts +46 -0
- package/build/website/plugins/remark-abbr.unit.ts +99 -0
- package/build/website/plugins/remark-ansi.ts +248 -0
- package/build/website/plugins/remark-ansi.unit.ts +197 -0
- package/build/website/plugins/remark-badge.ts +50 -0
- package/build/website/plugins/remark-badge.unit.ts +96 -0
- package/build/website/plugins/remark-button.ts +60 -0
- package/build/website/plugins/remark-button.unit.ts +147 -0
- package/build/website/plugins/remark-callout.ts +57 -0
- package/build/website/plugins/remark-card.ts +80 -0
- package/build/website/plugins/remark-code-tabs.ts +87 -0
- package/build/website/plugins/remark-columns.ts +66 -0
- package/build/website/plugins/remark-custom-heading-id.ts +70 -0
- package/build/website/plugins/remark-custom-heading-id.unit.ts +131 -0
- package/build/website/plugins/remark-deflist.ts +36 -0
- package/build/website/plugins/remark-details.ts +49 -0
- package/build/website/plugins/remark-filetree.ts +89 -0
- package/build/website/plugins/remark-filetree.unit.ts +137 -0
- package/build/website/plugins/remark-github-callout.ts +71 -0
- package/build/website/plugins/remark-icon.ts +42 -0
- package/build/website/plugins/remark-image.ts +34 -0
- package/build/website/plugins/remark-media.ts +62 -0
- package/build/website/plugins/remark-media.unit.ts +74 -0
- package/build/website/plugins/remark-mermaid.ts +23 -0
- package/build/website/plugins/remark-npm.ts +52 -0
- package/build/website/plugins/remark-steps.ts +36 -0
- package/build/website/plugins/remark-steps.unit.ts +97 -0
- package/build/website/plugins/remark-tab.ts +100 -0
- package/build/website/plugins/remark-tab.unit.ts +181 -0
- package/build/website/plugins/remark-toc.ts +39 -0
- package/build/website/plugins/remark-toc.unit.ts +82 -0
- package/build/website/plugins/shiki-icon.ts +82 -0
- package/build/website/plugins/shiki-line-highlight.ts +174 -0
- package/build/website/plugins/vite-livemark.ts +91 -0
- package/build/website/routeTree.gen.ts +86 -0
- package/build/website/router.tsx +34 -0
- package/build/website/routes/$.tsx +92 -0
- package/build/website/routes/__root.tsx +97 -0
- package/build/website/server.ts +7 -0
- package/build/website/styles/general.css +163 -0
- package/build/website/styles/markdown.css +214 -0
- package/build/website/vite.config.ts +71 -0
- package/package.json +120 -12
- package/skills/authoring/SKILL.md +97 -0
- package/skills/configuration/SKILL.md +120 -0
- package/skills/customization/SKILL.md +118 -0
- package/build/descriptor/index.d.ts +0 -3
- package/build/descriptor/index.js +0 -4
- package/build/descriptor/load.d.ts +0 -8
- package/build/descriptor/load.js +0 -40
- package/build/descriptor/node.d.ts +0 -125
- package/build/descriptor/node.js +0 -9
- package/build/descriptor/save.d.ts +0 -8
- package/build/descriptor/save.js +0 -17
- package/build/descriptor/save.spec.js +0 -80
- package/build/descriptor/validate.d.ts +0 -9
- package/build/descriptor/validate.js +0 -14
- package/build/descriptor/validate.spec.js +0 -124
- package/build/dialect/Dialect.d.ts +0 -88
- package/build/dialect/Dialect.js +0 -2
- package/build/dialect/index.d.ts +0 -3
- package/build/dialect/index.js +0 -3
- package/build/dialect/load.d.ts +0 -4
- package/build/dialect/load.js +0 -7
- package/build/dialect/save.d.ts +0 -9
- package/build/dialect/save.js +0 -13
- package/build/dialect/validate.d.ts +0 -1
- package/build/dialect/validate.js +0 -4
- package/build/metadata/index.d.ts +0 -3
- package/build/metadata/index.js +0 -4
- package/build/metadata/load.d.ts +0 -10
- package/build/metadata/load.js +0 -55
- package/build/metadata/node.d.ts +0 -125
- package/build/metadata/node.js +0 -9
- package/build/metadata/save.d.ts +0 -8
- package/build/metadata/save.js +0 -17
- package/build/metadata/save.spec.js +0 -80
- package/build/metadata/validate.d.ts +0 -9
- package/build/metadata/validate.js +0 -14
- package/build/metadata/validate.spec.d.ts +0 -1
- package/build/metadata/validate.spec.js +0 -124
- package/build/package/Contributor.d.ts +0 -21
- package/build/package/Contributor.js +0 -2
- package/build/package/Package.d.ts +0 -65
- package/build/package/Package.js +0 -2
- package/build/package/index.d.ts +0 -4
- package/build/package/index.js +0 -3
- package/build/package/load.d.ts +0 -4
- package/build/package/load.js +0 -7
- package/build/package/save.d.ts +0 -9
- package/build/package/save.js +0 -13
- package/build/package/validate.d.ts +0 -1
- package/build/package/validate.js +0 -4
- package/build/resource/License.d.ts +0 -18
- package/build/resource/License.js +0 -2
- package/build/resource/Resource.d.ts +0 -67
- package/build/resource/Resource.js +0 -2
- package/build/resource/Source.d.ts +0 -17
- package/build/resource/Source.js +0 -2
- package/build/resource/index.d.ts +0 -5
- package/build/resource/index.js +0 -2
- package/build/resource/load.d.ts +0 -1
- package/build/resource/load.js +0 -2
- package/build/resource/save.d.ts +0 -9
- package/build/resource/save.js +0 -13
- package/build/resource/types/index.d.ts +0 -1
- package/build/resource/types/index.js +0 -2
- package/build/resource/types/table.d.ts +0 -29
- package/build/resource/types/table.js +0 -2
- package/build/resource/validate.d.ts +0 -1
- package/build/resource/validate.js +0 -4
- package/build/schema/Field.d.ts +0 -5
- package/build/schema/Field.js +0 -2
- package/build/schema/Schema.d.ts +0 -55
- package/build/schema/Schema.js +0 -2
- package/build/schema/fields/any.d.ts +0 -20
- package/build/schema/fields/any.js +0 -2
- package/build/schema/fields/array.d.ts +0 -32
- package/build/schema/fields/array.js +0 -2
- package/build/schema/fields/base.d.ts +0 -42
- package/build/schema/fields/base.js +0 -2
- package/build/schema/fields/boolean.d.ts +0 -28
- package/build/schema/fields/boolean.js +0 -2
- package/build/schema/fields/date.d.ts +0 -35
- package/build/schema/fields/date.js +0 -2
- package/build/schema/fields/datetime.d.ts +0 -35
- package/build/schema/fields/datetime.js +0 -2
- package/build/schema/fields/duration.d.ts +0 -28
- package/build/schema/fields/duration.js +0 -2
- package/build/schema/fields/geojson.d.ts +0 -26
- package/build/schema/fields/geojson.js +0 -2
- package/build/schema/fields/geopoint.d.ts +0 -27
- package/build/schema/fields/geopoint.js +0 -2
- package/build/schema/fields/index.d.ts +0 -16
- package/build/schema/fields/index.js +0 -17
- package/build/schema/fields/integer.d.ts +0 -37
- package/build/schema/fields/integer.js +0 -2
- package/build/schema/fields/list.d.ts +0 -36
- package/build/schema/fields/list.js +0 -2
- package/build/schema/fields/number.d.ts +0 -40
- package/build/schema/fields/number.js +0 -2
- package/build/schema/fields/object.d.ts +0 -32
- package/build/schema/fields/object.js +0 -2
- package/build/schema/fields/string.d.ts +0 -40
- package/build/schema/fields/string.js +0 -2
- package/build/schema/fields/time.d.ts +0 -35
- package/build/schema/fields/time.js +0 -2
- package/build/schema/fields/year.d.ts +0 -28
- package/build/schema/fields/year.js +0 -2
- package/build/schema/fields/yearmonth.d.ts +0 -28
- package/build/schema/fields/yearmonth.js +0 -2
- package/build/schema/index.d.ts +0 -4
- package/build/schema/index.js +0 -2
- package/build/schema/load.d.ts +0 -1
- package/build/schema/load.js +0 -2
- package/build/schema/save.d.ts +0 -9
- package/build/schema/save.js +0 -13
- package/build/schema/validate.d.ts +0 -1
- package/build/schema/validate.js +0 -4
- package/build/tsconfig.tsbuildinfo +0 -1
- package/index.ts +0 -0
- package/tsconfig.json +0 -10
- package/typedoc.json +0 -4
- /package/build/{descriptor/save.spec.d.ts → actions/changelog/build.unit.d.ts} +0 -0
- /package/build/{descriptor/validate.spec.d.ts → actions/config/define.unit.d.ts} +0 -0
- /package/build/{metadata/save.spec.d.ts → actions/config/load.unit.d.ts} +0 -0
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: livemark-configuration
|
|
3
|
+
description: Use when editing livemark.config.ts — site metadata, include/exclude globs, syntax themes, sections (article/blog/changelog), navigation links, and patches.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Livemark Configuration
|
|
7
|
+
|
|
8
|
+
Guidance for editing `livemark.config.ts` at the project root.
|
|
9
|
+
|
|
10
|
+
## When to use this skill
|
|
11
|
+
|
|
12
|
+
Invoke when the user asks to:
|
|
13
|
+
|
|
14
|
+
- Set the site title, description, canonical URL, logo, favicon.
|
|
15
|
+
- Change which files are included or excluded.
|
|
16
|
+
- Switch code-block syntax highlighting themes.
|
|
17
|
+
- Add, reorder, or retype a section (docs/blog/changelog).
|
|
18
|
+
- Add or remove header/sidebar links.
|
|
19
|
+
- Patch a specific file's frontmatter without editing its source.
|
|
20
|
+
|
|
21
|
+
## The config shape
|
|
22
|
+
|
|
23
|
+
```ts
|
|
24
|
+
// livemark.config.ts
|
|
25
|
+
import { defineConfig } from "livemark"
|
|
26
|
+
|
|
27
|
+
export default defineConfig({
|
|
28
|
+
// Required
|
|
29
|
+
include: "docs/**/*.md", // string | string[] of glob patterns
|
|
30
|
+
|
|
31
|
+
// Optional: site metadata
|
|
32
|
+
site: "https://example.com", // canonical origin — enables sitemap
|
|
33
|
+
title: "My Docs", // <title>, og:title, header
|
|
34
|
+
description: "Short blurb.", // <meta description>, og:description
|
|
35
|
+
logo: "/logo.svg", // header mark; also default favicon
|
|
36
|
+
favicon: "/favicon.ico", // browser tab icon
|
|
37
|
+
|
|
38
|
+
// Optional: content selection
|
|
39
|
+
exclude: "docs/drafts/**", // string | string[]
|
|
40
|
+
|
|
41
|
+
// Optional: syntax themes (Shiki)
|
|
42
|
+
codeThemeLight: "catppuccin-latte", // default
|
|
43
|
+
codeThemeDark: "catppuccin-mocha", // default
|
|
44
|
+
|
|
45
|
+
// Optional: navigation
|
|
46
|
+
links: [{ url: "https://github.com/x/y", title: "GitHub", icon: "github" }],
|
|
47
|
+
|
|
48
|
+
// Optional: sections
|
|
49
|
+
sections: [
|
|
50
|
+
{ title: "Docs", prefix: "/" },
|
|
51
|
+
{ title: "Blog", prefix: "/blog/", type: "blog" },
|
|
52
|
+
{
|
|
53
|
+
title: "Changelog",
|
|
54
|
+
prefix: "/changelog/",
|
|
55
|
+
type: "changelog",
|
|
56
|
+
source: "CHANGELOG.md",
|
|
57
|
+
version: true,
|
|
58
|
+
},
|
|
59
|
+
],
|
|
60
|
+
|
|
61
|
+
// Optional: per-file frontmatter overrides
|
|
62
|
+
patches: [
|
|
63
|
+
{ file: "README.md", article: { title: "Overview", icon: "sparkles" } },
|
|
64
|
+
],
|
|
65
|
+
})
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
## Sections: the three types
|
|
69
|
+
|
|
70
|
+
`sections` is optional. Omitting it gives a single default docs section.
|
|
71
|
+
|
|
72
|
+
- **Article** (default when `type` is omitted): flat docs with a tree sidebar.
|
|
73
|
+
- **Blog** (`type: "blog"`): auto-generated index at `prefix`, sorts by `date`, exposes `/prefix/tags/<tag>/` pages.
|
|
74
|
+
- **Changelog** (`type: "changelog"`): reads `source` file; with `version: true`, splits on semver headings into per-version articles.
|
|
75
|
+
|
|
76
|
+
Shared fields on every section: `title`, `prefix` (keep trailing-slashed), `type`, `icon` (lucide), `position` (`"header"` default, `"sidebar"` also available).
|
|
77
|
+
|
|
78
|
+
Article-to-section matching is longest-prefix-wins on the article's URL `path`.
|
|
79
|
+
|
|
80
|
+
## Links
|
|
81
|
+
|
|
82
|
+
```ts
|
|
83
|
+
{
|
|
84
|
+
url: "https://example.com",
|
|
85
|
+
title: "Example",
|
|
86
|
+
icon: "github", // lucide name, kebab-case
|
|
87
|
+
position: "header", // or "sidebar"
|
|
88
|
+
prefix: "/blog/", // optional: only show in this section
|
|
89
|
+
}
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
Default `position` is `"header"`. Use `prefix` to scope a sidebar link to a single section.
|
|
93
|
+
|
|
94
|
+
## Syntax themes
|
|
95
|
+
|
|
96
|
+
Any [Shiki theme](https://shiki.style/themes) name works. Defaults keep the catppuccin pairing. If you swap the light theme, audit code-block token contrast against the theme's background (WCAG AA wants 4.5:1).
|
|
97
|
+
|
|
98
|
+
## Editing rules of thumb
|
|
99
|
+
|
|
100
|
+
1. **Don't invent fields.** Livemark's `UserConfig` is a strict zod schema. Unknown keys throw at config load.
|
|
101
|
+
2. **Strings are literals.** Section `prefix` values are compared exactly; keep them consistent (`/blog/`, not `/blog`).
|
|
102
|
+
3. **Array order matters** for `sections` and `links` — it drives tab / link display order.
|
|
103
|
+
4. **Patches are silent on miss.** If `file` doesn't match any included article, nothing happens (no warning). Spell the path carefully.
|
|
104
|
+
|
|
105
|
+
## Autoreload
|
|
106
|
+
|
|
107
|
+
The dev server watches `livemark.config.ts` and restarts on edit. No need to kill `pnpm docs:start` after tweaking the config.
|
|
108
|
+
|
|
109
|
+
## Verification
|
|
110
|
+
|
|
111
|
+
- `pnpm type` — catches schema mismatches.
|
|
112
|
+
- `pnpm docs:build` — prerenders with the new config; the output listing shows whether section routes resolved.
|
|
113
|
+
|
|
114
|
+
## References
|
|
115
|
+
|
|
116
|
+
- Config schema: `models/config.ts`.
|
|
117
|
+
- Section variants: `models/section.ts`.
|
|
118
|
+
- Link shape: `models/link.ts`.
|
|
119
|
+
- Patch shape: `models/patch.ts`.
|
|
120
|
+
- Narrative docs: `docs/customization/`.
|
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: livemark-customization
|
|
3
|
+
description: Use when overriding Livemark's built-in UI or adding custom routes — drop same-named files under .livemark/{components,elements,styles} to shadow defaults, author .livemark/routes/*.tsx for new pages, or copy defaults with the `livemark escape` command.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Livemark Customization
|
|
7
|
+
|
|
8
|
+
Guidance for customizing the UI layer of a Livemark project beyond what `livemark.config.ts` exposes.
|
|
9
|
+
|
|
10
|
+
## When to use this skill
|
|
11
|
+
|
|
12
|
+
Invoke when the user asks to:
|
|
13
|
+
|
|
14
|
+
- Change a built-in component's layout or markup (Footer, Sidebar, Banner, …).
|
|
15
|
+
- Restyle a shared primitive (buttons, inputs, cards, sheet, …).
|
|
16
|
+
- Rebrand via CSS tokens (colors, radii, typography).
|
|
17
|
+
- Add a brand-new page that isn't a Markdown article (landing hero, pricing page, about page).
|
|
18
|
+
- Replace Livemark's default landing page with a custom React component.
|
|
19
|
+
- Serve a custom `favicon.svg`, `robots.txt`, `og-image.png`, or other static asset.
|
|
20
|
+
|
|
21
|
+
## Three overlapping mechanisms
|
|
22
|
+
|
|
23
|
+
| Goal | Mechanism |
|
|
24
|
+
| --------------------------------- | ----------------------------------------------------- |
|
|
25
|
+
| Replace a default component/style | Drop a file at `.livemark/components/<Name>.tsx` etc. |
|
|
26
|
+
| Add a new page at an exact URL | Create `.livemark/routes/<path>.tsx` |
|
|
27
|
+
| Serve a static asset at `/<path>` | Put the file in `.livemark/public/<path>` |
|
|
28
|
+
|
|
29
|
+
None require config changes. The Vite plugin (`website/plugins/vite-livemark.ts`) watches `.livemark/**` and hot-reloads.
|
|
30
|
+
|
|
31
|
+
## Discovering what's overridable
|
|
32
|
+
|
|
33
|
+
Run the `escape` command. No arg lists every overridable file:
|
|
34
|
+
|
|
35
|
+
```bash
|
|
36
|
+
livemark escape
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
Output is a flat `<subdir>/<file>` list across `components/`, `elements/`, and `styles/`. With an argument, the command copies the default into `.livemark/`:
|
|
40
|
+
|
|
41
|
+
```bash
|
|
42
|
+
livemark escape components/Footer.tsx # → .livemark/components/Footer.tsx
|
|
43
|
+
livemark escape elements/button.tsx # → .livemark/elements/button.tsx
|
|
44
|
+
livemark escape styles/general.css # → .livemark/styles/general.css
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
The command refuses to overwrite an existing override. Delete the override first if you want a fresh start.
|
|
48
|
+
|
|
49
|
+
## Typical workflow: override a component
|
|
50
|
+
|
|
51
|
+
1. `livemark escape components/Footer.tsx` — copy the default.
|
|
52
|
+
2. Edit `.livemark/components/Footer.tsx`. All the site's Footer renders shift to the new file on save.
|
|
53
|
+
3. Inside the override, import other Livemark modules from the `livemark/<subdir>/*` subpath exports:
|
|
54
|
+
```tsx
|
|
55
|
+
import { cn } from "livemark/helpers/style"
|
|
56
|
+
import { Button } from "livemark/elements/button"
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
## Typical workflow: rebrand
|
|
60
|
+
|
|
61
|
+
1. `livemark escape styles/general.css`.
|
|
62
|
+
2. Edit the `:root` and `.dark` blocks in `.livemark/styles/general.css`:
|
|
63
|
+
- `--primary` — brand accent (Tailwind-flavoured oklch values work).
|
|
64
|
+
- `--radius` — corner roundness base.
|
|
65
|
+
- Sidebar / chart tokens if you want deeper tweaks.
|
|
66
|
+
3. Save — the dev server applies immediately.
|
|
67
|
+
|
|
68
|
+
Whole-site contrast is audited: light mode targets blue-600, dark mode targets blue-500. Keep new token values AA-compliant on both backgrounds (≥4.5:1 for text).
|
|
69
|
+
|
|
70
|
+
## Typical workflow: add a page
|
|
71
|
+
|
|
72
|
+
Custom routes use [TanStack Router](https://tanstack.com/router). Minimal example:
|
|
73
|
+
|
|
74
|
+
```tsx title=".livemark/routes/about.tsx"
|
|
75
|
+
import { createFileRoute } from "@tanstack/react-router"
|
|
76
|
+
|
|
77
|
+
export const Route = createFileRoute("/about")({
|
|
78
|
+
component: () => (
|
|
79
|
+
<main className="mx-auto max-w-3xl px-6 py-16 prose">
|
|
80
|
+
<h1>About</h1>
|
|
81
|
+
<p>Hello.</p>
|
|
82
|
+
</main>
|
|
83
|
+
),
|
|
84
|
+
})
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
Filename maps to URL path: `.livemark/routes/pricing.tsx` → `/pricing/`. Nested paths work via nested folders.
|
|
88
|
+
|
|
89
|
+
An `index.tsx` in `.livemark/routes/` **replaces** Livemark's default landing at `/`.
|
|
90
|
+
|
|
91
|
+
Custom routes win over the Markdown catch-all at exact URLs. Don't create a route that collides with an article URL unless you intend to hide the article.
|
|
92
|
+
|
|
93
|
+
## Rules of thumb
|
|
94
|
+
|
|
95
|
+
1. **Don't fork the repo** for routine customization. Use `.livemark/` first — it reliably survives Livemark upgrades.
|
|
96
|
+
2. **Same filename, same path under `.livemark/`.** The override plugin is case-sensitive and mirrors the subdirectory structure exactly.
|
|
97
|
+
3. **Override files are full replacements**, not diffs. Copy the default first (via `escape`), then edit.
|
|
98
|
+
4. **Import Livemark internals via `livemark/*`**, not via relative paths — the plugin routes those through the override resolver, so chained overrides (e.g., your Layout using your Sidebar) compose correctly.
|
|
99
|
+
5. **Static files belong in `.livemark/public/`**, which Vite exposes at the site root.
|
|
100
|
+
|
|
101
|
+
## What's NOT overridable
|
|
102
|
+
|
|
103
|
+
- `actions/`, `commands/`, `program.ts` — server/CLI code. Fork upstream if you need to change these.
|
|
104
|
+
- `livemark.config.ts` schema — fixed.
|
|
105
|
+
- Content-collections transform pipeline. Customize markdown via remark/rehype plugins in a fork (or PR upstream).
|
|
106
|
+
|
|
107
|
+
## Verification
|
|
108
|
+
|
|
109
|
+
- `pnpm type` — confirms overrides typecheck.
|
|
110
|
+
- `pnpm docs:build` — smoke-test the override lands in the bundle.
|
|
111
|
+
- Browser: load an article page with the dev server; custom Footer/Sidebar/etc. should render without a full reload.
|
|
112
|
+
|
|
113
|
+
## References
|
|
114
|
+
|
|
115
|
+
- Narrative docs: `docs/customization/file-overrides.md`, `docs/customization/custom-routes.md`.
|
|
116
|
+
- Plugin implementation: `website/plugins/vite-livemark.ts`.
|
|
117
|
+
- Escape command: `commands/escape.ts`.
|
|
118
|
+
- Subpath exports: `package.json` `exports` block.
|
|
@@ -1,4 +0,0 @@
|
|
|
1
|
-
export { loadDescriptor } from "./load.js";
|
|
2
|
-
export { saveDescriptor } from "./save.js";
|
|
3
|
-
export { validateDescriptor } from "./validate.js";
|
|
4
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9kZXNjcmlwdG9yL2luZGV4LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSxjQUFjLEVBQUUsTUFBTSxXQUFXLENBQUE7QUFDMUMsT0FBTyxFQUFFLGNBQWMsRUFBRSxNQUFNLFdBQVcsQ0FBQTtBQUMxQyxPQUFPLEVBQUUsa0JBQWtCLEVBQUUsTUFBTSxlQUFlLENBQUEiLCJzb3VyY2VzQ29udGVudCI6WyJleHBvcnQgeyBsb2FkRGVzY3JpcHRvciB9IGZyb20gXCIuL2xvYWQuanNcIlxuZXhwb3J0IHsgc2F2ZURlc2NyaXB0b3IgfSBmcm9tIFwiLi9zYXZlLmpzXCJcbmV4cG9ydCB7IHZhbGlkYXRlRGVzY3JpcHRvciB9IGZyb20gXCIuL3ZhbGlkYXRlLmpzXCJcbiJdfQ==
|
|
@@ -1,8 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Load a descriptor (JSON Object) from a file or URL
|
|
3
|
-
* Uses dynamic imports to work in both Node.js and browser environments
|
|
4
|
-
* Supports HTTP, HTTPS, FTP, and FTPS protocols
|
|
5
|
-
*/
|
|
6
|
-
export declare function loadDescriptor(props: {
|
|
7
|
-
path: string;
|
|
8
|
-
}): Promise<Record<string, any>>;
|
package/build/descriptor/load.js
DELETED
|
@@ -1,40 +0,0 @@
|
|
|
1
|
-
import { loadNodeApis } from "./node.js";
|
|
2
|
-
/**
|
|
3
|
-
* Load a descriptor (JSON Object) from a file or URL
|
|
4
|
-
* Uses dynamic imports to work in both Node.js and browser environments
|
|
5
|
-
* Supports HTTP, HTTPS, FTP, and FTPS protocols
|
|
6
|
-
*/
|
|
7
|
-
export async function loadDescriptor(props) {
|
|
8
|
-
const url = createRemoteUrl(props.path);
|
|
9
|
-
return url
|
|
10
|
-
? await loadRemoteDescriptor(url)
|
|
11
|
-
: await loadLocalDescriptor(props.path);
|
|
12
|
-
}
|
|
13
|
-
function createRemoteUrl(path) {
|
|
14
|
-
try {
|
|
15
|
-
return new URL(path);
|
|
16
|
-
}
|
|
17
|
-
catch {
|
|
18
|
-
return undefined;
|
|
19
|
-
}
|
|
20
|
-
}
|
|
21
|
-
const REMOTE_PROTOCOLS = ["http:", "https:", "ftp:", "ftps:"];
|
|
22
|
-
async function loadRemoteDescriptor(url) {
|
|
23
|
-
const protocol = url.protocol.toLowerCase();
|
|
24
|
-
if (!REMOTE_PROTOCOLS.includes(protocol)) {
|
|
25
|
-
throw new Error(`Unsupported URL protocol: ${protocol}`);
|
|
26
|
-
}
|
|
27
|
-
const response = await fetch(url.toString());
|
|
28
|
-
const descriptor = (await response.json());
|
|
29
|
-
return descriptor;
|
|
30
|
-
}
|
|
31
|
-
async function loadLocalDescriptor(path) {
|
|
32
|
-
const node = await loadNodeApis();
|
|
33
|
-
if (!node) {
|
|
34
|
-
throw new Error("File system is not supported in this environment");
|
|
35
|
-
}
|
|
36
|
-
const content = await node.fs.readFile(path, "utf-8");
|
|
37
|
-
const descriptor = JSON.parse(content);
|
|
38
|
-
return descriptor;
|
|
39
|
-
}
|
|
40
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibG9hZC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL2Rlc2NyaXB0b3IvbG9hZC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUUsWUFBWSxFQUFFLE1BQU0sV0FBVyxDQUFBO0FBRXhDOzs7O0dBSUc7QUFDSCxNQUFNLENBQUMsS0FBSyxVQUFVLGNBQWMsQ0FBQyxLQUF1QjtJQUMxRCxNQUFNLEdBQUcsR0FBRyxlQUFlLENBQUMsS0FBSyxDQUFDLElBQUksQ0FBQyxDQUFBO0lBRXZDLE9BQU8sR0FBRztRQUNSLENBQUMsQ0FBQyxNQUFNLG9CQUFvQixDQUFDLEdBQUcsQ0FBQztRQUNqQyxDQUFDLENBQUMsTUFBTSxtQkFBbUIsQ0FBQyxLQUFLLENBQUMsSUFBSSxDQUFDLENBQUE7QUFDM0MsQ0FBQztBQUVELFNBQVMsZUFBZSxDQUFDLElBQVk7SUFDbkMsSUFBSSxDQUFDO1FBQ0gsT0FBTyxJQUFJLEdBQUcsQ0FBQyxJQUFJLENBQUMsQ0FBQTtJQUN0QixDQUFDO0lBQUMsTUFBTSxDQUFDO1FBQ1AsT0FBTyxTQUFTLENBQUE7SUFDbEIsQ0FBQztBQUNILENBQUM7QUFFRCxNQUFNLGdCQUFnQixHQUFHLENBQUMsT0FBTyxFQUFFLFFBQVEsRUFBRSxNQUFNLEVBQUUsT0FBTyxDQUFDLENBQUE7QUFFN0QsS0FBSyxVQUFVLG9CQUFvQixDQUFDLEdBQVE7SUFDMUMsTUFBTSxRQUFRLEdBQUcsR0FBRyxDQUFDLFFBQVEsQ0FBQyxXQUFXLEVBQUUsQ0FBQTtJQUMzQyxJQUFJLENBQUMsZ0JBQWdCLENBQUMsUUFBUSxDQUFDLFFBQVEsQ0FBQyxFQUFFLENBQUM7UUFDekMsTUFBTSxJQUFJLEtBQUssQ0FBQyw2QkFBNkIsUUFBUSxFQUFFLENBQUMsQ0FBQTtJQUMxRCxDQUFDO0lBRUQsTUFBTSxRQUFRLEdBQUcsTUFBTSxLQUFLLENBQUMsR0FBRyxDQUFDLFFBQVEsRUFBRSxDQUFDLENBQUE7SUFDNUMsTUFBTSxVQUFVLEdBQUcsQ0FBQyxNQUFNLFFBQVEsQ0FBQyxJQUFJLEVBQUUsQ0FBd0IsQ0FBQTtJQUVqRSxPQUFPLFVBQVUsQ0FBQTtBQUNuQixDQUFDO0FBRUQsS0FBSyxVQUFVLG1CQUFtQixDQUFDLElBQVk7SUFDN0MsTUFBTSxJQUFJLEdBQUcsTUFBTSxZQUFZLEVBQUUsQ0FBQTtJQUNqQyxJQUFJLENBQUMsSUFBSSxFQUFFLENBQUM7UUFDVixNQUFNLElBQUksS0FBSyxDQUFDLGtEQUFrRCxDQUFDLENBQUE7SUFDckUsQ0FBQztJQUVELE1BQU0sT0FBTyxHQUFHLE1BQU0sSUFBSSxDQUFDLEVBQUUsQ0FBQyxRQUFRLENBQUMsSUFBSSxFQUFFLE9BQU8sQ0FBQyxDQUFBO0lBQ3JELE1BQU0sVUFBVSxHQUFHLElBQUksQ0FBQyxLQUFLLENBQUMsT0FBTyxDQUF3QixDQUFBO0lBRTdELE9BQU8sVUFBVSxDQUFBO0FBQ25CLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBsb2FkTm9kZUFwaXMgfSBmcm9tIFwiLi9ub2RlLmpzXCJcblxuLyoqXG4gKiBMb2FkIGEgZGVzY3JpcHRvciAoSlNPTiBPYmplY3QpIGZyb20gYSBmaWxlIG9yIFVSTFxuICogVXNlcyBkeW5hbWljIGltcG9ydHMgdG8gd29yayBpbiBib3RoIE5vZGUuanMgYW5kIGJyb3dzZXIgZW52aXJvbm1lbnRzXG4gKiBTdXBwb3J0cyBIVFRQLCBIVFRQUywgRlRQLCBhbmQgRlRQUyBwcm90b2NvbHNcbiAqL1xuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIGxvYWREZXNjcmlwdG9yKHByb3BzOiB7IHBhdGg6IHN0cmluZyB9KSB7XG4gIGNvbnN0IHVybCA9IGNyZWF0ZVJlbW90ZVVybChwcm9wcy5wYXRoKVxuXG4gIHJldHVybiB1cmxcbiAgICA/IGF3YWl0IGxvYWRSZW1vdGVEZXNjcmlwdG9yKHVybClcbiAgICA6IGF3YWl0IGxvYWRMb2NhbERlc2NyaXB0b3IocHJvcHMucGF0aClcbn1cblxuZnVuY3Rpb24gY3JlYXRlUmVtb3RlVXJsKHBhdGg6IHN0cmluZykge1xuICB0cnkge1xuICAgIHJldHVybiBuZXcgVVJMKHBhdGgpXG4gIH0gY2F0Y2gge1xuICAgIHJldHVybiB1bmRlZmluZWRcbiAgfVxufVxuXG5jb25zdCBSRU1PVEVfUFJPVE9DT0xTID0gW1wiaHR0cDpcIiwgXCJodHRwczpcIiwgXCJmdHA6XCIsIFwiZnRwczpcIl1cblxuYXN5bmMgZnVuY3Rpb24gbG9hZFJlbW90ZURlc2NyaXB0b3IodXJsOiBVUkwpIHtcbiAgY29uc3QgcHJvdG9jb2wgPSB1cmwucHJvdG9jb2wudG9Mb3dlckNhc2UoKVxuICBpZiAoIVJFTU9URV9QUk9UT0NPTFMuaW5jbHVkZXMocHJvdG9jb2wpKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKGBVbnN1cHBvcnRlZCBVUkwgcHJvdG9jb2w6ICR7cHJvdG9jb2x9YClcbiAgfVxuXG4gIGNvbnN0IHJlc3BvbnNlID0gYXdhaXQgZmV0Y2godXJsLnRvU3RyaW5nKCkpXG4gIGNvbnN0IGRlc2NyaXB0b3IgPSAoYXdhaXQgcmVzcG9uc2UuanNvbigpKSBhcyBSZWNvcmQ8c3RyaW5nLCBhbnk+XG5cbiAgcmV0dXJuIGRlc2NyaXB0b3Jcbn1cblxuYXN5bmMgZnVuY3Rpb24gbG9hZExvY2FsRGVzY3JpcHRvcihwYXRoOiBzdHJpbmcpIHtcbiAgY29uc3Qgbm9kZSA9IGF3YWl0IGxvYWROb2RlQXBpcygpXG4gIGlmICghbm9kZSkge1xuICAgIHRocm93IG5ldyBFcnJvcihcIkZpbGUgc3lzdGVtIGlzIG5vdCBzdXBwb3J0ZWQgaW4gdGhpcyBlbnZpcm9ubWVudFwiKVxuICB9XG5cbiAgY29uc3QgY29udGVudCA9IGF3YWl0IG5vZGUuZnMucmVhZEZpbGUocGF0aCwgXCJ1dGYtOFwiKVxuICBjb25zdCBkZXNjcmlwdG9yID0gSlNPTi5wYXJzZShjb250ZW50KSBhcyBSZWNvcmQ8c3RyaW5nLCBhbnk+XG5cbiAgcmV0dXJuIGRlc2NyaXB0b3Jcbn1cbiJdfQ==
|
|
@@ -1,125 +0,0 @@
|
|
|
1
|
-
export declare function loadNodeApis(): Promise<{
|
|
2
|
-
fs: {
|
|
3
|
-
default: typeof import("node:fs/promises");
|
|
4
|
-
access(path: import("fs").PathLike, mode?: number): Promise<void>;
|
|
5
|
-
copyFile(src: import("fs").PathLike, dest: import("fs").PathLike, mode?: number): Promise<void>;
|
|
6
|
-
open(path: import("fs").PathLike, flags?: string | number, mode?: import("fs").Mode): Promise<import("fs/promises").FileHandle>;
|
|
7
|
-
rename(oldPath: import("fs").PathLike, newPath: import("fs").PathLike): Promise<void>;
|
|
8
|
-
truncate(path: import("fs").PathLike, len?: number): Promise<void>;
|
|
9
|
-
rmdir(path: import("fs").PathLike, options?: import("fs").RmDirOptions): Promise<void>;
|
|
10
|
-
rm(path: import("fs").PathLike, options?: import("fs").RmOptions): Promise<void>;
|
|
11
|
-
mkdir(path: import("fs").PathLike, options: import("fs").MakeDirectoryOptions & {
|
|
12
|
-
recursive: true;
|
|
13
|
-
}): Promise<string | undefined>;
|
|
14
|
-
mkdir(path: import("fs").PathLike, options?: import("fs").Mode | (import("fs").MakeDirectoryOptions & {
|
|
15
|
-
recursive?: false | undefined;
|
|
16
|
-
}) | null): Promise<void>;
|
|
17
|
-
mkdir(path: import("fs").PathLike, options?: import("fs").Mode | import("fs").MakeDirectoryOptions | null): Promise<string | undefined>;
|
|
18
|
-
readdir(path: import("fs").PathLike, options?: (import("fs").ObjectEncodingOptions & {
|
|
19
|
-
withFileTypes?: false | undefined;
|
|
20
|
-
recursive?: boolean | undefined;
|
|
21
|
-
}) | BufferEncoding | null): Promise<string[]>;
|
|
22
|
-
readdir(path: import("fs").PathLike, options: {
|
|
23
|
-
encoding: "buffer";
|
|
24
|
-
withFileTypes?: false | undefined;
|
|
25
|
-
recursive?: boolean | undefined;
|
|
26
|
-
} | "buffer"): Promise<Buffer[]>;
|
|
27
|
-
readdir(path: import("fs").PathLike, options?: (import("fs").ObjectEncodingOptions & {
|
|
28
|
-
withFileTypes?: false | undefined;
|
|
29
|
-
recursive?: boolean | undefined;
|
|
30
|
-
}) | BufferEncoding | null): Promise<string[] | Buffer[]>;
|
|
31
|
-
readdir(path: import("fs").PathLike, options: import("fs").ObjectEncodingOptions & {
|
|
32
|
-
withFileTypes: true;
|
|
33
|
-
recursive?: boolean | undefined;
|
|
34
|
-
}): Promise<import("fs").Dirent[]>;
|
|
35
|
-
readlink(path: import("fs").PathLike, options?: import("fs").ObjectEncodingOptions | BufferEncoding | null): Promise<string>;
|
|
36
|
-
readlink(path: import("fs").PathLike, options: import("fs").BufferEncodingOption): Promise<Buffer>;
|
|
37
|
-
readlink(path: import("fs").PathLike, options?: import("fs").ObjectEncodingOptions | string | null): Promise<string | Buffer>;
|
|
38
|
-
symlink(target: import("fs").PathLike, path: import("fs").PathLike, type?: string | null): Promise<void>;
|
|
39
|
-
lstat(path: import("fs").PathLike, opts?: import("fs").StatOptions & {
|
|
40
|
-
bigint?: false | undefined;
|
|
41
|
-
}): Promise<import("fs").Stats>;
|
|
42
|
-
lstat(path: import("fs").PathLike, opts: import("fs").StatOptions & {
|
|
43
|
-
bigint: true;
|
|
44
|
-
}): Promise<import("fs").BigIntStats>;
|
|
45
|
-
lstat(path: import("fs").PathLike, opts?: import("fs").StatOptions): Promise<import("fs").Stats | import("fs").BigIntStats>;
|
|
46
|
-
stat(path: import("fs").PathLike, opts?: import("fs").StatOptions & {
|
|
47
|
-
bigint?: false | undefined;
|
|
48
|
-
}): Promise<import("fs").Stats>;
|
|
49
|
-
stat(path: import("fs").PathLike, opts: import("fs").StatOptions & {
|
|
50
|
-
bigint: true;
|
|
51
|
-
}): Promise<import("fs").BigIntStats>;
|
|
52
|
-
stat(path: import("fs").PathLike, opts?: import("fs").StatOptions): Promise<import("fs").Stats | import("fs").BigIntStats>;
|
|
53
|
-
statfs(path: import("fs").PathLike, opts?: import("fs").StatFsOptions & {
|
|
54
|
-
bigint?: false | undefined;
|
|
55
|
-
}): Promise<import("fs").StatsFs>;
|
|
56
|
-
statfs(path: import("fs").PathLike, opts: import("fs").StatFsOptions & {
|
|
57
|
-
bigint: true;
|
|
58
|
-
}): Promise<import("fs").BigIntStatsFs>;
|
|
59
|
-
statfs(path: import("fs").PathLike, opts?: import("fs").StatFsOptions): Promise<import("fs").StatsFs | import("fs").BigIntStatsFs>;
|
|
60
|
-
link(existingPath: import("fs").PathLike, newPath: import("fs").PathLike): Promise<void>;
|
|
61
|
-
unlink(path: import("fs").PathLike): Promise<void>;
|
|
62
|
-
chmod(path: import("fs").PathLike, mode: import("fs").Mode): Promise<void>;
|
|
63
|
-
lchmod(path: import("fs").PathLike, mode: import("fs").Mode): Promise<void>;
|
|
64
|
-
lchown(path: import("fs").PathLike, uid: number, gid: number): Promise<void>;
|
|
65
|
-
lutimes(path: import("fs").PathLike, atime: import("fs").TimeLike, mtime: import("fs").TimeLike): Promise<void>;
|
|
66
|
-
chown(path: import("fs").PathLike, uid: number, gid: number): Promise<void>;
|
|
67
|
-
utimes(path: import("fs").PathLike, atime: import("fs").TimeLike, mtime: import("fs").TimeLike): Promise<void>;
|
|
68
|
-
realpath(path: import("fs").PathLike, options?: import("fs").ObjectEncodingOptions | BufferEncoding | null): Promise<string>;
|
|
69
|
-
realpath(path: import("fs").PathLike, options: import("fs").BufferEncodingOption): Promise<Buffer>;
|
|
70
|
-
realpath(path: import("fs").PathLike, options?: import("fs").ObjectEncodingOptions | BufferEncoding | null): Promise<string | Buffer>;
|
|
71
|
-
mkdtemp(prefix: string, options?: import("fs").ObjectEncodingOptions | BufferEncoding | null): Promise<string>;
|
|
72
|
-
mkdtemp(prefix: string, options: import("fs").BufferEncodingOption): Promise<Buffer>;
|
|
73
|
-
mkdtemp(prefix: string, options?: import("fs").ObjectEncodingOptions | BufferEncoding | null): Promise<string | Buffer>;
|
|
74
|
-
writeFile(file: import("fs").PathLike | import("fs/promises").FileHandle, data: string | NodeJS.ArrayBufferView | Iterable<string | NodeJS.ArrayBufferView> | AsyncIterable<string | NodeJS.ArrayBufferView> | import("stream"), options?: (import("fs").ObjectEncodingOptions & {
|
|
75
|
-
mode?: import("fs").Mode | undefined;
|
|
76
|
-
flag?: import("fs").OpenMode | undefined;
|
|
77
|
-
flush?: boolean | undefined;
|
|
78
|
-
} & import("events").Abortable) | BufferEncoding | null): Promise<void>;
|
|
79
|
-
appendFile(path: import("fs").PathLike | import("fs/promises").FileHandle, data: string | Uint8Array, options?: (import("fs").ObjectEncodingOptions & import("fs/promises").FlagAndOpenMode & {
|
|
80
|
-
flush?: boolean | undefined;
|
|
81
|
-
}) | BufferEncoding | null): Promise<void>;
|
|
82
|
-
readFile(path: import("fs").PathLike | import("fs/promises").FileHandle, options?: ({
|
|
83
|
-
encoding?: null | undefined;
|
|
84
|
-
flag?: import("fs").OpenMode | undefined;
|
|
85
|
-
} & import("events").Abortable) | null): Promise<Buffer>;
|
|
86
|
-
readFile(path: import("fs").PathLike | import("fs/promises").FileHandle, options: ({
|
|
87
|
-
encoding: BufferEncoding;
|
|
88
|
-
flag?: import("fs").OpenMode | undefined;
|
|
89
|
-
} & import("events").Abortable) | BufferEncoding): Promise<string>;
|
|
90
|
-
readFile(path: import("fs").PathLike | import("fs/promises").FileHandle, options?: (import("fs").ObjectEncodingOptions & import("events").Abortable & {
|
|
91
|
-
flag?: import("fs").OpenMode | undefined;
|
|
92
|
-
}) | BufferEncoding | null): Promise<string | Buffer>;
|
|
93
|
-
opendir(path: import("fs").PathLike, options?: import("fs").OpenDirOptions): Promise<import("fs").Dir>;
|
|
94
|
-
watch(filename: import("fs").PathLike, options: (import("fs").WatchOptions & {
|
|
95
|
-
encoding: "buffer";
|
|
96
|
-
}) | "buffer"): AsyncIterable<import("fs/promises").FileChangeInfo<Buffer>>;
|
|
97
|
-
watch(filename: import("fs").PathLike, options?: import("fs").WatchOptions | BufferEncoding): AsyncIterable<import("fs/promises").FileChangeInfo<string>>;
|
|
98
|
-
watch(filename: import("fs").PathLike, options: import("fs").WatchOptions | string): AsyncIterable<import("fs/promises").FileChangeInfo<string>> | AsyncIterable<import("fs/promises").FileChangeInfo<Buffer>>;
|
|
99
|
-
cp(source: string | URL, destination: string | URL, opts?: import("fs").CopyOptions): Promise<void>;
|
|
100
|
-
glob(pattern: string | string[]): NodeJS.AsyncIterator<string>;
|
|
101
|
-
glob(pattern: string | string[], opt: import("fs").GlobOptionsWithFileTypes): NodeJS.AsyncIterator<import("fs").Dirent>;
|
|
102
|
-
glob(pattern: string | string[], opt: import("fs").GlobOptionsWithoutFileTypes): NodeJS.AsyncIterator<string>;
|
|
103
|
-
glob(pattern: string | string[], opt: import("fs").GlobOptions): NodeJS.AsyncIterator<import("fs").Dirent | string>;
|
|
104
|
-
constants: typeof import("fs").constants;
|
|
105
|
-
};
|
|
106
|
-
path: {
|
|
107
|
-
default: import("path").PlatformPath;
|
|
108
|
-
normalize(path: string): string;
|
|
109
|
-
join(...paths: string[]): string;
|
|
110
|
-
resolve(...paths: string[]): string;
|
|
111
|
-
matchesGlob(path: string, pattern: string): boolean;
|
|
112
|
-
isAbsolute(path: string): boolean;
|
|
113
|
-
relative(from: string, to: string): string;
|
|
114
|
-
dirname(path: string): string;
|
|
115
|
-
basename(path: string, suffix?: string): string;
|
|
116
|
-
extname(path: string): string;
|
|
117
|
-
sep: "\\" | "/";
|
|
118
|
-
delimiter: ";" | ":";
|
|
119
|
-
parse(path: string): import("path").ParsedPath;
|
|
120
|
-
format(pathObject: import("path").FormatInputPathObject): string;
|
|
121
|
-
toNamespacedPath(path: string): string;
|
|
122
|
-
posix: import("path").PlatformPath;
|
|
123
|
-
win32: import("path").PlatformPath;
|
|
124
|
-
};
|
|
125
|
-
} | undefined>;
|
package/build/descriptor/node.js
DELETED
|
@@ -1,9 +0,0 @@
|
|
|
1
|
-
export async function loadNodeApis() {
|
|
2
|
-
if (globalThis.process) {
|
|
3
|
-
const fs = await import("node:fs/promises");
|
|
4
|
-
const path = await import("node:path");
|
|
5
|
-
return { fs, path };
|
|
6
|
-
}
|
|
7
|
-
return undefined;
|
|
8
|
-
}
|
|
9
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibm9kZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL2Rlc2NyaXB0b3Ivbm9kZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxNQUFNLENBQUMsS0FBSyxVQUFVLFlBQVk7SUFDaEMsSUFBSSxVQUFVLENBQUMsT0FBTyxFQUFFLENBQUM7UUFDdkIsTUFBTSxFQUFFLEdBQUcsTUFBTSxNQUFNLENBQUMsa0JBQWtCLENBQUMsQ0FBQTtRQUMzQyxNQUFNLElBQUksR0FBRyxNQUFNLE1BQU0sQ0FBQyxXQUFXLENBQUMsQ0FBQTtRQUN0QyxPQUFPLEVBQUUsRUFBRSxFQUFFLElBQUksRUFBRSxDQUFBO0lBQ3JCLENBQUM7SUFFRCxPQUFPLFNBQVMsQ0FBQTtBQUNsQixDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIGxvYWROb2RlQXBpcygpIHtcbiAgaWYgKGdsb2JhbFRoaXMucHJvY2Vzcykge1xuICAgIGNvbnN0IGZzID0gYXdhaXQgaW1wb3J0KFwibm9kZTpmcy9wcm9taXNlc1wiKVxuICAgIGNvbnN0IHBhdGggPSBhd2FpdCBpbXBvcnQoXCJub2RlOnBhdGhcIilcbiAgICByZXR1cm4geyBmcywgcGF0aCB9XG4gIH1cblxuICByZXR1cm4gdW5kZWZpbmVkXG59XG4iXX0=
|
package/build/descriptor/save.js
DELETED
|
@@ -1,17 +0,0 @@
|
|
|
1
|
-
import { loadNodeApis } from "./node.js";
|
|
2
|
-
/**
|
|
3
|
-
* Save a descriptor (JSON Object) to a file path
|
|
4
|
-
* Works in Node.js environments
|
|
5
|
-
*/
|
|
6
|
-
export async function saveDescriptor(props) {
|
|
7
|
-
const { descriptor, path } = props;
|
|
8
|
-
const node = await loadNodeApis();
|
|
9
|
-
if (!node) {
|
|
10
|
-
throw new Error("File system is not supported in this environment");
|
|
11
|
-
}
|
|
12
|
-
const content = JSON.stringify(descriptor, null, 2);
|
|
13
|
-
await node.fs.mkdir(node.path.dirname(path), { recursive: true });
|
|
14
|
-
await node.fs.writeFile(path, content, "utf-8");
|
|
15
|
-
return true;
|
|
16
|
-
}
|
|
17
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic2F2ZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL2Rlc2NyaXB0b3Ivc2F2ZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUUsWUFBWSxFQUFFLE1BQU0sV0FBVyxDQUFBO0FBRXhDOzs7R0FHRztBQUNILE1BQU0sQ0FBQyxLQUFLLFVBQVUsY0FBYyxDQUFDLEtBR3BDO0lBQ0MsTUFBTSxFQUFFLFVBQVUsRUFBRSxJQUFJLEVBQUUsR0FBRyxLQUFLLENBQUE7SUFFbEMsTUFBTSxJQUFJLEdBQUcsTUFBTSxZQUFZLEVBQUUsQ0FBQTtJQUNqQyxJQUFJLENBQUMsSUFBSSxFQUFFLENBQUM7UUFDVixNQUFNLElBQUksS0FBSyxDQUFDLGtEQUFrRCxDQUFDLENBQUE7SUFDckUsQ0FBQztJQUVELE1BQU0sT0FBTyxHQUFHLElBQUksQ0FBQyxTQUFTLENBQUMsVUFBVSxFQUFFLElBQUksRUFBRSxDQUFDLENBQUMsQ0FBQTtJQUVuRCxNQUFNLElBQUksQ0FBQyxFQUFFLENBQUMsS0FBSyxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsT0FBTyxDQUFDLElBQUksQ0FBQyxFQUFFLEVBQUUsU0FBUyxFQUFFLElBQUksRUFBRSxDQUFDLENBQUE7SUFDakUsTUFBTSxJQUFJLENBQUMsRUFBRSxDQUFDLFNBQVMsQ0FBQyxJQUFJLEVBQUUsT0FBTyxFQUFFLE9BQU8sQ0FBQyxDQUFBO0lBRS9DLE9BQU8sSUFBSSxDQUFBO0FBQ2IsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IGxvYWROb2RlQXBpcyB9IGZyb20gXCIuL25vZGUuanNcIlxuXG4vKipcbiAqIFNhdmUgYSBkZXNjcmlwdG9yIChKU09OIE9iamVjdCkgdG8gYSBmaWxlIHBhdGhcbiAqIFdvcmtzIGluIE5vZGUuanMgZW52aXJvbm1lbnRzXG4gKi9cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiBzYXZlRGVzY3JpcHRvcihwcm9wczoge1xuICBkZXNjcmlwdG9yOiBSZWNvcmQ8c3RyaW5nLCBhbnk+XG4gIHBhdGg6IHN0cmluZ1xufSkge1xuICBjb25zdCB7IGRlc2NyaXB0b3IsIHBhdGggfSA9IHByb3BzXG5cbiAgY29uc3Qgbm9kZSA9IGF3YWl0IGxvYWROb2RlQXBpcygpXG4gIGlmICghbm9kZSkge1xuICAgIHRocm93IG5ldyBFcnJvcihcIkZpbGUgc3lzdGVtIGlzIG5vdCBzdXBwb3J0ZWQgaW4gdGhpcyBlbnZpcm9ubWVudFwiKVxuICB9XG5cbiAgY29uc3QgY29udGVudCA9IEpTT04uc3RyaW5naWZ5KGRlc2NyaXB0b3IsIG51bGwsIDIpXG5cbiAgYXdhaXQgbm9kZS5mcy5ta2Rpcihub2RlLnBhdGguZGlybmFtZShwYXRoKSwgeyByZWN1cnNpdmU6IHRydWUgfSlcbiAgYXdhaXQgbm9kZS5mcy53cml0ZUZpbGUocGF0aCwgY29udGVudCwgXCJ1dGYtOFwiKVxuXG4gIHJldHVybiB0cnVlXG59XG4iXX0=
|
|
@@ -1,80 +0,0 @@
|
|
|
1
|
-
import * as fs from "node:fs/promises";
|
|
2
|
-
import * as path from "node:path";
|
|
3
|
-
import { temporaryDirectory } from "tempy";
|
|
4
|
-
import { afterEach, beforeEach, describe, expect, it } from "vitest";
|
|
5
|
-
import { saveDescriptor } from "./save.js";
|
|
6
|
-
describe("saveDescriptor", () => {
|
|
7
|
-
const testDescriptor = {
|
|
8
|
-
name: "test-descriptor",
|
|
9
|
-
version: "1.0.0",
|
|
10
|
-
description: "Test descriptor for save function",
|
|
11
|
-
resources: [
|
|
12
|
-
{
|
|
13
|
-
name: "resource1",
|
|
14
|
-
path: "data/resource1.csv",
|
|
15
|
-
},
|
|
16
|
-
],
|
|
17
|
-
};
|
|
18
|
-
let testDir;
|
|
19
|
-
let testPath;
|
|
20
|
-
beforeEach(() => {
|
|
21
|
-
testDir = temporaryDirectory();
|
|
22
|
-
testPath = path.join(testDir, "descriptor.json");
|
|
23
|
-
});
|
|
24
|
-
afterEach(async () => {
|
|
25
|
-
try {
|
|
26
|
-
await fs.rm(testDir, { recursive: true, force: true });
|
|
27
|
-
}
|
|
28
|
-
catch (error) {
|
|
29
|
-
if (error instanceof Error && !error.message.includes("ENOENT")) {
|
|
30
|
-
console.error(`Failed to clean up test directory: ${testDir}`, error);
|
|
31
|
-
}
|
|
32
|
-
}
|
|
33
|
-
});
|
|
34
|
-
it("should save a descriptor to the specified path", async () => {
|
|
35
|
-
const result = await saveDescriptor({
|
|
36
|
-
descriptor: testDescriptor,
|
|
37
|
-
path: testPath,
|
|
38
|
-
});
|
|
39
|
-
expect(result).toBe(true);
|
|
40
|
-
const fileExists = await fs
|
|
41
|
-
.stat(testPath)
|
|
42
|
-
.then(() => true)
|
|
43
|
-
.catch(() => false);
|
|
44
|
-
expect(fileExists).toBe(true);
|
|
45
|
-
const content = await fs.readFile(testPath, "utf-8");
|
|
46
|
-
const parsedContent = JSON.parse(content);
|
|
47
|
-
expect(parsedContent).toEqual(testDescriptor);
|
|
48
|
-
});
|
|
49
|
-
it("should save a descriptor to a nested directory path", async () => {
|
|
50
|
-
const nestedPath = path.join(testDir, "nested", "dir", "descriptor.json");
|
|
51
|
-
const result = await saveDescriptor({
|
|
52
|
-
descriptor: testDescriptor,
|
|
53
|
-
path: nestedPath,
|
|
54
|
-
});
|
|
55
|
-
expect(result).toBe(true);
|
|
56
|
-
const fileExists = await fs
|
|
57
|
-
.stat(nestedPath)
|
|
58
|
-
.then(() => true)
|
|
59
|
-
.catch(() => false);
|
|
60
|
-
expect(fileExists).toBe(true);
|
|
61
|
-
const content = await fs.readFile(nestedPath, "utf-8");
|
|
62
|
-
const parsedContent = JSON.parse(content);
|
|
63
|
-
expect(parsedContent).toEqual(testDescriptor);
|
|
64
|
-
});
|
|
65
|
-
it("should use pretty formatting with 2-space indentation", async () => {
|
|
66
|
-
await saveDescriptor({
|
|
67
|
-
descriptor: testDescriptor,
|
|
68
|
-
path: testPath,
|
|
69
|
-
});
|
|
70
|
-
const content = await fs.readFile(testPath, "utf-8");
|
|
71
|
-
const expectedFormat = JSON.stringify(testDescriptor, null, 2);
|
|
72
|
-
expect(content).toEqual(expectedFormat);
|
|
73
|
-
const lines = content.split("\n");
|
|
74
|
-
expect(lines.length).toBeGreaterThan(1);
|
|
75
|
-
if (lines.length > 1 && lines[1]) {
|
|
76
|
-
expect(lines[1].startsWith(" ")).toBe(true);
|
|
77
|
-
}
|
|
78
|
-
});
|
|
79
|
-
});
|
|
80
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic2F2ZS5zcGVjLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vZGVzY3JpcHRvci9zYXZlLnNwZWMudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxLQUFLLEVBQUUsTUFBTSxrQkFBa0IsQ0FBQTtBQUN0QyxPQUFPLEtBQUssSUFBSSxNQUFNLFdBQVcsQ0FBQTtBQUNqQyxPQUFPLEVBQUUsa0JBQWtCLEVBQUUsTUFBTSxPQUFPLENBQUE7QUFDMUMsT0FBTyxFQUFFLFNBQVMsRUFBRSxVQUFVLEVBQUUsUUFBUSxFQUFFLE1BQU0sRUFBRSxFQUFFLEVBQUUsTUFBTSxRQUFRLENBQUE7QUFDcEUsT0FBTyxFQUFFLGNBQWMsRUFBRSxNQUFNLFdBQVcsQ0FBQTtBQUUxQyxRQUFRLENBQUMsZ0JBQWdCLEVBQUUsR0FBRyxFQUFFO0lBQzlCLE1BQU0sY0FBYyxHQUFHO1FBQ3JCLElBQUksRUFBRSxpQkFBaUI7UUFDdkIsT0FBTyxFQUFFLE9BQU87UUFDaEIsV0FBVyxFQUFFLG1DQUFtQztRQUNoRCxTQUFTLEVBQUU7WUFDVDtnQkFDRSxJQUFJLEVBQUUsV0FBVztnQkFDakIsSUFBSSxFQUFFLG9CQUFvQjthQUMzQjtTQUNGO0tBQ0YsQ0FBQTtJQUVELElBQUksT0FBZSxDQUFBO0lBQ25CLElBQUksUUFBZ0IsQ0FBQTtJQUVwQixVQUFVLENBQUMsR0FBRyxFQUFFO1FBQ2QsT0FBTyxHQUFHLGtCQUFrQixFQUFFLENBQUE7UUFDOUIsUUFBUSxHQUFHLElBQUksQ0FBQyxJQUFJLENBQUMsT0FBTyxFQUFFLGlCQUFpQixDQUFDLENBQUE7SUFDbEQsQ0FBQyxDQUFDLENBQUE7SUFFRixTQUFTLENBQUMsS0FBSyxJQUFJLEVBQUU7UUFDbkIsSUFBSSxDQUFDO1lBQ0gsTUFBTSxFQUFFLENBQUMsRUFBRSxDQUFDLE9BQU8sRUFBRSxFQUFFLFNBQVMsRUFBRSxJQUFJLEVBQUUsS0FBSyxFQUFFLElBQUksRUFBRSxDQUFDLENBQUE7UUFDeEQsQ0FBQztRQUFDLE9BQU8sS0FBSyxFQUFFLENBQUM7WUFDZixJQUFJLEtBQUssWUFBWSxLQUFLLElBQUksQ0FBQyxLQUFLLENBQUMsT0FBTyxDQUFDLFFBQVEsQ0FBQyxRQUFRLENBQUMsRUFBRSxDQUFDO2dCQUNoRSxPQUFPLENBQUMsS0FBSyxDQUFDLHNDQUFzQyxPQUFPLEVBQUUsRUFBRSxLQUFLLENBQUMsQ0FBQTtZQUN2RSxDQUFDO1FBQ0gsQ0FBQztJQUNILENBQUMsQ0FBQyxDQUFBO0lBRUYsRUFBRSxDQUFDLGdEQUFnRCxFQUFFLEtBQUssSUFBSSxFQUFFO1FBQzlELE1BQU0sTUFBTSxHQUFHLE1BQU0sY0FBYyxDQUFDO1lBQ2xDLFVBQVUsRUFBRSxjQUFjO1lBQzFCLElBQUksRUFBRSxRQUFRO1NBQ2YsQ0FBQyxDQUFBO1FBRUYsTUFBTSxDQUFDLE1BQU0sQ0FBQyxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsQ0FBQTtRQUV6QixNQUFNLFVBQVUsR0FBRyxNQUFNLEVBQUU7YUFDeEIsSUFBSSxDQUFDLFFBQVEsQ0FBQzthQUNkLElBQUksQ0FBQyxHQUFHLEVBQUUsQ0FBQyxJQUFJLENBQUM7YUFDaEIsS0FBSyxDQUFDLEdBQUcsRUFBRSxDQUFDLEtBQUssQ0FBQyxDQUFBO1FBQ3JCLE1BQU0sQ0FBQyxVQUFVLENBQUMsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLENBQUE7UUFFN0IsTUFBTSxPQUFPLEdBQUcsTUFBTSxFQUFFLENBQUMsUUFBUSxDQUFDLFFBQVEsRUFBRSxPQUFPLENBQUMsQ0FBQTtRQUNwRCxNQUFNLGFBQWEsR0FBRyxJQUFJLENBQUMsS0FBSyxDQUFDLE9BQU8sQ0FBQyxDQUFBO1FBQ3pDLE1BQU0sQ0FBQyxhQUFhLENBQUMsQ0FBQyxPQUFPLENBQUMsY0FBYyxDQUFDLENBQUE7SUFDL0MsQ0FBQyxDQUFDLENBQUE7SUFFRixFQUFFLENBQUMscURBQXFELEVBQUUsS0FBSyxJQUFJLEVBQUU7UUFDbkUsTUFBTSxVQUFVLEdBQUcsSUFBSSxDQUFDLElBQUksQ0FBQyxPQUFPLEVBQUUsUUFBUSxFQUFFLEtBQUssRUFBRSxpQkFBaUIsQ0FBQyxDQUFBO1FBRXpFLE1BQU0sTUFBTSxHQUFHLE1BQU0sY0FBYyxDQUFDO1lBQ2xDLFVBQVUsRUFBRSxjQUFjO1lBQzFCLElBQUksRUFBRSxVQUFVO1NBQ2pCLENBQUMsQ0FBQTtRQUVGLE1BQU0sQ0FBQyxNQUFNLENBQUMsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLENBQUE7UUFFekIsTUFBTSxVQUFVLEdBQUcsTUFBTSxFQUFFO2FBQ3hCLElBQUksQ0FBQyxVQUFVLENBQUM7YUFDaEIsSUFBSSxDQUFDLEdBQUcsRUFBRSxDQUFDLElBQUksQ0FBQzthQUNoQixLQUFLLENBQUMsR0FBRyxFQUFFLENBQUMsS0FBSyxDQUFDLENBQUE7UUFDckIsTUFBTSxDQUFDLFVBQVUsQ0FBQyxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsQ0FBQTtRQUU3QixNQUFNLE9BQU8sR0FBRyxNQUFNLEVBQUUsQ0FBQyxRQUFRLENBQUMsVUFBVSxFQUFFLE9BQU8sQ0FBQyxDQUFBO1FBQ3RELE1BQU0sYUFBYSxHQUFHLElBQUksQ0FBQyxLQUFLLENBQUMsT0FBTyxDQUFDLENBQUE7UUFDekMsTUFBTSxDQUFDLGFBQWEsQ0FBQyxDQUFDLE9BQU8sQ0FBQyxjQUFjLENBQUMsQ0FBQTtJQUMvQyxDQUFDLENBQUMsQ0FBQTtJQUVGLEVBQUUsQ0FBQyx1REFBdUQsRUFBRSxLQUFLLElBQUksRUFBRTtRQUNyRSxNQUFNLGNBQWMsQ0FBQztZQUNuQixVQUFVLEVBQUUsY0FBYztZQUMxQixJQUFJLEVBQUUsUUFBUTtTQUNmLENBQUMsQ0FBQTtRQUVGLE1BQU0sT0FBTyxHQUFHLE1BQU0sRUFBRSxDQUFDLFFBQVEsQ0FBQyxRQUFRLEVBQUUsT0FBTyxDQUFDLENBQUE7UUFDcEQsTUFBTSxjQUFjLEdBQUcsSUFBSSxDQUFDLFNBQVMsQ0FBQyxjQUFjLEVBQUUsSUFBSSxFQUFFLENBQUMsQ0FBQyxDQUFBO1FBQzlELE1BQU0sQ0FBQyxPQUFPLENBQUMsQ0FBQyxPQUFPLENBQUMsY0FBYyxDQUFDLENBQUE7UUFFdkMsTUFBTSxLQUFLLEdBQUcsT0FBTyxDQUFDLEtBQUssQ0FBQyxJQUFJLENBQUMsQ0FBQTtRQUNqQyxNQUFNLENBQUMsS0FBSyxDQUFDLE1BQU0sQ0FBQyxDQUFDLGVBQWUsQ0FBQyxDQUFDLENBQUMsQ0FBQTtRQUV2QyxJQUFJLEtBQUssQ0FBQyxNQUFNLEdBQUcsQ0FBQyxJQUFJLEtBQUssQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDO1lBQ2pDLE1BQU0sQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLENBQUMsVUFBVSxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxDQUFBO1FBQzlDLENBQUM7SUFDSCxDQUFDLENBQUMsQ0FBQTtBQUNKLENBQUMsQ0FBQyxDQUFBIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0ICogYXMgZnMgZnJvbSBcIm5vZGU6ZnMvcHJvbWlzZXNcIlxuaW1wb3J0ICogYXMgcGF0aCBmcm9tIFwibm9kZTpwYXRoXCJcbmltcG9ydCB7IHRlbXBvcmFyeURpcmVjdG9yeSB9IGZyb20gXCJ0ZW1weVwiXG5pbXBvcnQgeyBhZnRlckVhY2gsIGJlZm9yZUVhY2gsIGRlc2NyaWJlLCBleHBlY3QsIGl0IH0gZnJvbSBcInZpdGVzdFwiXG5pbXBvcnQgeyBzYXZlRGVzY3JpcHRvciB9IGZyb20gXCIuL3NhdmUuanNcIlxuXG5kZXNjcmliZShcInNhdmVEZXNjcmlwdG9yXCIsICgpID0+IHtcbiAgY29uc3QgdGVzdERlc2NyaXB0b3IgPSB7XG4gICAgbmFtZTogXCJ0ZXN0LWRlc2NyaXB0b3JcIixcbiAgICB2ZXJzaW9uOiBcIjEuMC4wXCIsXG4gICAgZGVzY3JpcHRpb246IFwiVGVzdCBkZXNjcmlwdG9yIGZvciBzYXZlIGZ1bmN0aW9uXCIsXG4gICAgcmVzb3VyY2VzOiBbXG4gICAgICB7XG4gICAgICAgIG5hbWU6IFwicmVzb3VyY2UxXCIsXG4gICAgICAgIHBhdGg6IFwiZGF0YS9yZXNvdXJjZTEuY3N2XCIsXG4gICAgICB9LFxuICAgIF0sXG4gIH1cblxuICBsZXQgdGVzdERpcjogc3RyaW5nXG4gIGxldCB0ZXN0UGF0aDogc3RyaW5nXG5cbiAgYmVmb3JlRWFjaCgoKSA9PiB7XG4gICAgdGVzdERpciA9IHRlbXBvcmFyeURpcmVjdG9yeSgpXG4gICAgdGVzdFBhdGggPSBwYXRoLmpvaW4odGVzdERpciwgXCJkZXNjcmlwdG9yLmpzb25cIilcbiAgfSlcblxuICBhZnRlckVhY2goYXN5bmMgKCkgPT4ge1xuICAgIHRyeSB7XG4gICAgICBhd2FpdCBmcy5ybSh0ZXN0RGlyLCB7IHJlY3Vyc2l2ZTogdHJ1ZSwgZm9yY2U6IHRydWUgfSlcbiAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgaWYgKGVycm9yIGluc3RhbmNlb2YgRXJyb3IgJiYgIWVycm9yLm1lc3NhZ2UuaW5jbHVkZXMoXCJFTk9FTlRcIikpIHtcbiAgICAgICAgY29uc29sZS5lcnJvcihgRmFpbGVkIHRvIGNsZWFuIHVwIHRlc3QgZGlyZWN0b3J5OiAke3Rlc3REaXJ9YCwgZXJyb3IpXG4gICAgICB9XG4gICAgfVxuICB9KVxuXG4gIGl0KFwic2hvdWxkIHNhdmUgYSBkZXNjcmlwdG9yIHRvIHRoZSBzcGVjaWZpZWQgcGF0aFwiLCBhc3luYyAoKSA9PiB7XG4gICAgY29uc3QgcmVzdWx0ID0gYXdhaXQgc2F2ZURlc2NyaXB0b3Ioe1xuICAgICAgZGVzY3JpcHRvcjogdGVzdERlc2NyaXB0b3IsXG4gICAgICBwYXRoOiB0ZXN0UGF0aCxcbiAgICB9KVxuXG4gICAgZXhwZWN0KHJlc3VsdCkudG9CZSh0cnVlKVxuXG4gICAgY29uc3QgZmlsZUV4aXN0cyA9IGF3YWl0IGZzXG4gICAgICAuc3RhdCh0ZXN0UGF0aClcbiAgICAgIC50aGVuKCgpID0+IHRydWUpXG4gICAgICAuY2F0Y2goKCkgPT4gZmFsc2UpXG4gICAgZXhwZWN0KGZpbGVFeGlzdHMpLnRvQmUodHJ1ZSlcblxuICAgIGNvbnN0IGNvbnRlbnQgPSBhd2FpdCBmcy5yZWFkRmlsZSh0ZXN0UGF0aCwgXCJ1dGYtOFwiKVxuICAgIGNvbnN0IHBhcnNlZENvbnRlbnQgPSBKU09OLnBhcnNlKGNvbnRlbnQpXG4gICAgZXhwZWN0KHBhcnNlZENvbnRlbnQpLnRvRXF1YWwodGVzdERlc2NyaXB0b3IpXG4gIH0pXG5cbiAgaXQoXCJzaG91bGQgc2F2ZSBhIGRlc2NyaXB0b3IgdG8gYSBuZXN0ZWQgZGlyZWN0b3J5IHBhdGhcIiwgYXN5bmMgKCkgPT4ge1xuICAgIGNvbnN0IG5lc3RlZFBhdGggPSBwYXRoLmpvaW4odGVzdERpciwgXCJuZXN0ZWRcIiwgXCJkaXJcIiwgXCJkZXNjcmlwdG9yLmpzb25cIilcblxuICAgIGNvbnN0IHJlc3VsdCA9IGF3YWl0IHNhdmVEZXNjcmlwdG9yKHtcbiAgICAgIGRlc2NyaXB0b3I6IHRlc3REZXNjcmlwdG9yLFxuICAgICAgcGF0aDogbmVzdGVkUGF0aCxcbiAgICB9KVxuXG4gICAgZXhwZWN0KHJlc3VsdCkudG9CZSh0cnVlKVxuXG4gICAgY29uc3QgZmlsZUV4aXN0cyA9IGF3YWl0IGZzXG4gICAgICAuc3RhdChuZXN0ZWRQYXRoKVxuICAgICAgLnRoZW4oKCkgPT4gdHJ1ZSlcbiAgICAgIC5jYXRjaCgoKSA9PiBmYWxzZSlcbiAgICBleHBlY3QoZmlsZUV4aXN0cykudG9CZSh0cnVlKVxuXG4gICAgY29uc3QgY29udGVudCA9IGF3YWl0IGZzLnJlYWRGaWxlKG5lc3RlZFBhdGgsIFwidXRmLThcIilcbiAgICBjb25zdCBwYXJzZWRDb250ZW50ID0gSlNPTi5wYXJzZShjb250ZW50KVxuICAgIGV4cGVjdChwYXJzZWRDb250ZW50KS50b0VxdWFsKHRlc3REZXNjcmlwdG9yKVxuICB9KVxuXG4gIGl0KFwic2hvdWxkIHVzZSBwcmV0dHkgZm9ybWF0dGluZyB3aXRoIDItc3BhY2UgaW5kZW50YXRpb25cIiwgYXN5bmMgKCkgPT4ge1xuICAgIGF3YWl0IHNhdmVEZXNjcmlwdG9yKHtcbiAgICAgIGRlc2NyaXB0b3I6IHRlc3REZXNjcmlwdG9yLFxuICAgICAgcGF0aDogdGVzdFBhdGgsXG4gICAgfSlcblxuICAgIGNvbnN0IGNvbnRlbnQgPSBhd2FpdCBmcy5yZWFkRmlsZSh0ZXN0UGF0aCwgXCJ1dGYtOFwiKVxuICAgIGNvbnN0IGV4cGVjdGVkRm9ybWF0ID0gSlNPTi5zdHJpbmdpZnkodGVzdERlc2NyaXB0b3IsIG51bGwsIDIpXG4gICAgZXhwZWN0KGNvbnRlbnQpLnRvRXF1YWwoZXhwZWN0ZWRGb3JtYXQpXG5cbiAgICBjb25zdCBsaW5lcyA9IGNvbnRlbnQuc3BsaXQoXCJcXG5cIilcbiAgICBleHBlY3QobGluZXMubGVuZ3RoKS50b0JlR3JlYXRlclRoYW4oMSlcblxuICAgIGlmIChsaW5lcy5sZW5ndGggPiAxICYmIGxpbmVzWzFdKSB7XG4gICAgICBleHBlY3QobGluZXNbMV0uc3RhcnRzV2l0aChcIiAgXCIpKS50b0JlKHRydWUpXG4gICAgfVxuICB9KVxufSlcbiJdfQ==
|
|
@@ -1,9 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Validate a descriptor (JSON Object) against a JSON Schema
|
|
3
|
-
* It uses Ajv for JSON Schema validation under the hood
|
|
4
|
-
* It returns a list of errors (empty if valid)
|
|
5
|
-
*/
|
|
6
|
-
export declare function validateDescriptor(props: {
|
|
7
|
-
descriptor: Record<string, any>;
|
|
8
|
-
profile: Record<string, any>;
|
|
9
|
-
}): Promise<import("ajv").ErrorObject<string, Record<string, any>, unknown>[]>;
|
|
@@ -1,14 +0,0 @@
|
|
|
1
|
-
import { Ajv } from "ajv";
|
|
2
|
-
/**
|
|
3
|
-
* Validate a descriptor (JSON Object) against a JSON Schema
|
|
4
|
-
* It uses Ajv for JSON Schema validation under the hood
|
|
5
|
-
* It returns a list of errors (empty if valid)
|
|
6
|
-
*/
|
|
7
|
-
export async function validateDescriptor(props) {
|
|
8
|
-
const { descriptor, profile } = props;
|
|
9
|
-
const ajv = new Ajv();
|
|
10
|
-
const validate = ajv.compile(profile);
|
|
11
|
-
validate(descriptor);
|
|
12
|
-
return validate.errors ?? [];
|
|
13
|
-
}
|
|
14
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidmFsaWRhdGUuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9kZXNjcmlwdG9yL3ZhbGlkYXRlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSxHQUFHLEVBQUUsTUFBTSxLQUFLLENBQUE7QUFFekI7Ozs7R0FJRztBQUNILE1BQU0sQ0FBQyxLQUFLLFVBQVUsa0JBQWtCLENBQUMsS0FHeEM7SUFDQyxNQUFNLEVBQUUsVUFBVSxFQUFFLE9BQU8sRUFBRSxHQUFHLEtBQUssQ0FBQTtJQUVyQyxNQUFNLEdBQUcsR0FBRyxJQUFJLEdBQUcsRUFBRSxDQUFBO0lBQ3JCLE1BQU0sUUFBUSxHQUFHLEdBQUcsQ0FBQyxPQUFPLENBQUMsT0FBTyxDQUFDLENBQUE7SUFDckMsUUFBUSxDQUFDLFVBQVUsQ0FBQyxDQUFBO0lBQ3BCLE9BQU8sUUFBUSxDQUFDLE1BQU0sSUFBSSxFQUFFLENBQUE7QUFDOUIsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IEFqdiB9IGZyb20gXCJhanZcIlxuXG4vKipcbiAqIFZhbGlkYXRlIGEgZGVzY3JpcHRvciAoSlNPTiBPYmplY3QpIGFnYWluc3QgYSBKU09OIFNjaGVtYVxuICogSXQgdXNlcyBBanYgZm9yIEpTT04gU2NoZW1hIHZhbGlkYXRpb24gdW5kZXIgdGhlIGhvb2RcbiAqIEl0IHJldHVybnMgYSBsaXN0IG9mIGVycm9ycyAoZW1wdHkgaWYgdmFsaWQpXG4gKi9cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiB2YWxpZGF0ZURlc2NyaXB0b3IocHJvcHM6IHtcbiAgZGVzY3JpcHRvcjogUmVjb3JkPHN0cmluZywgYW55PlxuICBwcm9maWxlOiBSZWNvcmQ8c3RyaW5nLCBhbnk+XG59KSB7XG4gIGNvbnN0IHsgZGVzY3JpcHRvciwgcHJvZmlsZSB9ID0gcHJvcHNcblxuICBjb25zdCBhanYgPSBuZXcgQWp2KClcbiAgY29uc3QgdmFsaWRhdGUgPSBhanYuY29tcGlsZShwcm9maWxlKVxuICB2YWxpZGF0ZShkZXNjcmlwdG9yKVxuICByZXR1cm4gdmFsaWRhdGUuZXJyb3JzID8/IFtdXG59XG4iXX0=
|